与网络相关的几个重要的类(一) —— NSURLSession(一)

版本记录

版本号 时间
V1.0 2018.01.09

前言

APP都需要与服务器进行数据交互,极个别的除外,比如简单的相机,计算器等等,不需要登录和服务端存储信息的APP,绝大多数都是需要和服务器进行交互的,那就需要用到网络,接下来几篇就讲述一下与网络相关的几个类。

Overview

该类作用是用来协调一组相关网络数据传输任务的对象。

NSURLSession类和相关类提供了用于下载内容的API。 此API提供了一组丰富的委托方法来支持身份验证,并使您的应用能够在应用未运行时或者暂停应用时执行后台下载。

NSURLSession类本地支持datafileftphttphttps URL schemes,透明地支持代理proxy服务器和SOCKS网关,如用户系统偏好设置中配置的那样。

NSURLSession支持HTTP / 1.1SPDYHTTP / 2协议。 HTTP / 2支持由RFC 7540描述,并需要支持ALPNNPN的服务器进行协议协商。

您还可以使用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,Cookiecredentials写入磁盘。 您可以通过调用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.0OS X 10.11开始,对于使用NSURLSession进行的所有HTTP连接,默认启用称为App Transport Security(ATS)的新安全功能。 ATS要求HTTP连接使用HTTPS(RFC 2818)。


Using a URL Session - 使用URL会话

使用NSURLSession类发出请求

    1. 创建会话配置。 对于后台会话,此配置必须包含唯一标识符。 存储该标识符,并在应用程序崩溃或终止或挂起时使用该标识符与会话重新关联。
    1. 创建一个会话,指定一个配置对象,还可以指定一个代理。
    1. 在会话中创建任务代表资源请求的任务对象。 这些任务对象是NSURLSessionTask—— NSURLSessionDataTask, NSURLSessionUploadTask或NSURLSessionDownloadTask的子类,具体取决于您尝试实现的行为。 每个任务都以暂停suspended状态启动。 在您的应用程序调用恢复resume任务后,它开始下载指定的资源。

在你开始一个任务之后,会话在它的代理上调用方法

    1. 如果与服务器的初始握手需要连接级别的挑战(如SSL客户端证书),则NSURLSession将调用URLSession:task:didReceiveChallenge:completionHandler:或 URLSession:didReceiveChallenge:completionHandler:代理方法。
    1. 如果任务的数据是从流中提供的,则NSURLSession对象将调用代理的 URLSession:task:needNewBodyStream:方法来获取为新请求提供主体数据的NSInputStream实例。
    1. 在将主体内容初始上传到服务器(如果适用)期间,代理会定期接收URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:回调,报告上传进度。
    1. 服务器发送一个响应。
    1. 如果响应表明需要身份验证,则会话将调用其代理的 URLSession:task:didReceiveChallenge:completionHandler:方法。 回到步骤2。
    1. 如果响应是HTTP重定向响应,则NSURLSession对象将调用代理的URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:方法。 该代理方法使用提供的NSURLRequest对象(遵循重定向),新的NSURLRequest对象(重定向到不同的URL)或nil(将重定向的响应主体视为有效的响应并将其返回)调用提供的完成处理程序作为结果)。
      1)如果您决定遵循重定向,请返回步骤2。
      2)如果委托没有实现此方法,则重定向的跟随次数达到最大重定向次数。
    1. 对于通过调用downloadTaskWithResumeData:
      或downloadTaskWithResumeData:completionHandler:创建的下载(或重新下载)任务,NSURLSession使用新的任务对象调用代理的 URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:方法。
    1. 对于数据任务,NSURLSession对象调用代理的URLSession:dataTask:didReceiveResponse:completionHandler:方法。 决定是否将数据任务转换为下载任务,然后调用完成处理程序以转换,继续或取消任务。 如果您的app选择将数据任务转换为下载任务,则NSURLSession将新下载任务作为参数调用代理的URLSession:dataTask:didBecomeDownloadTask:方法。 在这个调用之后,代理不会收到来自数据任务的进一步回调,并开始接收来自下载任务的回调。
    1. 在从服务器传输的过程中,代理会定期收到一个任务级回调,以报告传输进度。 对于数据任务,会话会在接收到实际的数据段时调用委托的 URLSession:dataTask:didReceiveData:方法。 对于下载任务,会话调用代理的 URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:方法的成功写入磁盘的字节数。 如果用户通知您的app暂停下载,则通过调用cancelByProducingResumeData:方法取消该任务。 稍后,如果用户请求您的应用程序继续下载,请将所返回的重启处数据传递给downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:方法以创建一个新的下载任务,以继续下载。 (转到步骤1)。
    1. 对于数据任务,NSURLSession对象可以调用委托的 URLSession:dataTask:willCacheResponse:completionHandler:方法。 您的应用程序应该决定是否允许缓存。 如果您不实现此方法,则默认行为是使用会话的配置对象中指定的缓存策略。
    1. 如果响应是多部分编码的,则会话可以再次调用代理的didReceiveResponse方法,然后再进行零次或多次didReceiveData调用。 如果发生这种情况,请转到步骤8(处理didReceiveResponse调用)。
    1. 如果下载任务成功完成,则NSURLSession对象使用临时文件的位置调用任务的URLSession:downloadTask:didFinishDownloadingToURL:方法。您的app必须在此代理方法返回之前从此文件读取响应数据,或者将其移至永久位置。
    1. 当任何任务完成时,NSURLSession对象调用代理的 URLSession:task:didCompleteWithError:方法,返回的为error对象或nil(如果任务成功完成)。如果可以恢复下载任务,则NSError对象的userInfo字典包含NSURLSessionDownloadTaskResumeData键的值。您的app应该传递此值以调用downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:创建一个新的下载任务,以继续现有的下载。如果任务无法恢复,您的app应该创建一个新的下载任务并从头开始重新启动事务。在这两种情况下,如果传输因服务器错误以外的任何原因而失败,请转到步骤3(创建和恢复任务对象)。
    1. 如果不再需要会话,则可以通过调用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:

    • 使用指定的会话配置创建一个会话。
  • + sessionWithConfiguration:delegate:delegateQueue:

    • 使用指定的会话配置,代理和操作队列创建会话。
  • sharedSession

    • 返回一个共享的单例会话对象。

