本文由 伯乐在线 - ylovesy 翻译自 Mattt Thompson。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。
说到
此时可能有人正沉浸在Apple的网络基础架构,我想在这里分享一下我对这些新APIs的看法,并展示这些新APIs如何改变我们构建应用程序的方式,以及这些它们在API设计理念演变中的意义。
作为Core Foundation / CFNetwork 框架的APIs之上的一个抽象,NSURLConnection伴随着2003年Safari浏览器的原始发行版本,诞生于10年前。NSURLConnection这个名字,实际上指的是一组构成Foundation框架中URL加载系统的相互关联的组件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
NSURLRequest对象被传递给一个NSURLConnection对象。委托(遵守从前的非正式 和
一个请求发送到服务器前,共享的高速缓存先被访问,然后根据策略(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最直接的改善就是提供了配置每个会话的缓存,协议,cookie和证书政策(credential policies),甚至跨应用程序共享它们的能力。这使得框架的网络基础架构和部分应用程序独立工作,而不会互相干扰。每一个NSURLSession对象都是根据一个NSURLSessionConfiguratio
NSURLSession的另一重要组成部分是会话任务,它负责处理数据的加载,以及客户端与服务器之间的文件和数据的上传下载服务。NSURLSessionTask与NSURLConnection是及其相似的,因为它负责加载数据,而主要的区别在于,任务共享它们父类NSURLSession的共同委托(common delegate)。
我们现在首先深入探讨任务,然后再介绍更多关于会话配置的知识。
NSURLSessionTask
NSURLSessionTask是一个抽象子类,它有三个具体的子类是可以直接使用的:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask
当一个NSURLSessionDataTask完成时,它具有关联的数据,而一个NSURLSessionDownloadTask
不同于直接使用alloc-init‘d初始化方法,任务是由一个NSURLSession创建的。每个任务的构造方法都对应一个版本,有或者没有completionHandler属性,例如:–dataTaskWithRequest: 和
Constructors
iOS5中,NSURLConnection添加了sendAsynchronousRequest:queue:completionHandler:方法,这大大简化了一次性请求的使用,同时可以作为sendSynchronousRequest:returningResponse:error::的异步替代品。
1 2 3 4 5 6 7 8 | NSURL *URL = [NSURL URLWithString:@"http://example.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; [NSURLConnection sendAsynchronousRequest:request }]; |
NSURLSession与它的任务构造方法在此模式上迭代。在执行resume方法前,该任务对象为了进行进一步的配置而返回,而不是立即执行resume方法。
数据任务可以通过NSURL或NSURLRequest创建(前者是一个标准GET请求URL的快捷方式)。
1 2 3 4 5 6 7 8 9 10 11 | NSURL *URL = [NSURL URLWithString:@"http://example.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request [task resume]; |
上传任务也可以通过一个请求以及一个需要上传的本地文件的URL对应的NSData对象创建。
1 2 3 4 5 6 7 8 9 10 11 12 13 | NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; |
下载任务也需要一个请求,但不同之处在于它们的completionHandler。数据和上传任务在完成时立即返回,但下载任务将数据写入本地的临时文件。completionHandler有责任将文件从它的临时位置移动到一个永久位置,这个永久位置就是块的返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 | NSURL *URL = [NSURL URLWithString:@"http://example.com/file.zip"]; |
NSURLSession & NSURLConnection Delegate Methods
总体而言,NSURLSession的委托方法,是NSURLConnection的演化的十年中
以下是一些具体的观察:
NSURLSession同时具有用来处理身份验证挑战会话和任务委托方法。这个会话的委托方法处理连接级别的问题,如服务器信任和客户端证书的评估,NTLM和Kerberos,而任务的委托处理以请求为基础的挑战,如Basic, Digest, 或者代理身份验证。
NSURLConnection由两个方法可以表明一个请求已经完成(NSURLConnectionDataDeleg
与NSURLConnection使用的 long long类型相比,委托方法指定在NSURLSession中一定数量的字节传输使用int64_t类型的参数。
NSURLSession在Foundation框架对于委托方法的completionHandler:参数使用上
想要查看更多关于会话任务的信息,可以查看
NSURLSessionConfiguratio
NSURLSessionConfiguratio
会话在初始化时复制它们的配置,NSURLSession有一个只读的配置属性,使得该配置对象上的变化对这个会话的政策无效。配置在初始化时被读取一次,之后都是不会变化的。
Constructors
NSURLSessionConfiguratio
+ defaultSessionConfigurat
+ ephemeralSessionConfigur
+ backgroundSessionConfigu
想要查看更多关于后台会话的信息,可以查看WWDC Session 204: “What’s New with Multitasking”
Properties
NSURLSessionConfiguratio
General
HTTPAdditionalHeaders指定了一组默认的可以设置出站请求的数据头。这对于跨会话共享信息,如内容类型,语言,用户代理,身份认证,是很有用的。
1 2 3 4 5 6 7 8 9 10 | NSString *userPasswordString = [NSString stringWithFormat:@"%@:%@", user, password]; NSData * userPasswordData = [userPasswordString dataUsingEncoding:NSUTF8StringEncoding]; NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithO NSString *authString = [NSString stringWithFormat:@"Basic: %@", base64EncodedCredential]; NSString *userAgentString = @"AppName/com.example.app (iPhone 5s; iOS 7.0.2; Scale/2.0)"; configuration.HTTPAdditionalHeaders = @{@"Accept": @"application/json", |
networkServiceType对标准的网络流量,网络电话,语音,视频,以及由一个后台进程使用的流量进行了区分。大多数应用程序都不需要设置这个。
allowsCellularAccess 和 discretionary 被用于节省通过蜂窝连接的带宽。建议在使用后台传输的时候,使用discretionary属性,而不是allowsCellularAccess属性,因为它会把WiFi和电源可用性考虑在内。
timeoutIntervalForReques
HTTPMaximumConnectionsPe
HTTPShouldUsePipelining 也出现在NSMutableURLRequest,它可以被用于开启HTTP管道,这可以显着降低请求的加载时间,但是由于没有被服务器广泛支持,默认是禁用的。
sessionSendsLaunchEvents
connectionProxyDictionar
关于连接代理的更多信息可以在
Cookie Policies
HTTPCookieStorage 是被会话使用的cookie存储。默认情况下,NSHTTPCookieShorage的+ sharedHTTPCookieStorage会被使用,这与NSURLConnection是相同的。
HTTPCookieAcceptPolicy 决定了该会话应该接受从服务器发出的cookie的条件。
HTTPShouldSetCookies 指定了请求是否应该使用会话HTTPCookieStorage的cookie。
Security Policies
URLCredentialStorage 是会话使用的证书存储。默认情况下,NSURLCredentialStorage 的+ sharedCredentialStorage 会被使用使用,这与NSURLConnection是相同的。
TLSMaximumSupportedProto
Caching Policies
URLCache 是会话使用的缓存。默认情况下,NSURLCache 的+ sharedURLCache 会被使用,这与NSURLConnection是相同的。
requestCachePolicy 指定了一个请求的缓存响应应该在什么时候返回。这相当于NSURLRequest 的-cachePolicy方法。
Custom Protocols
protocolClasses是注册NSURLProtocol类的特定会话数组。
总结
iOS 7 和 Mac OS X 10.9 Mavericks 中URL加载系统的变化,是NSURLConnection的一个深思熟虑而自然的进化。总体而言,Foundation框架团队做出了令人惊讶的工作,他们研究并预测了移动开发者现有的和新兴的用例,创造了能够满足日常任务的, 真正有用的APIs。
就可组合性和可扩展性而言,尽管在会话任务的体系结构中,某些决定是一种倒退,NSURLSession仍然可以很好地作为更高级别的网络功能的一个基础。