这篇指南描述了在Foundation框架中和URL交互的类,以及使用标准的网络协议和服务器通信。这些类一起被叫做URL loading system
URL loading system是类和协议的集合,允许你的App可以通过URL访问内容。这个技术的核心就是NSURL类,这让你的App操作他们指向的URLs和资源。
为了协助这个类,Foundation框架提供了一组丰富的类集合。这让你能够加载一个URL的内容,上传数据到服务端,管理cookie的存储,控制返回值的缓存,处理证书的存储,用App指定的方式认证,写一个自定义的协议扩展。
URL loading system通过下面的协议提供访问资源的支持:
- 文件传输协议(ftp://)
- 超文本传输协议(http://)
- 超文本传输协议和加密(https://)
- 本地文件资源定位协议(file:///)
- 数据资源定位(data://)
通过使用用户的设置,可以让它支持代理服务和SOCKS通道
Important:在App平台中,网络安全被叫做App Transport Security(ATS),这个适用于App和App extension,并且是默认可用的。它通过App网络链接使用的标准协议和难以被人破解密码防护来确保用户隐私的安全、数据的完整。更多的信息,请见NSAppTransportSecurity
Note:除了URL loading system,OS X和iOS提供了API可以在其他应用中打开自己的App。例如 Safari。这些API在这篇文章中没有被提到。
关于在OS X中加载服务的信息,可以阅读Launch Services Programming Guide
关于OS X中的NSWorkSpace
类中 openURL:方法的相关信息可以阅读NSWorkspace Class Reference
关于iOS中的UIApplication
类中 openURL:方法的相关信息可以阅读UIApplication Class Reference
总纲
URL loading system中包括 大量使用重要的helper类来加载RUL的 类,helper类和加载URL的类一起使用来改变它们的行为。主要的hepler类被分为5类:协议支持(protocol support),证书认证(authentication and credentials),cookie存储(cookie storage),配置管理(configuration mangement)和 缓存管理(cache mangement)。
<img src="http://upload-images.jianshu.io/upload_images/1086250-d41a7174c55ea6e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="nsobject_hierarchy" width=10px height=10px />
URL Loading
在URL loading system中被使用最多的类(功能)就是允许你的app从原文件地址取回URL中的内容。你可以用NSURLSession
类实现。你指定使用的方法很大程度上取决于你是希望接收到的数据是放到内存中还是下载到本地(磁盘中)。
抓取内容作为数据(在内存中)(Downloading Content as a File) (In Memory)
在较高的抽象层级上有两个方法来获取URL数据
- 对于一个简单的请求,要使用
NSURLSession
API来从URL对象中直接获取数据,无论数据是一个NSData
对象还是一个在磁盘上的文件。 - 对于更复杂的请求,请求上传数据。要提供一个
NSURLRequest
对象(或者是其可变的子类NSMutableURLRequest
)给NSURLSession
无论你选择哪种方法,你的app可以通过下面两种方式获得数据
- 提供一个完成后的回调闭包。URL的加载类将会在它完成从服务端取回数据的操作和调用这个闭包。
- 提供一个自定义的delegate。URL的加载类将会在当它从服务端收到数据的时候按需求的调用你的delegate。如果有需要,你的app可以对不断变化的数据进行响应。
除了数据本身,URL还可以为闭包或者delegate提供一个相应的对象,里面包装了和请求相关的原数据。例如 MIME类、请求内容长度。
相关章节:Using NSURLSession
什么是MIME:在维基百科是这样描述的
Multipurpose Internet Mail Extensions (MIME) is an Internet standard that extends the format of email to support:
- Text in character sets other than ASCII
- Non-text attachments: audio, video, images, application programs etc.
- Message bodies with multiple parts
- Header information in non-ASCII character sets
Although MIME was designed mainly for SMTP, the content types defined by MIME standards are also of importance in communication protocols outside of email, such as HTTP for the World Wide Web
大概意思:MIME全称是Multipurpose Internet Mail Extensions(多目标的因特网邮件协议补充),它是因特网的一个标准,为了达到如下目标:
- 字符集的文本显示,而不总是ASCII
- 非文本的附件传输:音频、视频、图片、程序等
- 多部分组成的消息体
- 非ASCII集的头信息
虽然MIME是被设计出来发送邮件的,现在被MIME标准定义的内容类型在Email之外的协议交流上也是很重要的,例如,万维网的HTTP协议。
下载内容到文件(Downloading Content as a File)
在一个较高的抽象层级上,我们有两种方法来下载URL里面的内容到文件中
- 对于一个简单的请求,要使用
NSURLSession
API来从URL对象中直接获取数据,无论数据是一个NSData
对象还是一个在磁盘上的文件。 - 对于更复杂的请求,请求上传数据。要提供一个
NSURLRequest
对象(或者是其可变的子类NSMutableURLRequest
)给NSURLSession
Note:通过
NSURLSession
实例开始的一个下载,下载结果是不会自动被缓存的。如果你想要缓存下载结果,你的app必须自己用NSURLSession
写数据到磁盘中。
相关章节:Using NSURLSession
帮助类(Helper Classes)
URL加载类使用两个helper类来提供另外的元数据,一个是为了请求本身(NSURLRequest
),另一个是为了服务端的响应数据(NSURLResponse
)。
URL请求(URL Requests)
一个NSURLRequest
类通过一种独立出协议的方式,包装了一个URL和一些指定协议的属性。
当app客户端实例出一个链接或者使用
NSMutableURLrequest
来下载的时候,request会发生一个深层次的拷贝(deep copy)。在下载被初始化之后,发生在request上的变化不会对下载产生影响。
一些协议提供了指定协议的属性。例如,HTTP协议添加方法到NSURLRequest
,方法返回了HTTP请求的主体(body),请求头(heasers)和转换方法(transfer method)。它同样添加一些方法到NSMutableURLRequest
来设置那些值。URL请求的实现细节的描述将会贯穿本博客
添加方法理解为:一些HTTP协议需要的属性或者方法需要在request中有对应的体现
响应元数据(Response Metadata)
对于一个请求从服务端的响应可以看作两个部分:描述内容的元数据和内容数据本身。在大多是协议中元数据是最普遍的,它被包装在NSURLReponse
类中,并由MIME类、预期响应的内容长度、文本编码和提供响应的URL组成。协议指定了NSURLResponse
的子类,它能够提供另外的元数据。例如,NSHTTPURLResponse
存储了头(headers)和状态码(status code),这些都被网络服务返回。
Important:只有为了响应的元数据被存贮在NSURLResponse对象中。各种URL加载类提供它们自己的响应数据为他们的app,无论是通过delegate还是闭包。
一个NSCachedURLResponse实例包装了NSURLResponse对象、URL内容数据、还有一些被你app提供的其他信息。详见 缓存管理细节
URL请求的实现细节的描述将会贯穿本博客
重定向和其他的请求变化(Redirection and Other Request Changes)
一些协议例如:HTTP,为服务端提供了一种方法来告诉你的app,内容已经被移动到一个不同的URL中。URL的加载类可以通知他们的代理当这种事情发生的时候。如果你的app提供了一个较友好的delegate,你的app可以决定是否要重定向,从重定向的地址中返回数据或者直接返回一个错误。
证书认证(Authentication and Credentials)
一些服务会约束访问核心的内容,需用用户通过提供一些证明的方式来认证。- 一个客户端证书,用户名和密码,还有一些其他的。为了能够获得访问权。在网络服务的场景下,约束的内容被分到一个地方。这个地方需要一组认证的凭证才能访问。认证(特别是证书的)同样在其他的地方被用来检测是否信任。为了评估你的app是否信任server的服务。
URL loading system提供了一些类。你的app可以指定认证的持续时间,是只针对于一个请求,还是只在app启动的时间,或者永久的保存在用户的钥匙串中。
认证凭证以一种持久存储的方式被保存在用户钥匙串中,来让所有的app共享。
NSURLCredential类包装了由认证信息(例如:用户名和密码)组成的凭证,并持久化数据。NSURLProtectionSpace类代表了一个区域,一个需要特殊认证的区域。一个被保护的区域,可以是只对一种URL的访问,网络服务中的某些地方,被指定的访问策略等。
NSURLCredentialStorage对象为session管理凭证的存储,并提供NSURLCredential对象到相对应的NSURLProtectionSpace对象的映射。一个凭证只有在认证成功的时候才被存储。
NSURLAuthenticationChallenge类包装了需要实现NSURLProtocol的信息,为了认证一个请求:一个被准备好的凭证,保护区域的调用,错误或者响应。协议用来检测被需要的凭证,大量的认证尝试被执行。一个NSURLAuthenticationChallenge
实例同样指定了对象来初始化认证。初始化对象,像渲染一样被引用,并且必须符合NSURLAuthenticaionChallengeSender
协议
NSURLAuthenticaionChallenge
实例通过NSURLProtocol的字类被使用,来通知URL loading system认证是必须的。他们同样提供了NSURLSession的delgate方法,来减少自定义认证处理的难度。
缓存管理(Cache Management)
URL loading system提供了磁盘上和内存中的存储,允许app减少对网络的依赖。并提供了快速的响应对于之前缓存的数据。缓存在每个app的底层。缓存需要NSURLSession根据被 NSURLRequest和NSURLSessionConfiguration对象指定的缓存策略来查找。
NSURLCache类提供了方法来配置缓存的大小和在磁盘上缓存的位置。它同样提供了方法来管理 NSCachedURLResponse对象的集合,它包含了缓存的response。
一个NSCacheURLResponse
对象包装了 NSURLResponse对象和URL内容数据。NSCachedURLResponse
同样提供了一个用户信息的字典。这样你的app可以使用它来缓存任何自定义的数据。不是所有的协议实现都支持response缓存。现在只有http和https支持。
一个NSURLSession对象能够控制是否response需要被缓存。是否response应该被缓存到内存中通过实现URLSession:dataTask:willCacheResponse:completionHandler: delegate方法。
Cookes存储(Cookie Storage)
由于http协议是无状态的,客户端经常使用cookie来提供一个持久的数据存储,通过URL请求。
URL loading system提供了创建和管理cookie的接口,来做为http请求的一部分发送cookie。为了在网络服务响应的时候收到cookie
OS X和iOS提供了NSHTTPCookieStorage类,它提供了管理 NSHTTPCookie对象集合的接口。在OS X中cookie的存储在所有app中都被共享;在iOS只能在一个app中使用。
相关章节:Cookie Storage
协议支持(Protocol Support)
URL loading system支持http、https、file、ftp和data协议。但是URL loading system同样允许你的app注册你自己的类来支持另外的app层的网络协议。你可以同样添加协议指定的属性到URL request中和URL response中。
校验:LinkRober
本文译自About the URL Loading System
有翻译不准确的的地方或有待改进的地方欢迎指正🙏🙏🙏