使用NSURLSession
NSURLSession类和相关的类提供了通过http协议下载内容的应用程序接口,这些接口提供了丰富的代理方法,当你的应用没有运行或者被挂起的时候,这些代理方法支持授权认证、app能够在后台下载。
为了用NSURLSession的这些api,你的app需要创建一系列的会话,每个会话都和一组相关的数据传输任务协同工作,例如,如果你正在写一个web浏览器,你的app可能会为每一个标签或者窗口创建一个会话,在每个会话里面,你的app增加一系列任务,每个任务代表了一个详细的URL请求。
像大部分的网络请求接口一样,NSURLSession API是高度异步。如果你用默认系统提供的代理方法,你必须提供一个处理完成的代码块,来返回传输成功或者失败的数据,或者你提供自定义的代理对象,任务对象调用那些代理对象的方法来获取从服务器返回的数据。
注意:完成回调主要是为了替代使用自定义协议,如果你用了带有完成回调的方法来创建一个任务,那么对于传递网络响应和数据的代理方法将不会被调用。
NSURLSession 应用接口提供了进度和状态特性,除了向代理对象传递这些信息,它支持取消、重置、挂起任务,提供了挂起、取消、或者下载失败重置的功能。
理解URL 会话的概念
会话任务取决三个东西:会话类型(取决于用来创建它的配置对象类型)、任务类型、创建任务的时候app是否处于前台。
会话类型
NSURLSession API支持3种会话类型,取决于用来创建会话的配置对象的类型:
1、默认会话类型对于URL下载和其他基础方法是相似的。它们用了基于磁盘的缓存和在用户钥匙串里面存储证书。
2、暂时会话类型不会存储任何数据到磁盘,所有的缓存、证书等等都是保存到只读存储器,因此当你对会话无效的时候,这些东西都会被自动清空。
3、后台会话类型和默认会话类型相似的。除了它是一个单独的进程处理所有的数据传输,后台会话有一些其他的限制。
任务类型
在一个会话里面,NSURLSession类支持三种类型的数据任务:数据任务、下载任务、上传任务。
1、数据任务用NSData对象发送和接收数据,数据任务的目的是短,app到服务端经常请求交互。数据任务能够在每一片数据被接收之后的一个时间返回,或者通过完成处理代码块一次返回。
2、下载任务以稳文件的形式接收数据,当app不运行的时候支持后台下载。
3、上传任务以文件的形式发送数据,也支持后台上传。
后台传输
当你的app在后台被挂起掉时候NSURLSession类型支持后台传输,后台传输只提供用后台配置对象创建的会话类型。
在后台会话里面,由于实际的传输实在一个单独的进程里面,因此要恢复你app的进程的代价是很高的,有很多的特性是不支持的,下面列出的都是需要限制的:
1、会话必须提供一个代理来进行事件传递(对于上传和下载,传输进程的代理行为时一致的)
2、只有http活着https协议才被支持(自定义的协议不支持)
3、回调总是被允许
4、只有文件形式的上传任务才支持(上传数据对象或者一个数据流在程序退出之后会失败)
5、如果后台传输初始化的时候app处于后台模式,配置对象的discretionary属性被看作true。
注意:在iOS8、OSX10.10之前,数据任务是不支持后台会话的。
在iOS中,当一个后台传输完成或者请求证书的时候,如果app不再运行,iOS在后台自动重启,然后在app代理对象里面
回调application:handleEventsForBackgroundURLSession:completionHandler: 方法。回调提供了会话的id来让你的app重新启动,你的app应该在处理完成里面用和创建后台配置对象一样的id,然后用配置对象创建一个会话。新的会话会自动关联后台,然后,当这个会话完成了最后一个下载任务,它给会话的代理发送URLSessionDidFinishEventsForBackgroundURLSession: 消息,在代理方法里面,在主线程调用以前的存储的处理完成模块以至于操作系统能够知道你的app再次被安全挂起。
任何任务完成的时候如果app 是挂起的,任务的代理方法URLSession:downloadTask:didFinishDownloadingToURL:会被回调,执行和新下载文件关联的URL。
类似地,如果任何任务请求证书,NSURLSession对象调用代理的URLSession:task:didReceiveChallenge:completionHandler: 或者 URLSession:didReceiveChallenge:completionHandler:方法。
上传和下载任务在后台会话在网络出错之后会通过url载入系统自动修复,没有必要用reachability接口来判断修复失败的任务。