2. Configuring a Session

  • configuration

    • 此会话的配置对象的副本。
  • delegate

    • 创建此对象时分配的代理。
  • NSURLSessionDelegate

    • NSURLSessionDelegate协议描述NSURLSession对象在代理上调用以处理会话级事件的方法。
  • NSURLSessionTaskDelegate

    • NSURLSessionTaskDelegate协议定义了在使用任何类型的NSURLSession任务时应该实现的特定于任务的代理方法。
  • delegateQueue

    • 此对象创建时提供的操作队列
  • sessionDescription

    • 会话的应用程序定义的描述性标签。

3. Adding Data Tasks to a Session

  • - dataTaskWithURL:

    • 创建一个检索指定URL内容的任务。
  • dataTaskWithURL:completionHandler:

    • 创建一个检索指定URL内容的任务,然后在完成时调用一个处理程序。
  • - dataTaskWithRequest:

    • 创建一个基于指定的URL请求对象检索URL内容的任务。
  • - dataTaskWithRequest:completionHandler:

    • 创建一个任务,根据指定的URL请求对象检索URL的内容,并在完成时调用处理程序。
  • NSURLSessionDataTask

    • 将下载的数据直接返回到内存中的应用程序的URL会话任务。
  • NSURLSessionDataDelegate

    • NSURLSessionDataDelegate协议定义了NSURLSession对象的代理可以实现的方法,以处理特定于数据任务和上传任务的任务级事件。

4. Adding Download Tasks to a Session

  • downloadTaskWithURL:

    • 创建一个下载任务,用于检索指定URL的内容并将结果保存到文件中。
  • - downloadTaskWithURL:completionHandler:

    • 创建一个下载任务,用于检索指定URL的内容,将结果保存到文件中,并在完成时调用处理程序。
  • - downloadTaskWithRequest:

    • 创建一个下载任务,根据指定的URL请求对象检索URL的内容,并将结果保存到文件中。
  • - downloadTaskWithRequest:completionHandler:

    • 创建一个下载任务,根据指定的URL请求对象检索URL的内容,将结果保存到文件中,并在完成时调用处理程序。
  • - downloadTaskWithResumeData:

    • 创建一个下载任务恢复以前取消或失败的下载。
  • - downloadTaskWithResumeData:completionHandler:

    • 创建一个下载任务恢复以前取消或失败的下载,并在完成后调用处理程序。
  • NSURLSessionDownloadTask

    • 将会下载的数据存储到文件的URL会话任务。
  • NSURLSessionDownloadDelegate

    • 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请求以上传数据。
  • NSURLSessionUploadTask

    • 以请求体的形式将数据上传到网络的URL会话任务。
  • NSURLSessionDataDelegate

    • NSURLSessionDataDelegate协议定义了NSURLSession对象的代理可以实现的方法,以处理特定数据任务和上载任务的任务级事件。

6. Adding Stream Tasks to a Session

  • - streamTaskWithHostName:port:

    • 创建一个任务,建立到指定主机名和端口的双向TCP / IP连接。
  • - streamTaskWithNetService:

    • 创建使用指定的网络服务建立双向TCP / IP连接的任务。
  • NSURLSessionStreamTask

    • 基于流的URL会话任务。
  • NSURLSessionStreamDelegate

    • NSURLSessionStreamDelegate协议定义了在使用NSURLSession流任务时应该实现的代理方法。

7. Managing the Session

  • - finishTasksAndInvalidate

    • 使会话无效,允许任何未完成的任务完成。
  • - flushWithCompletionHandler:

    • 刷新cookies和凭证到磁盘,清除临时缓存,并确保将来的请求发生在新的TCP连接上。
  • - getTasksWithCompletionHandler:

    • 在会话中异步调用所有数据的完成回调,上载和下载任务。
  • - getAlTasksWithCompletionHandler:

    • 与会话中的所有任务异步调用完成回调
  • - invalidateAndCancel

    • 取消所有未完成的任务,然后使会话失效。
  • - resetWithCompletionHandler:

    • 清空所有的Cookie,缓存和凭证存储,删除磁盘文件,将正在进行的下载刷新到磁盘,并确保将来的请求在新套接字socket上发生。

8. Constants

  • NSURLSession-Specific NSError userInfo Dictionary Keys

    • 键与NSURLSession API返回的NSError对象一起使用。
  • Background Task Cancellation reasons

    • 指示后台任务为什么被取消的常量。
  • NSURLSessionDelayedRequestDisposition

    • 采取延迟URL会话任务的操作。
  • Transfer Size Constant

    • 表示未知传输大小的常量。

后记

未完,待续~~~

与网络相关的几个重要的类(一) —— NSURLSession(一)_第1张图片

你可能感兴趣的:(与网络相关的几个重要的类(一) —— NSURLSession(一))