使用NSURLSession
NSURLSession和其相关的类提供了通过HTTP下载数据的API.该API提供了丰富的代理方法来支持信息身份认证,以及当app未运行时(比如,在iOS中,app挂起状态)的后台下载功能.
使用NSURLSession,客户端会创建一系列对话,每个会话都匹配一组相关的数据传输任务.例如,编码一个web浏览器,客户端可能需要为没一个标签或者窗口创建一个会话.对每个会话,客户端增加一系列任务,每个任务代表了指向一个特定URL得请求(或者HTTP重定向后的URLs).
像大部分网络API一样,NSURLSession是异步的.如果你默认使用系统系统的代理,那么当一个传输成功完成或发生错误时,你必须提供一个处理结果的块(block).如果你使用自定义的代理对象,当从服务器接收到数据后,任务对象会调用自定义的代理方法(对文件下载来说,是当传输完成时调用).
注意:回调block是自定义代理的一个主要备选方案.如果你通过回调block的方式创建了一个任务,那么代理方法将不会再被调用.
通过NSURLSession 还能获得当前状态以及任务进度值,并能将这些信息传递给代理.它还支持取消,重启(重设),挂起任务,还能从挂起,取消,失败状态重新开始任务.
理解URL Session的概念
一个会话中任务的行为取决于3个因素:会话的类型(由一个先前创建的configuration对象的类型决定),任务的类型,以及任务创建时app是否处在前端激活状态.
会话的类型
NSURLSession支持三种会话类型(由一个先前创建的configuration对象的类型决定):
- 默认会话类型:与其他下载URLs的方法基本类似(NSURLConnection).使用永久磁盘缓存的持久化策略,在用户钥匙串(keychain)中存储认证信息.
- 临时会话类型:不在磁盘上永久化存储任何信息(缓存,认证),所有信息只保存在与会话关联的内存中,当会话失效时,所有信息都会被清空.
- 后台会话类型:与默认会话类型大致相似,不同点是有一个单独的线程来处理数据传输.后台会话类型还存在一些额外的限制,参见下文后台数据传输注意事项
任务的类型
一个会话中,NSURLSession支持三种任务类型:加载数据,下载数据,和上传数据.
- 加载任务类型使用NSData对象来发送和接收数据.使用场景是传输短数据,与服务器交互性强的请求.数据加载能周期性的返回获得的数据(总数据的一部分),或者一次性通过一个下载完成的回调处理整个数据.数据加载并没有将获得的数据存储到文件中,所以不支持后台加载.
- 下载任务类型以文件形式接收数据,支持app处于非运行状态时在后台下载.
- 上传任务类型通常以文件形式发送数据,支持app处于非运行状态时在后台上传.
后台数据传输注意事项
NSURLSession支持app挂起状态时进行后台数据传输.后台传输只有在使用后台会话配置对象创建的会话中可用.
对后台会话来说,因为真实的数据传输是在一条单独的线程中执行的,并且重新开启一条线程开销相对将大,所以一部分特性将不被支持,导致存在下面一些限制:
- 会话必须给每一个委托提供一个代理.(对上传和下载类型的会话来说,代理方法与进程内传输一样.)
- 只支持HTTP和HTTPS协议(不支持自定义协议)
- 只支持上传和下载两种会话类型(不支持后台加载数据).
- 重定向的情况将自动转向重定向后URL.
- 如果后台数据传输是在app处于后台期间创建的,configuration对象的 discretionary属性将被视为true(表明当程序在后台运作时由系统自己选择最佳的网络连接配置,该属性可以节省通过蜂窝连接的带宽).
app的重启时的表现在iOS和OS X下有些许区别.
在iOS中,当一个后台传输完成或者需要进行信息认证时,如果此时app没有运行,iOS将自动在后台重启app并且调用UIApplicationDelegate对象的application:handleEventsForBackgroundURLSession:completionHandler:方法.这个调用提供一个会话标识并导致app重启.app应该存储完成处理器(completion handler,没想到合适的,先这么翻吧),用同样的会话标识创建一个后台配置(configuration)对象,并通过这个配置对象创建一个会话.这个会话将在后台持续运行.之后,当会话完成了最后一个下载任务,会发送给会话的代理对象一个URLSessionDidFinishEventsForBackgroundURLSession:消息.会话代理对象应当调用并且存储完成处理器.
在iOS和OS X中,当用户重新运行app时,app应当立即创建一个后台配置对象,使用上一次运行有未完成任务的会话标识(可能包含多个).然后为这些配置对象创建会话.这些新创建的会话同样会在后台持续运行.
注意:必须为每一个会话正确的指定标识(在创建配置对象时指定),多个会话使用同一个标识将会导致定义不明确.
如果有任务在app挂起期间完成,代理对象的 URLSession:downloadTask:didFinishDownloadingToURL:,方法将被调用.
类似的,如果任务需要进行信息认证,会话对象会在调用代理的 URLSession:task:didReceiveChallenge:completionHandler:方法或者 URLSession:didReceiveChallenge:completionHandler: 方法.
如何使用NSURLSession的示例参见Simple Background Transfer.
生命周期和代理交互
为了更好的使用NSURLSession,最好深入理解会话的生命周期,以及会话是如何与其代理对象进行交互的.比如代理何时被调用,当服务器返回一个重定向URL时的处理,当一个任务下载失败时的处理等等.
完整的会话生命周期描述,参见Life Cycle of a URL Session
NSCopying行为
会话对象和任务对象遵循NSCopying协议如下:
- 当app复制一个会话或者任务对象时,返回的是这个对象本身(没有创建新对象).
- 当app复制一个配置对象时,返回一个新创建的配置对象(创建了新对象).
转载请注明出处:http://blog.csdn.net/qq329735967
任何疑问欢迎Email至329735967@qq.com