iOS NSURLSession 网络请求 重定向 302

本文详细介绍iOS中的网络请求处理,包括NSURLRequest与NSMutableURLRequest的使用,GET与POST请求的区别,以及如何利用NSURLSession与NSURLConnection执行请求。同时深入探讨NSURLSession的配置与任务管理,后台传输的实现方法,下载文件的操作及重定向处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 加载url的类总汇  
  2.   
  3. 一、url请求  
  4.   
  5. 网络请求的组成部分有服务器地址、请求参数,以及请求方式。在iOS中,一个网络请求用NSURLRequest(或者其子类NSMutableURLRequest)来表示。  
  6.   
  7. NSURLRequest适合于get请求,NSMutableURLRequest可以是post请求。  
  8.   
  9. get方式下,服务器地址和请求参数都可以明文包含在url中,可以直接使用这个url来创建NSURLRequest(或者NSMutableURLRequest)。  
  10.   
  11. post方式下,服务器地址用NSURL来表示,请求参数可以封装到NSData中(也可以以文件或者流的形式保存)。由于需要将服务器地址和请求参数分开,所以需要用到NSMutableURLRequest类。用服务器地址的url创建NSMutableURLRequest对象,然后将封装了请求参数的NSData对象添加到这个NSMutableURLRequest对象中。示例如下:  
  12.   
  13. NSURL *url=[NSURL URLWithString:@“http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];  
  14. NSData *data=[@"date=20151101&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];  
  15. 1  
  16. 2  
  17. 然后将服务器地址与请求参数加入到NSMutableURLRequest对象中:  
  18.   
  19. NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];  
  20. request.HTTPMethod=@"post";//指明请求方式为post,默认为get  
  21. request.HTTPBody=data;  
  22. 1  
  23. 2  
  24. 3  
  25. 这样就准备好了一个网络请求,接下来就是如何去执行这个网络请求的问题。  
  26.   
  27. 二、执行url请求  
  28.   
  29. 执行url请求可以使用iOS原生API也可以使用第三方库。  
  30.   
  31. 执行url请求的两个原生方法:   
  32. 1)NSURLSession   
  33. 2)NSURLConnection   
  34. iOS 7.0 以后推荐使用NSURLSession,以前使用NSURLConnection。   
  35. NSURLSession、NSURLConnection都可以发送和接收以NSData或者文件的形式保存的数据.  
  36.   
  37. 实现url请求的第三方库有afNetworking、sdWebImage等。  
  38.   
  39. 1.两个原生方法的基本使用思路  
  40.   
  41. 1)每个项目都有一个NSURLSession对象,可以通过[NSURLSession sharedSession]方法来获取它,然后就可以用它来新建请求任务。该任务调用resume方法后开始执行。请求任务有三种,上传、下载、数据。通过NSURLSession来执行url请求是异步的。  
  42.   
  43. 2)NSURLConnection直接执行send方法(类方法)发送请求,可以选择同步也可以选择异步。异步发送请求接收数据的话可以使用block接收,也可以使用代理。注意如果使用代理来接收数据,数据会是断续接收的。通常使用block比较方便。  
  44.   
  45. 同步和异步的区别就是,同步就是执行完网络请求方法后,要等到网络请求得到响应并完成数据传输之后才返回,异步就是发送完请求之后马上返回。  
  46.   
  47. 2. NSURLSession详解  
  48.   
  49. 获取session可以通过初始化方法,也可以直接使用项目默认的session对象,通过sharedSession方法获取。初始化session对象需要指定代理,如果指定为nil,就是使用系统默认的代理。  
  50.   
  51. 1)session的分类  
  52.   
  53. session分为3种:  
  54.   
  55. 默认的(default session):会将存储数据存到硬盘上。  
  56. 短暂的(ephemeral session):不会存储任何数据到硬盘上,只会占用内存,当session释放了,所有的数据也就没有了。  
  57. 后台的(background session):和默认的session的区别在于会用独立的过程来处理数据传输。  
  58. 初始化session的时候需要指定一个NSURLSessionConfiguration对象,session的类型就由这个对象的类型来确定。  
  59.   
  60. 2)任务task的分类  
  61.   
  62. 任务分为3种,数据、下载、上传:  
  63.   
  64. data task数据任务:发送和接收NSData形式的数据  
  65. download task下载任务:解析文件形式的数据,支持app没有运行的时候在后台执行。  
  66. upload task上传任务:发送文件形式的数据,也支持后台执行。  
  67. 3)任务task和session的关系  
  68.   
  69. 任务的初始化和任务的管理都由session来完成。  
  70.   
  71. 每个session对象管理着它自己创建的任务。  
  72.   
  73. 任务创建后需要执行resume方法,session才会处理它。  
  74.   
  75. 任务处理的具体操作是由session的代理来完成的,也就是说具体的处理会写在代理方法中。  
  76.   
  77. 4)利用session完成后台传输  
  78.   
  79. 需要注意的问题:  
  80.   
  81. 只有后台类型的session才可以新建支持后台传输的任务(下载任务或上传任务)。而且后台上传只支持文件上传,如果上传的是NSData对象或者数据流,在app退出后就会断掉。  
  82. 后台任务只支持http和https协议,不支持自定义协议。  
  83. 如果后台传输的任务是在app已经进入了后台之后才初始化的,那么session的NSURLSessionConfiguration对象的discretionary属性值为true。  
  84. 由于网络错误导致的后台上传或后台下载任务失败,系统会自动重新尝试执行这些任务,所以不需要自己写代码来重新执行失败的后台任务。  
  85. 后台任务与app的交互:  
  86.   
  87. 后台任务的特点就是运行在后台,当app不在运行的时候后台任务仍然可以运行。  
  88.   
  89. 上面说过,任务的处理是由session的代理方法来完成的,但是当app没有运行的时候,session已经被释放,这时候后台任务怎么和创建这个任务的session重新关联起来呢?  
  90.   
  91. 这个问题iOS系统已经有一套完整的机制去处理它。是这样的:当后台任务完成或者需要认证的时候,如果app没有在运行,系统就会唤醒app,并调用app delegate的(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler方法。这个方法就是特地写来处理后台任务的,下面所描述的内容都围绕这个方法来展开。  
  92.   
  93. 需要重写在这个方法,在这个方法中让后台任务和session重新关联起来。由于创建它的session已经释放,要找回它不可能,实际的做法是创建一个和它一样的session,然后让任务与这个session关联起来。具体就是用这个方法的参数identifier来新建一个NSURLSessionConfiguration对象,并且用这个NSURLSessionConfiguration对象新建一个session,这个session就可以当成是原来的session了。神奇的是,只要这样创建了session,正在运行的任务就会自动和它关联起来,至于是怎么做到了,不需要操心,系统已经解决了。  
  94.   
  95. 留意到这个方法有一个block类型的参数completionHandler,它的意义在于,一旦它被执行就表明后台任务处理完成,因此系统自唤醒app之后就会一直等待completionHandler的执行,以便让app重新停止运行。因此,要记得把completionHandler传给session的代理,并且在session的代理方法URLSessionDidFinishEventsForBackgroundURLSession:中调用它,这样就实现了在最后一个任务处理完毕以后让app再次进入后台。  
  96.   
  97. 在正在运行的任务已经和session重新取得联系之后就会调用其代理的相关方法,如果是后台任务完成,就会调用URLSession:downloadTask:didFinishDownloadingToURL:方法。如果是需要认证,就会调用URLSession:task:didReceiveChallenge:completionHandler:方法或者URLSession:didReceiveChallenge:completionHandler:方法。  
  98.   
  99. 官网例子:https://developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013416  
  100.   
  101. 4)下载文件  
  102.   
  103. 与文件下载有关的协议方法:  
  104.   
  105. URLSession:downloadTask:didFinishDownloadingToURL:   
  106. 文件下载完成后调用,可以获取下载好的文件的url  
  107. URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:   
  108. 下载过程中调用  
  109. URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:   
  110. 该方法在开始恢复一个失败的下载任务之后调用  
  111. URLSession:task:didCompleteWithError:   
  112. 下载任务完成或终止后调用,如果任务出错,可以获取到NSError对象  
  113. 终止下载任务   
  114. 可以调用NSURLSessionDownloadTask对象的方法:cancelByProducingResumeData:  
  115. 恢复下载任务   
  116. 可以调用session的downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:   
  117. 这里的resumeData从协议方法URLSession:task:didCompleteWithError:中的NSError对象的userInfo字典中会有,对应key为NSURLSessionDownloadTaskResumeData。  
  118. 5)重定向  
  119.   
  120. 相关协议方法:  
  121.   
  122. - (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest *))completionHandler  
  123. 1  
  124. 对于默认的session和暂时的session管理的url请求任务发生重定向时就会调用这个方法,而后台任务发生重定向会直接服从重定向。  
  125.   
  126. 在这个方法里面,可以获取到新的url请求,调用completionHandler(request);就会允许重定向。如果调用completionHandler(nil);就相当于拒绝重定向。当然也可以调用completionHandler(otherRequest);实现自定义重定向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值