忘记NSURLConnection,拥抱NSURLSession吧!

  说到 iOS 7 和 Mac OS X 10.9 Mavericks 的显著变化,其中一个就是Foundation框架中URL加载系统的优化。

  此时可能有人正沉浸在Apple的网络基础架构,我想在这里分享一下我对这些新APIs的看法,并展示这些新APIs如何改变我们构建应用程序的方式,以及这些它们在API设计理念演变中的意义。

  作为Core Foundation / CFNetwork 框架的APIs之上的一个抽象,NSURLConnection伴随着2003年Safari浏览器的原始发行版本,诞生于10年前。NSURLConnection这个名字,实际上指的是一组构成Foundation框架中URL加载系统的相互关联的组件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。

  NSURLRequest对象被传递给一个NSURLConnection对象。委托(遵守从前的非正式<NSURLConnectionDelegate> 和 <NSURLConnectionDataDelegate>协议)作为一个NSURLResponse异步响应,任何相关的NSData从服务器发送。

  一个请求发送到服务器前,共享的高速缓存先被访问,然后根据策略(policy)和可用性(availability),一个缓存的响应可能立即透明地返回,如果所有缓存的响应都不可用,则该请求根据选项,被用于为任何后续请求缓存它的响应。

  在协商发送一个请求到服务器的过程中,该服务器可发出验证质询,这可以由共享的cookie,证书存储(credential storage)或通过连接委托自动处理。必要的时候,为了无缝地改变装载行为,传出请求也可以被注册的NSURLProtocol对象截获。

  不管怎样,考虑到NSURLConnection作为一个网络基础架构,成千上万的Cocoa和Cocoa Touch应用程序从中获益,它已经表现得相当好。但是,这些年来,iPhone和iPad新兴的用例,特别是有一些已经向NSURLConnection的几个核心设想提出了挑战,对其重构已经迫在眉睫。

  在2013年的WWDC上,Apple揭开了NSURLConnection继任者的面纱:NSURLSession。

  

  与NSURLConnection类似,除了同名类NSURLSession,NSURLSession也是指一组相互依赖的类。NSURLSession包括与之前相同的组件,例如NSURLRequest, NSURLCache等。NSURLSession的不同之处在于,它把 NSURLConnection替换为NSURLSession, NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask.

  与NSURLConnection相比,NSURLSession最直接的改善就是提供了配置每个会话的缓存,,协议,cookie和证书政策(credential policies),甚至跨应用程序共享它们的能力。这使得框架的网络基础架构和部分应用程序独立工作,而不会互相干扰。每一个NSURLSession对象都是根据一个NSURLSessionConfiguration初始化的,该NSURLSessionConfiguration指定了上面提到的政策,以及一系列为了提高移动设备性能而专门添加的新选项。

  NSURLSession的另一重要组成部分是会话任务,它负责处理数据的加载,以及客户端与服务器之间的文件和数据的上传下载服务。NSURLSessionTask与NSURLConnection是及其相似的,因为它负责加载数据,而主要的区别在于,任务共享它们父类NSURLSession的共同委托(common delegate)。

  我们现在首先深入探讨任务,然后再介绍更多关于会话配置的知识。

NSURLSessionTask

  NSURLSessionTask是一个抽象子类,它有三个具体的子类是可以直接使用的:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。这三个类封装了现代应用程序的三个基本网络任务:获取数据,比如JSON或XML,以及上传下载文件。

  

  当一个NSURLSessionDataTask完成时,它具有关联的数据,而一个NSURLSessionDownloadTask完成时,它具有一个已下载文件的临时文件路径。 NSURLSessionUploadTask 继承了 NSURLSessionDataTask,因为服务器响应一个上传请求时,往往伴随着相关联的数据。 ???所有任务均可撤销,也可以暂停和恢复。当一个下载任务被取消时,它可以选择创建恢复数据,然后可以传递给下一次新创建的下载任务,以便继续之前的下载。

  不同于直接使用alloc-init‘d初始化方法,任务是由一个NSURLSession创建的。每个任务的构造方法都对应一个版本,有或者没有completionHandler属性,例如:–dataTaskWithRequest: 和–dataTaskWithRequest:completionHandler:。这与NSURLConnection的 -sendAsynchronousRequest:queue:completionHandler:类似,通过指定completionHandler属性创建并使用一个隐含的委托,而不是使用任务的会话。在任何一种任务会话委托的默认行为需要被重写的情况下,这种不太方便的非completionHandler的变体将需要被使用。

Constructors

  iOS5中,NSURLConnection添加了sendAsynchronousRequest:queue:completionHandler:方法,这大大简化了一次性请求的使用,同时可以作为sendSynchronousRequest:returningResponse:error::的异步替代品。

NSURL *URL = [NSURL URLWithString:@""]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; [NSURLConnection sendAsynchronousRequest:requestqueue:[NSOperationQueue mainQueue]completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {// … }];

  NSURLSession与它的任务构造方法在此模式上迭代。在执行resume方法前,该任务对象为了进行进一步的配置而返回,而不是立即执行resume方法。

  数据任务可以通过NSURL或NSURLRequest创建(前者是一个标准GET请求URL的快捷方式)。

NSURL *URL = [NSURL URLWithString:@""]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:requestcompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {// …}]; [task resume];痛苦留给的一切,请细加回味!苦难一经过去,苦难就变为甘美。

忘记NSURLConnection,拥抱NSURLSession吧!

相关文章:

你感兴趣的文章:

标签云: