版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.01.09 |
前言
APP都需要与服务器进行数据交互,极个别的除外,比如简单的相机,计算器等等,不需要登录和服务端存储信息的APP,绝大多数都是需要和服务器进行交互的,那就需要用到网络,接下来几篇就讲述一下与网络相关的几个类。
Overview
该类作用是用来协调一组相关网络数据传输任务的对象。
NSURLSession
类和相关类提供了用于下载内容的API。 此API提供了一组丰富的委托方法来支持身份验证,并使您的应用能够在应用未运行时或者暂停应用时执行后台下载。
NSURLSession
类本地支持data
,file
,ftp
,http
和https
URL schemes,透明地支持代理proxy
服务器和SOCKS
网关,如用户系统偏好设置中配置的那样。
NSURLSession
支持HTTP / 1.1
,SPDY
和HTTP / 2
协议。 HTTP / 2支持由RFC 7540描述,并需要支持ALPN
或NPN
的服务器进行协议协商。
您还可以使用NSURLProtocol添加对自己的自定义网络协议和URL scheme的支持(用于您的app的私人使用)。
注意:
NSURLSession
API涉及许多不同的类以相当复杂的方式一起工作,如果您阅读参考文档,则这些类可能并不明显。 在使用这个API之前,你应该阅读 URL Session Programming Guide以便了解这些类如何相互交互。
使用NSURLSession
API,您的app会创建一个或多个会话,每个会话都会协调一组相关的数据传输任务。 例如,如果您正在创建Web浏览器,则您的应用程序可以为每个tab或window创建一个会话,或者一个会话用于交互式使用,另一个用于后台下载。 在每个会话中,您的应用程序会添加一系列任务,其中每个任务代表对特定URL的请求(如果需要,请在HTTP redirects
之后)。
给定的URL会话中的任务共享一个公共的会话配置对象session configuration object
,该对象定义了连接行为,例如要对单个host
进行的同时连接的最大数量,是否允许通过蜂窝网络的连接等等。 会话的行为部分由您在创建配置对象时调用的方法决定:
单利共享会话
singleton shared session
(没有配置对象)用于基本请求。 它不像您创建的会话那样具有可定制性,但是如果您的要求非常有限,则它是一个很好的起点。 您可以通过调用sharedSession类方法来访问此会话。 有关其局限性的更多信息,请参阅该方法的讨论。默认会话
Default sessions
的行为与共享会话singleton shared session
非常相似(除非您进一步自定义),但是可以使用代理逐步获取数据。 您可以通过调用NSURLSessionConfiguration类的defaultSessionConfiguration方法来创建默认的会话配置。临时会话
Ephemeral sessions
与默认会话default sessions
类似,但不会将缓存cache,Cookie
或credentials
写入磁盘。 您可以通过调用NSURLSessionConfiguration类上的 ephemeralSessionConfiguration方法来创建临时会话配置。后台会话
Background sessions
允许您在应用程序未运行时在后台执行上传和下载内容。 您可以通过调用NSURLSessionConfiguration的 backgroundSessionConfiguration:方法来创建后台会话配置。
会话配置session configuration
对象还包含对URL缓存和Cookie存储对象的引用,这些对象可能在发出请求和处理响应时使用,具体取决于配置和请求类型。
会话中的任务还共享一个通用代理,以便在发生各种事件时提供和获取信息 - 当身份验证失败时,当数据从服务器到达时,当数据准备好被缓存时等等。 Using a URL Session一步一步地列出了会话执行任务时发生的事件,以及作为结果调用哪个代理方法。
另一方面,如果您不需要代理提供的任何功能,则可以在创建会话时通过传递nil来使用此API,而无需提供此功能。
重要:会话对象保持对代理的强引用,直到你的应用程序退出或显式使会话无效。 如果您不会使会话无效,那么您的应用程序会泄漏内存,直到退出。
在会话中,您可以创建任务,可选地将数据上载到服务器,然后从服务器检索数据(作为磁盘上的文件或内存中的一个或多个NSData对象)。 NSURLSession
API提供了三种类型的任务:
Data tasks
,数据任务使用NSData对象发送和接收数据。 数据任务旨在用于对服务器进行简短的交互式请求。Upload tasks
,上传任务与数据任务类似,但也会发送数据(通常以文件的形式),并在应用程序未运行时支持后台上传。Download tasks
,下载任务以文件的形式检索数据,并在应用程序不运行时支持后台下载和上传,。
像大多数网络API一样,NSURLSession
API是高度异步的。 它以两种方式之一将数据返回到您的应用程序,具体取决于您调用的方法:
当传输成功完成或发生错误时,通过调用完成处理程序块。
当数据被接收并且传输完成时,通过在会话的代理中调用方法。
除了将这些信息传递给代理,NSURLSession
API还提供状态status和进度progress属性,如果需要根据任务的当前状态做出编程决定(可以随时改变状态),可以查询状态和进度属性。
URL会话还支持取消,重新启动或恢复以及暂停任务,并提供恢复暂停,取消或失败下载的功能。
Related Classes - 相关的类
NSURLSession
API使用许多类,这些类也常用于其他API,例如NSURLConnection和 NSURLDownload。 其中一些共享类包括:
- NSURL - 包含URL的一个对象。
- NSURLRequest - 封装与URL请求有关的元数据,包括URL,请求方法等等。
- NSURLResponse - 封装与服务器对请求的响应相关的元数据,例如内容MIME类型和长度。
- NSHTTPURLResponse - 添加特定于HTTP请求的元数据,例如响应头。
- NSCachedURLResponse - 封装URL响应对象,以及服务器响应的实际主体数据,以进行缓存。
App Transport Security (ATS)
从iOS 9.0
和OS X 10.11
开始,对于使用NSURLSession
进行的所有HTTP连接,默认启用称为App Transport Security(ATS)
的新安全功能。 ATS要求HTTP连接使用HTTPS(RFC 2818)。
Using a URL Session - 使用URL会话
使用NSURLSession类发出请求
- 创建会话配置。 对于后台会话,此配置必须包含唯一标识符。 存储该标识符,并在应用程序崩溃或终止或挂起时使用该标识符与会话重新关联。
- 创建一个会话,指定一个配置对象,还可以指定一个代理。
- 在会话中创建任务代表资源请求的任务对象。 这些任务对象是NSURLSessionTask—— NSURLSessionDataTask, NSURLSessionUploadTask或NSURLSessionDownloadTask的子类,具体取决于您尝试实现的行为。 每个任务都以暂停
suspended
状态启动。 在您的应用程序调用恢复resume任务后,它开始下载指定的资源。
- 在会话中创建任务代表资源请求的任务对象。 这些任务对象是NSURLSessionTask—— NSURLSessionDataTask, NSURLSessionUploadTask或NSURLSessionDownloadTask的子类,具体取决于您尝试实现的行为。 每个任务都以暂停
在你开始一个任务之后,会话在它的代理上调用方法
- 如果与服务器的初始握手需要连接级别的挑战(如SSL客户端证书),则NSURLSession将调用URLSession:task:didReceiveChallenge:completionHandler:或 URLSession:didReceiveChallenge:completionHandler:代理方法。
- 如果任务的数据是从流中提供的,则NSURLSession对象将调用代理的 URLSession:task:needNewBodyStream:方法来获取为新请求提供主体数据的NSInputStream实例。
- 在将主体内容初始上传到服务器(如果适用)期间,代理会定期接收URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:回调,报告上传进度。
- 服务器发送一个响应。
- 如果响应表明需要身份验证,则会话将调用其代理的 URLSession:task:didReceiveChallenge:completionHandler:方法。 回到步骤2。
- 如果响应是HTTP重定向响应,则NSURLSession对象将调用代理的URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:方法。 该代理方法使用提供的
NSURLRequest
对象(遵循重定向),新的NSURLRequest对象(重定向到不同的URL)或nil(将重定向的响应主体视为有效的响应并将其返回)调用提供的完成处理程序作为结果)。
1)如果您决定遵循重定向,请返回步骤2。
2)如果委托没有实现此方法,则重定向的跟随次数达到最大重定向次数。
- 如果响应是HTTP重定向响应,则NSURLSession对象将调用代理的URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:方法。 该代理方法使用提供的
- 对于通过调用downloadTaskWithResumeData:
或downloadTaskWithResumeData:completionHandler:创建的下载(或重新下载)任务,NSURLSession
使用新的任务对象调用代理的 URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:方法。
- 对于通过调用downloadTaskWithResumeData:
- 对于数据任务,NSURLSession对象调用代理的URLSession:dataTask:didReceiveResponse:completionHandler:方法。 决定是否将数据任务转换为下载任务,然后调用完成处理程序以转换,继续或取消任务。 如果您的app选择将数据任务转换为下载任务,则NSURLSession将新下载任务作为参数调用代理的URLSession:dataTask:didBecomeDownloadTask:方法。 在这个调用之后,代理不会收到来自数据任务的进一步回调,并开始接收来自下载任务的回调。
- 在从服务器传输的过程中,代理会定期收到一个任务级回调,以报告传输进度。 对于数据任务,会话会在接收到实际的数据段时调用委托的 URLSession:dataTask:didReceiveData:方法。 对于下载任务,会话调用代理的 URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:方法的成功写入磁盘的字节数。 如果用户通知您的app暂停下载,则通过调用cancelByProducingResumeData:方法取消该任务。 稍后,如果用户请求您的应用程序继续下载,请将所返回的重启处数据传递给downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:方法以创建一个新的下载任务,以继续下载。 (转到步骤1)。
- 对于数据任务,NSURLSession对象可以调用委托的 URLSession:dataTask:willCacheResponse:completionHandler:方法。 您的应用程序应该决定是否允许缓存。 如果您不实现此方法,则默认行为是使用会话的配置对象中指定的缓存策略。
- 如果响应是多部分编码的,则会话可以再次调用代理的
didReceiveResponse
方法,然后再进行零次或多次didReceiveData
调用。 如果发生这种情况,请转到步骤8(处理didReceiveResponse
调用)。
- 如果响应是多部分编码的,则会话可以再次调用代理的
- 如果下载任务成功完成,则NSURLSession对象使用临时文件的位置调用任务的URLSession:downloadTask:didFinishDownloadingToURL:方法。您的app必须在此代理方法返回之前从此文件读取响应数据,或者将其移至永久位置。
- 当任何任务完成时,NSURLSession对象调用代理的 URLSession:task:didCompleteWithError:方法,返回的为error对象或nil(如果任务成功完成)。如果可以恢复下载任务,则NSError对象的
userInfo
字典包含NSURLSessionDownloadTaskResumeData键的值。您的app应该传递此值以调用downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:创建一个新的下载任务,以继续现有的下载。如果任务无法恢复,您的app应该创建一个新的下载任务并从头开始重新启动事务。在这两种情况下,如果传输因服务器错误以外的任何原因而失败,请转到步骤3(创建和恢复任务对象)。
- 当任何任务完成时,NSURLSession对象调用代理的 URLSession:task:didCompleteWithError:方法,返回的为error对象或nil(如果任务成功完成)。如果可以恢复下载任务,则NSError对象的
- 如果不再需要会话,则可以通过调用invalidateAndCancel(取消未完成的任务)或finishTasksAndInvalidate(以允许未完成的任务在使对象失效之前完成)来使其无效。 如果您不会使会话无效,则会在应用程序终止时自动消失(除非是具有活动任务的后台会话)。 在使会话无效之后,当所有未完成的任务被取消或完成时,会话将调用代理的 URLSession:didBecomeInvalidWithError:方法。 当该代理方法返回时,该会话将处理其对代理的强烈引用。
如果您的app取消正在进行的下载,则NSURLSession对象会像发生错误一样调用代理的 URLSession:task:didCompleteWithError:方法。
NSCopying Behavior - NSCopying行为
会话和任务对象遵循NSCopying协议如下:
- 当您的app复制一个会话或任务对象时,你会得到相同的对象。
- 当您的app复制一个配置对象时,您会得到一个您可以独立修改的新副本。
Thread Safety - 线程安全
URL会话API本身完全是线程安全的。 您可以在任何线程上下文中自由创建会话和任务,并且当您的代理方法调用提供的完成处理程序时,会自动在正确的代理队列上调度工作。
警告:您的 URLSessionDidFinishEventsForBackgroundURLSession:会话代理方法可能会在辅助线程上调用。 但是,在iOS中,您的该方法的实现可能需要调用在您的app中提供给您的完成处理程序: application:handleEventsForBackgroundURLSession:completionHandler:app代理方法。 您必须在主线程上调用完成处理程序。
Topics
1. Creating a Session
-
- 使用指定的会话配置创建一个会话。
-
+ sessionWithConfiguration:delegate:delegateQueue:
- 使用指定的会话配置,代理和操作队列创建会话。
-
- 返回一个共享的单例会话对象。
2. Configuring a Session
-
- 此会话的配置对象的副本。
-
- 创建此对象时分配的代理。
-
-
NSURLSessionDelegate
协议描述NSURLSession
对象在代理上调用以处理会话级事件的方法。
-
-
-
NSURLSessionTaskDelegate
协议定义了在使用任何类型的NSURLSession任务时应该实现的特定于任务的代理方法。
-
-
- 此对象创建时提供的操作队列
-
- 会话的应用程序定义的描述性标签。
3. Adding Data Tasks to a Session
-
- 创建一个检索指定URL内容的任务。
-
dataTaskWithURL:completionHandler:
- 创建一个检索指定URL内容的任务,然后在完成时调用一个处理程序。
-
- 创建一个基于指定的URL请求对象检索URL内容的任务。
-
- dataTaskWithRequest:completionHandler:
- 创建一个任务,根据指定的URL请求对象检索URL的内容,并在完成时调用处理程序。
-
- 将下载的数据直接返回到内存中的应用程序的URL会话任务。
-
-
NSURLSessionDataDelegate
协议定义了NSURLSession
对象的代理可以实现的方法,以处理特定于数据任务和上传任务的任务级事件。
-
4. Adding Download Tasks to a Session
-
- 创建一个下载任务,用于检索指定URL的内容并将结果保存到文件中。
-
- downloadTaskWithURL:completionHandler:
- 创建一个下载任务,用于检索指定URL的内容,将结果保存到文件中,并在完成时调用处理程序。
-
- 创建一个下载任务,根据指定的URL请求对象检索URL的内容,并将结果保存到文件中。
-
- downloadTaskWithRequest:completionHandler:
- 创建一个下载任务,根据指定的URL请求对象检索URL的内容,将结果保存到文件中,并在完成时调用处理程序。
-
- 创建一个下载任务恢复以前取消或失败的下载。
-
- downloadTaskWithResumeData:completionHandler:
- 创建一个下载任务恢复以前取消或失败的下载,并在完成后调用处理程序。
-
- 将会下载的数据存储到文件的URL会话任务。
-
- NSURLSessionDownloadDelegate协议定义了在使用NSURLSession下载任务时应该实现的代理方法。
5. Adding Upload Tasks to a Session
-
- uploadTaskWithRequest:fromData:
- 创建一个对指定的URL请求对象执行HTTP请求并上传提供的数据的任务。
-
- uploadTaskWithRequest:fromData:completionHandler:
- 创建一个对指定的URL请求对象执行HTTP请求的任务,上传提供的数据,并在完成时调用处理程序。
-
- uploadTaskWithRequest:fromFile:
- 创建执行HTTP请求以上载指定文件的任务。
-
uploadTaskWithRequest:fromFile:completionHandler:
- 创建执行HTTP请求以上载指定文件的任务,然后在完成时调用处理程序。
-
- uploadTaskWithStreamedRequest:
- 创建一个任务,根据指定的URL请求执行HTTP请求以上传数据。
-
- 以请求体的形式将数据上传到网络的URL会话任务。
-
-
NSURLSessionDataDelegate
协议定义了NSURLSession对象的代理可以实现的方法,以处理特定数据任务和上载任务的任务级事件。
-
6. Adding Stream Tasks to a Session
-
- streamTaskWithHostName:port:
- 创建一个任务,建立到指定主机名和端口的双向TCP / IP连接。
-
- 创建使用指定的网络服务建立双向TCP / IP连接的任务。
-
- 基于流的URL会话任务。
-
-
NSURLSessionStreamDelegate
协议定义了在使用NSURLSession流任务时应该实现的代理方法。
-
7. Managing the Session
-
- 使会话无效,允许任何未完成的任务完成。
-
- 刷新cookies和凭证到磁盘,清除临时缓存,并确保将来的请求发生在新的TCP连接上。
-
- getTasksWithCompletionHandler:
- 在会话中异步调用所有数据的完成回调,上载和下载任务。
-
- getAlTasksWithCompletionHandler:
- 与会话中的所有任务异步调用完成回调
-
- 取消所有未完成的任务,然后使会话失效。
-
- 清空所有的Cookie,缓存和凭证存储,删除磁盘文件,将正在进行的下载刷新到磁盘,并确保将来的请求在新套接字socket上发生。
8. Constants
-
NSURLSession-Specific NSError user<wbr>Info Dictionary Keys
- 键与NSURLSession API返回的NSError对象一起使用。
-
Background Task Cancellation reasons
- 指示后台任务为什么被取消的常量。
-
NSURLSessionDelayedRequestDisposition
- 采取延迟URL会话任务的操作。
-
- 表示未知传输大小的常量。
后记
未完,待续~~~