美文网首页
Objective-C的网络请求相关——NSURLSession

Objective-C的网络请求相关——NSURLSession

作者: 寻心_0a46 | 来源:发表于2023-02-14 08:30 被阅读0次

NSURLSession - URL会话(协调一组相关网络数据传输任务)

NSURLSession派生自NSObject,是用来协调一组相关网络数据传输任务的对象

NSURLSession类和相关类提供了一个API,用于从URL指示的端点下载数据并将数据上传到该端点。当应用没有运行时,或者在iOS中,当应用被挂起时,API还允许应用执行后台下载。提供了一组丰富的代理方法支持身份验证,并允许应用程序收到重定向等事件的通知。

NSURLSession API涉及许多不同的类,它们以一种相当复杂的方式协同工作。

使用NSURLSession API,应用程序创建一个或多个会话,每个会话协调一组相关的数据传输任务。例如,如果正在创建一个web浏览器,应用程序可能会为每个选项卡或窗口创建一个会话,或者为交互使用创建一个会话,为后台下载创建另一个会话。在每个会话中,应用程序将添加一系列任务,每个任务表示对特定URL的请求(如果需要,将遵循HTTP重定向)。

NSURLSession常用属性
@property (class, readonly, strong) NSURLSession *sharedSession;

属性描述类属性,返回共享的单例会话对象。对于基本请求,NSURLSession类提供了一个共享的单例会话对象,为创建任务提供了一个合理的默认行为。与其他会话类型不同,创建共享会话,只需通过直接使用此属性来访问它,而不需要提供代理或配置对象

@property (readonly, retain) NSOperationQueue *delegateQueue;

属性描述创建会话对象时提供的操作队列。此队列必须在对象创建时设置,不能更改。与会话相关的所有代理方法调用和完成处理程序都在此队列上执行。会话对象保持对此队列的强引用,直到应用程序退出或会话对象被释放。如果会话对象没有被释放,则应用程序直到退出前会泄漏内存。

@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;

属性描述创建此对象时指定的代理。此代理对象必须在对象创建时设置,并且不能更改。此代理对象负责处理身份验证、做出缓存决策以及处理其他与会话相关的事件。会话对象保持对该代理的强引用,直到应用程序退出或显式地使会话失效。如果不使会话无效,应用程序直到退出前会泄漏内存。

@property (readonly, copy) NSURLSessionConfiguration *configuration;

属性描述 :只读属性,为此会话定义行为和策略的配置对象的副本,从iOS 9开始,NSURLSession对象存储了初始化时传递给它的NSURLSessionConfiguration对象的副本,这样一个会话的配置在初始化后是不可变的。对传递给会话初始化方法的配置对象的可变属性或从会话该配置属性返回的值的任何进一步更改都不会影响该会话的行为。但是可以使用修改后的配置对象创建一个新的会话。

@property (nullable, copy) NSString *sessionDescription;

属性描述应用程序为会话定义的描述性标签,默认为nil。此属性包含可用于调试目的的可读字符串。该值可以为nil,此时会话将忽略该值。

NSURLSession常用函数
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;

函数描述使用指定的会话配置创建会话

参数 :

configuration :一个指定某些行为的配置对象,例如缓存策略、超时、代理、通道、要支持的TLS版本、cookie策略和凭据存储等。

返回值 :使用指定的会话配置初始化的NSURLSession对象。

+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;

函数描述使用指定的会话配置、代理和操作队列创建会话。使用此方法创建NSURLSession对象,如果代理不为nil,需要通过调用invalidateAndCancel或finishTasksAndInvalidate方法使会话失效,否则应用程序可能泄漏内存。代理如果为nil,则该类只能与接受完成处理程序的方法一起使用

参数 :

configuration :一个指定某些行为的配置对象,例如缓存策略、超时、代理、通道、要支持的TLS版本、cookie策略和凭据存储等。

delegate :处理身份验证请求和其他与会话相关的事件的会话代理对象。该代理对象负责处理身份验证、做出缓存决策和处理其他与会话相关的事件。会话对象保持对代理的强引用,直到应用程序退出或显式地使会话失效。

queue :用于调度代理调用和完成处理程序的操作队列。队列应该是串行队列,以确保回调的正确顺序。如果为nil,会话将创建一个串行操作队列来执行所有代理方法调用和完成处理程序调用。

返回值 :使用指定的会话配置、代理和操作队列初始化的NSURLSession对象。

- (void)finishTasksAndInvalidate;

函数描述使会话失效,但允许任何未完成的任务完成。此方法立即返回,而不等待任务完成。一旦会话失效,就不能在会话中创建新任务,但现有任务将继续执行,直到完成。在最后一个任务完成后,会话进行与这些任务相关的最后一个代理的调用,会话调用其代理上的URLSession:didBecomeInvalidWithError: 方法,然后中断对代理和回调对象的引用。失效后,会话对象不能被重用。

对sharedSession方法返回的会话调用此方法无效

- (void)invalidateAndCancel;

函数描述取消所有未完成的任务,然后使会话失效。一旦失效,对委托和回调对象的引用就会中断。失效后,会话对象不能被重用。

对sharedSession方法返回的会话调用此方法无效

- (void)resetWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(void))completionHandler; 

函数描述:清空所有cookie,缓存和凭证存储,删除磁盘文件,并隐式调用flushWithCompletionHandler:方法,在委托队列上调用完成处理程序。

参数 :

completionHandler :完成处理程序。

- (void)flushWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(void))completionHandler;  

函数描述:将存储刷新到磁盘并清除临时网络缓存。

参数 :

completionHandler :完成处理程序。

- (void)getTasksWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler;

函数描述:在完成处理程序中获取未完成的数据任务、上传任务和下载任务。

参数 :

completionHandler :完成处理程序。传递给完成处理程序的数组包含在会话中创建的任何任务,但不包括已完成、已失败或被取消后无效的任何任务。

- (void)getAllTasksWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler;

函数描述:异步调用一个会话中所有任务的完成回调,可以在完成处理程序中获取所有的未完成任务。

参数 :

completionHandler :完成处理程序。接收一个任务列表参数。

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;

函数描述创建基于指定URL请求对象检索URL内容的任务。创建后需要调用resume方法启动任务。通过基于请求对象创建任务,可以通过请求对象调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request :URL请求对象,提供请求特定信息,如URL、缓存策略、请求类型和正文数据或正文流。

返回值 :新的会话数据任务。

- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;

函数描述创建检索指定URL内容的任务。创建后需要调用resume方法启动任务。该任务调用会话委托代理上的方法,提供响应元数据、响应数据等。

参数 :

url :要检索的URL。

返回值 :新的会话数据任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;

函数描述创建一个基于指定URL请求对象的执行HTTP请求用于上传指定文件的任务。创建后需要调用resume方法启动任务。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。HTTP上传请求是任何包含请求体的请求,例如POST或PUT请求。上传任务要求创建一个请求对象,以便为上传提供元数据,如HTTP请求头。

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略。

fileURL :要上传的文件的URL。

返回值 :新的会话上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;

函数描述创建一个基于指定URL请求对象的执行HTTP请求用于上传指定数据的任务。创建后需要调用resume方法启动任务。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略。

bodyData :上传的主体数据。

返回值 :新的会话上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;

函数描述创建一个基于指定URL请求对象的执行HTTP请求的上传任务。创建后需要调用resume方法启动任务。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。会话的代理必须实现URLSession:task:needNewBodyStream:方法,来为该方法提供要上传的主体数据

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略,而通过会话的代理对象的URLSession:task:needNewBodyStream:方法获取要上传的主体数据。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;

函数描述创建一个下载任务,该任务根据指定的URL请求对象检索URL的内容,并将结果保存到文件中。创建后需要调用resume方法启动任务。该任务调用会话代理上的方法,以提供进度通知、生成的临时文件的位置等。通过基于请求对象创建任务,可以调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request :一个URL请求对象,提供URL、缓存策略、请求类型、主体数据或主体流等。

返回值 :新的会话下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;

函数描述创建一个下载任务,检索指定URL的内容并将结果保存到文件中。创建后需要调用resume方法启动任务。该任务调用会话代理上的方法,以提供进度通知、生成的临时文件的位置等。

参数 :

url :要下载内容的URL。

返回值 :新的会话下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;

函数描述创建下载任务以恢复以前取消或失败的下载。创建后需要调用resume方法启动任务。这个方法等价于downloadTaskWithResumeData:completionHandler:并为完成处理程序传递一个nil参数。

参数 :

resumeData :一个数据对象,提供恢复下载所需的数据。

返回值 :新的会话下载任务。

- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));

函数描述创建一个任务,该任务建立到指定主机名和端口的双向TCP/IP连接。创建后需要调用resume方法启动任务。

参数 :

hostname :连接端点的主机名。

port :连接端点的端口。

返回值 :新的会话流任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithURL:(NSURL *)url API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述为提供的URL创建WebSocket任务。所提供的URL必须具有ws或wss方案。

参数 :

url :要创建WebSocket连接的URL。

返回值 :新的会话WebSocket任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithURL:(NSURL *)url protocols:(NSArray<NSString *>*)protocols API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述在给定URL和协议数组的情况下创建WebSocket任务。在WebSocket握手期间,任务使用提供的协议与服务器协商首选协议。该协议不会影响WebSocket框架。

参数 :

url :要创建WebSocket连接的URL。

protocols :与服务器协商的一系列协议。

返回值 :新的会话WebSocket任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithRequest:(NSURLRequest *)request API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述为提供的URL请求创建WebSocket任务。可以在对任务调用resume方法之前修改请求的属性。任务在HTTP握手阶段使用这些属性。要添加自定义协议,请添加一个带有Sec-WebSocket-Protocol密钥的头,以及一个以逗号分隔的协议列表,这些协议是希望与服务器协商的。客户端提供的自定义HTTP头在与服务器握手时保持不变。

参数 :

request :一个URL请求,指示要连接的WebSockets端点。

返回值 :新的会话WebSocket任务。

NSURLSession (NSURLSessionAsynchronousConvenience) - 分类扩展的异步处理会话数据任务的便捷代码块

NSURLSession提供的便捷程序方法创建任务,执行任务后将任务结果交付给完成处理程序块。完成处理程序块在代理队列上执行。如果完成处理程序不为nil,通过使用完成处理程序,该任务将绕过对用于响应和数据传递的代理方法的调用,而是在完成处理程序中提供任何生成的NSData、NSURL、 NSURLResponse和NSError对象。但仍然调用用于处理身份验证的代理方法如果为完成处理程序传递nil,则相当于调用了NSURLSession提供与之对应的不带完成完成处理程序块的任务创建函数,如果设置了代理,则在任务完成时仅调用会话代理方法

  • 这些便捷的程序方法对于配置为后台会话的NSURLSessions是不可用的

  • 任务对象总是在挂起状态下创建,并且在执行之前必须调用resume方法

- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建检索指定URL数据内容的任务,然后在完成时调用处理程序。仅当在其代理包含URLSession:dataTask:didReceiveData:方法的会话中创建任务时,才应传递nil作为完成处理程序。

参数 :

url : 要检索的URL。

completionHandler : 加载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error : 一个错误对象,指示请求失败的原因;如果请求成功,则为nil。

返回值 : 新会话数据任务。

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建基于指定的URL请求对象检索URL数据内容的任务,并在完成时调用处理程序。仅当在其代理包含URLSession:dataTask:didReceiveData:method的会话中创建任务时,才应传递nil作为完成处理程序。通过基于请求对象创建任务,可以调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request : 提供URL、缓存策略、请求类型、正文数据或正文流等的URL请求对象。

completionHandler : 加载请求完成时要调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :指示请求失败原因的错误对象,如果请求成功则为nil。

返回值 : 新的会话数据任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个任务,执行用于上传指定文件的HTTP请求,然后在完成时调用处理程序。HTTP上传请求是任何包含请求体的请求,例如POST或PUT请求。上传任务要求创建一个请求对象,以便为上传提供元数据,如HTTP请求头。

与uploadTaskWithRequest:fromFile:方法不同,此方法在完整接收到响应体后返回响应体,并且不需要编写自定义代理来获取响应体。

通常,只有在会话中创建任务时,其代理包含URLSession:dataTask:didReceiveData:方法,才会为完成处理程序块的参数传递nil。但如果不需要响应数据,可以使用键值观察来观察任务状态的变化,以确定任务何时完成。

参数 :

request :提供URL、缓存策略、请求类型等的NSURLRequest实例。此请求对象中的正文流和正文数据将被忽略。

fileURL :要上传的文件的URL。

completionHandler :上传请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个任务,该任务为指定的URL请求对象执行HTTP请求,上传提供的数据(NSData),并在完成时调用处理程序

与uploadTaskWithRequest:fromData:方法不同,此方法在完整接收到响应体后返回响应体,并且不需要编写自定义代理来获取响应体。

通常,只有在会话中创建任务时,其代理包含URLSession:dataTask:didReceiveData:方法,才会为完成处理程序块的参数传递nil。但如果不需要响应数据,可以使用键值观察来观察任务状态的变化,以确定任务何时完成。

参数 :

request :提供URL、缓存策略、请求类型等的NSURLRequest实例。此请求对象中的正文流和正文数据将被忽略。

bodyData :请求的主体数据。

completionHandler :上传请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的上传任务。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个下载任务,该任务根据指定的URL请求对象检索URL的内容,将结果保存到文件中,并在完成时调用处理程序。通过基于请求对象创建任务,可以优化任务行为的各个方面,包括缓存策略和超时间隔。

通常,只有在会话中创建任务时,其代理包含URLSession:downloadTask:didFinishDownloadingToURL: 方法,才会为完成处理程序块的参数传递nil。

参数 :

request :一个URL请求对象,提供URL、缓存策略、请求类型、主体数据或主体流等。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :如果请求成功完成,则为存储服务器响应的临时文件的位置。如果请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建下载任务,检索指定URL的内容,将结果保存到文件中,并在完成时调用处理程序

通常,只有在会话中创建任务时,其代理包含URLSession:downloadTask:didFinishDownloadingToURL: 方法,才会为完成处理程序块的参数传递nil。

参数 :

url :提供要下载的URL的NSURL对象。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :如果请求成功完成,则为存储服务器响应的临时文件的位置。如果请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个下载任务以恢复先前取消或失败的下载,并在完成时调用处理程序

通常,只有在会话中创建任务时,其代理包含URLSession:downloadTask:didFinishDownloadingToURL: 方法,才会为完成处理程序块的参数传递nil。

应用程序可以通过两种方式获取resumeData对象:

  • 1.如果应用程序通过调用cancelByProducingResumeData:方法,取消了一个现有的传输,会话对象将一个resumeData对象传递给cancelByProducingResumeData:方法提供的完成处理程序。
    1. 如果传输失败,会话对象提供一个NSError对象给它的代理或者任务的完成处理程序。在该对象中,userInfo字典中的NSURLSessionDownloadTaskResumeData键包含一个resumeData对象。

需要注意的是只有请求是HTTP或HTTPS的GET请求时,并且远程服务器支持字节范围请求(带有Range报头)并在其响应中提供ETag或Last-Modified报头时,才能恢复下载。如果服务器上的文件已被修改,或者由于磁盘空间不足而删除了临时文件,下载也可能重新启动。

参数 :

resumeData :一个数据对象,提供恢复下载所需的数据。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :如果请求成功完成,则为存储服务器响应的临时文件的位置。如果请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

\color{red}{例如通过基于请求对象创建请求任务的简单代码片段: }

//初始化Url
NSURL *url = [[NSURL alloc]initWithString:@"请求的url"];
//可变URL加载请求
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
//设置请求方式(默认也是GET)
[request setHTTPMethod:@"GET"];
//设置请求头
request.allHTTPHeaderFields = @{@"Content-Type":@"application/x-www-form-urlencoded",@"User-Agent":@"szyapp/ios"};
//通过单例初始化网络数据传输任务对象
NSURLSession *session = [NSURLSession sharedSession];
//通过基于请求对象创建请求任务
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  if(error == nil){
      //请求成功
      //将响应数据转换为字典
      NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
      NSLog(@"%@",jsonDict);
   }else{
      NSLog(@"%@",error);
   }
}]resume];

注:NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection(译:NSLocalizedDescription=无法加载资源,因为应用传输安全策略要求使用安全连接)错误可能是需要发送https请求,结果发送http请求导致的

NSURLSessionDelegate - 处理会话级事件的代理

一种协议,定义URL会话实例调用其代理来处理会话级事件(如会话生命周期更改)的方法。如果未分配代理给NSURLSession对象,

除此协议中定义的方法外,大多数委托还应实现NSURLSessionTaskDelegate、NSURLSessionDataDelegate和NSURLSessionDownloadDelegate协议中的一些或所有方法,以处理任务级事件。这些事件包括单个任务的开始和结束,以及数据或下载任务的定期进度更新。

处理事件时,如果提供完成回调以获取数据的情况下,不需要为NSURLSession对象设置代理,此时使用系统提供的代理。

NSURLSessionDelegate代理函数
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error;

函数描述:通知代理URL会话对象的会话已无效。如果通过调用其finishTasksAndInvalidate方法使会话失效,则会话将一直等待,直到会话中的最后一个任务完成或失败后才调用此代理方法。如果调用invalidateAndCancel方法,会话将立即调用此代理方法。

参数 :

session :无效的会话对象。

error :导致无效的错误,如果是显式的使会话无效,则为nil。

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
                                             completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

函数描述从代理请求凭据,以响应来自远程服务器的会话级身份验证请求。在两种情况下调用此方法:

  • 当远程服务器要求客户端证书或Windows NT LAN Manager (NTLM)身份验证时,允许应用程序提供适当的凭据。
  • 当会话第一次建立到使用SSL或TLS的远程服务器的连接时,允许您的应用程序验证服务器的证书链。

需要注意的是这个方法只处理NSURLAuthenticationMethodNTLM、NSURLAuthenticationMethodNegotiate、NSURLAuthenticationMethodClientCertificate和NSURLAuthenticationMethodServerTrust认证类型。

对于所有其他身份验证方案或未实现该方法,会话会调用代理的URLSession:task:didReceiveChallenge:completionHandler: 方法。

参数 :

session :包含需要请求身份验证的任务的会话。

challenge :包含身份验证请求的对象。

completionHandler :代理方法必须调用的处理程序。这个完成处理程序接受以下参数:

  • disposition :描述如何处理验证的几个常量之一。
  • credential :如果disposition设置为NSURLSessionAuthChallengeUseCredential,则该参数为应该用于身份验证的凭据,否则为NULL。
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session API_AVAILABLE(macos(11.0), ios(7.0), watchos(2.0), tvos(9.0));

函数描述:通知代理为后台会话排队的所有消息都已交付。当应用程序稍后接收到URLSessionDidFinishEventsForBackgroundURLSession:消息时,这表明之前为该会话排队的所有消息都已经交付,现在可以安全地调用之前存储的完成处理程序或开始任何可能导致调用完成处理程序的内部更新。

参数 :

session :不再有任何未完成请求的会话。

NSURLSessionTask - 会话任务基类

NSURLSessionTask类是URL会话中任务的基类。任务总是会话的一部分,可以通过调用NSURLSession实例上的一个任务创建方法来创建任务,所调用的方法决定任务的类型。

  • 使用NSURLSession的dataTaskWithURL: 方法和其相关的方法来创建NSURLSessionDataTask实例。数据任务请求一个资源,以内存中的一个或多个NSData对象的形式返回服务器的响应。支持默认会话、临时会话和共享会话,但不支持后台会话。

  • 使用NSURLSession的uploadTaskWithRequest:方法和其相关的方法来创建NSURLSessionUploadTask实例。上传任务与数据任务类似,只是它们更容易提供请求体,以便在检索服务器响应之前上传数据。后台会话支持上传任务。

  • 使用NSURLSession的downloadTaskWithURL: 相关的方法来创建NSURLSessionDownloadTask实例。下载任务将资源直接下载到磁盘上的文件。在任何类型的会话中都支持下载任务。

  • 使用NSURLSession的streamTaskWithHostName:port: 方法或streamTaskWithNetService: 方法来创建NSURLSessionStreamTask实例。流任务从主机名和端口或网络服务对象建立TCP/IP连接。

创建任务后,通过调用resume方法启动任务。然后会话保持对任务的强引用,直到请求完成或失败。你不需要维护对任务的引用,除非它对应用程序的内部记录有用。

所有任务属性都支持键值观察

NSURLSessionTask常用属性
@property (readonly)                 NSUInteger    taskIdentifier;

属性描述给定会话中任务的唯一标识符。该值仅在单个会话的上下文中是唯一的,其他会话中的任务可以具有相同的taskIdentifier值。

@property (nullable, readonly, copy) NSURLRequest  *originalRequest;

属性描述创建任务时传递的原始请求对象。这个值通常与当前活动的请求(currentRequest)相同,除非服务器已经响应了初始请求,并将其重定向到另一个URL。

@property (nullable, readonly, copy) NSURLRequest  *currentRequest;

属性描述任务当前正在处理的URL请求对象。这个值通常与初始请求(originalRequest)相同,除非服务器已经响应了初始请求,并将初始请求重定向到另一个URL。

@property (nullable, readonly, copy) NSURLResponse *response;

属性描述服务器对当前活动请求的响应。该对象提供由服务器提供的关于请求的信息。该信息总是包含原始URL,还可能包括预期长度、MIME类型信息、编码信息、建议文件名或这些的组合。

@property (nullable, retain) id <NSURLSessionTaskDelegate> delegate API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));

属性描述特定于任务的代理。此特定于任务的代理在会话的代理接收消息之前接收来到自任务的消息。

@property (readonly, strong) NSProgress *progress API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述:表示总体任务进度的对象。

@property (nullable, copy) NSDate *earliestBeginDate API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述网络加载开始的最早日期。对于从后台NSURLSession实例创建的任务,此属性表示网络加载不应早于此日期开始。设置此属性不能保证加载将在指定日期开始,只能保证加载不会更早开始。如果未指定,则不使用启动延迟。此属性对从非后台会话创建的任务无效

@property int64_t countOfBytesClientExpectsToSend API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述客户端期望发送的字节数的最佳预估上限。为此属性设置的值应考虑HTTP报头和正文数据或正文流的大小。如果不指定,则使用NSURLSessionTransferSizeUnknown。系统使用此属性优化URL会话任务的调度。强烈建议开发人员尽可能提供一个近似的上限,或者一个精确的字节计数,而不是接受默认值。

@property int64_t countOfBytesClientExpectsToReceive API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述客户端期望接收的字节数的最佳预估上限。为此属性设置的值应考虑HTTP响应标头和响应体的大小。如果不指定,则使用NSURLSessionTransferSizeUnknown。系统使用此属性优化URL会话任务的调度。强烈建议开发人员尽可能提供一个近似的上限,或者一个精确的字节计数,而不是接受默认值。

@property (readonly) int64_t countOfBytesSent;

属性描述任务在请求正文中发送给服务器的字节数。此字节计数仅包括请求体本身的长度,而不包括请求头。要在该值更改时得到通知,需要实现URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:代理方法。

@property (readonly) int64_t countOfBytesReceived;

属性描述任务在响应正文中从服务器接收的字节数。要在该值更改时得到通知,需要实现URLSession:dataTask:didReceiveData: 代理方法(用于数据和上传任务)或URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:方法(用于下载任务)。

@property (readonly) int64_t countOfBytesExpectedToSend;

属性描述任务希望在请求正文中发送的字节数。URL加载系统可以通过三种方式确定上传数据的长度: 1. 作为上传主体提供的数据对象的长度。2. 来自作为上传任务(不是下载任务)上传主体提供的磁盘上文件的长度。3. 从请求对象中的Content-Length(如果显式地设置了它)确定。否则,如果您提供了流或主体数据对象,则值为NSURLSessionTransferSizeUnknown (-1),如果没有提供,则为0。

@property (readonly) int64_t countOfBytesExpectedToReceive;

属性描述任务希望在响应正文中接收的字节数。该值基于从服务器接收的Content-Length响应头确定。如果该响应头不存在,则值为NSURLSessionTransferSizeUnknown。

@property (nullable, copy) NSString *taskDescription;

属性描述应用程序为当前任务提供的字符串描述。系统不解释该值,把它用于你认为合适的任何目的。例如可以存储任务的描述以用于调试,或者在自己的数据结构中存储跟踪任务的键。

@property (readonly) NSURLSessionTaskState state;

属性描述任务的当前状态。分为活动、挂起、正在取消或已完成。

  • NSURLSessionTaskState提供的任务当前状态枚举值:
typedef NS_ENUM(NSInteger, NSURLSessionTaskState) {
    //该任务当前正在由会话提供服务(活动)
    NSURLSessionTaskStateRunning = 0, 
    //该任务已被应用程序挂起
    NSURLSessionTaskStateSuspended = 1,
    //该任务已经取消
    NSURLSessionTaskStateCanceling = 2,   
    //任务已完成
    NSURLSessionTaskStateCompleted = 3, 
} API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
@property (nullable, readonly, copy) NSError *error;

属性描述指示任务失败原因的错误对象。如果任务仍处于活动状态或传输成功完成,则此值为nil。

@property float priority API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

属性描述希望主机处理任务的相对优先级,指定为0.0(最低优先级)到1.0(最高优先级)之间的浮点值。为主机提供提示,告诉主机如何从应用程序中将URL会话任务划分优先级,请为每个任务指定优先级。指定优先级只能提供提示,不能保证性能。如果不指定优先级,URL会话任务的优先级为NSURLSessionTaskPriorityDefault,值为0.5。

可以在任何时候指定或更改任务的优先级,但并不是所有的网络协议都在任务启动后响应更改。没有API可以从主机的角度确定任务的有效优先级。

NSURLSessionTask常用函数
- (void)suspend;

函数描述暂时挂起任务。挂起的任务不会产生网络流量,也不受超时的影响。调用resume方法可以恢复数据传输。

- (void)resume;

函数描述如果任务已挂起,则继续执行该任务。新初始化的任务以挂起状态开始,因此需要调用此方法来启动任务。

- (void)cancel;

函数描述取消任务,可以在挂起的任务上调用此方法。此方法立即返回,将任务标记为已取消。一旦一个任务被标记为取消,会调用任务代理对象的URLSession:task:didCompleteWithError: 方法,在域NSURLErrorDomain中传递一个带有代码NSURLErrorCancelled的错误。在某些情况下,任务可以在确认取消之前向其代理发送消息。

NSURLSessionTaskDelegate - 处理任务事件的代理

一种定义方法的协议,定义了NSURLSession实例在其代理上调用这些方法来处理任务级事件,同时遵循了NSURLSessionDelegate协议。如果使用dataTaskWithURL:和downloadTaskWithURL:等方法将任务添加到会话中,则在会话中设置的代理中实现此协议的方法。该会话代理还可以根据需要实现其他协议,如NSURLSessionDownloadDelegate和NSURLSessionDataDelegate协议。还可以将此类型的代理直接分配给任务,以便在任务将回调传递给会话的代理之前将回调拦截。

处理事件时,如果提供完成处理程序回调以获取数据的情况下,不需要为NSURLSession对象设置代理,此时使用系统提供的代理。

NSURLSessionTaskDelegate代理函数
- (void)URLSession:(NSURLSession *)session didCreateTask:(NSURLSessionTask *)task
    API_AVAILABLE(macos(13.0), ios(16.0), watchos(9.0), tvos(16.0));

函数描述通知代理任务已经创建。此方法是任务发送的第一条消息,在任务恢复之前提供配置任务的位置。这个委托回调被NOT分派到代理队列。在任务创建方法返回之前以同步方式调用它。

参数 :

session :包含已创建任务的会话。

task :已经创建的任务。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                        willBeginDelayedRequest:(NSURLRequest *)request
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionDelayedRequestDisposition disposition, NSURLRequest * _Nullable newRequest))completionHandler
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函数描述通知代理延迟的URL会话任务现在将开始加载。当一个延迟开始时间的后台会话任务准备开始时(使用earliestBeginDate属性设置)调用此方法。只有当请求在等待网络负载时可能变得过时并且需要被新请求替换时,才应实现此代理方法。为了继续加载,委托必须调用完成处理程序,并传入指示任务应如何进行的设置。传递NSURLSessionDelayedRequestCancel处理相当于直接在任务上调用cancel。

参数 :

session :包含延迟请求的会话。

task :处理延迟请求的任务。

request :被延迟的请求。

completionHandler :执行请求的完成处理程序。完成处理程序接受两个参数:一个是指示任务如何继续的处置方式,另一个是仅在处置为NSURLSessionDelayedRequestUseNewRequest时才使用的新请求对象。

- (void)URLSession:(NSURLSession *)session taskIsWaitingForConnectivity:(NSURLSessionTask *)task
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函数描述通知代理在开始网络加载之前,任务正在等待合适的连接可用。如果NSURLSessionConfiguration的waitsForConnectivity属性为true,并且连接不足,则调用此方法。代理可以利用此机会更新用户界面,例如通过呈现离线模式或仅蜂窝模式。每个任务最多调用一次此方法,并且仅在连接最初不可用时调用。后台会话不会调用它,因为这些会话会忽略waitsForConnectivity属性。

参数 :

session :包含等待任务的会话。

task :等待连接变化的任务。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                     willPerformHTTPRedirection:(NSHTTPURLResponse *)response
                                     newRequest:(NSURLRequest *)request
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLRequest * _Nullable))completionHandler;

函数描述通知代理远程服务器要求HTTP重定向。仅对默认会话和临时会话中的任务调用此方法,后台会话中的任务自动遵循重定向。

参数 :

session :包含其请求导致重定向的任务的会话。

task :其请求导致重定向的任务。

response :包含服务器对原始请求的响应的对象。

request :用新的请求位置填充的NSURLRequest对象。

completionHandler :处理程序应该使用请求参数的值、修改后的NSURLRequest对象或NULL来调用该块,以拒绝重定向并返回重定向响应的主体。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                            didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

函数描述向代理请求凭据,以响应来自远程服务器的身份验证请求。此方法处理任务级别的身份验证请求,对于非会话级别的挑战(所有其他),NSURLSession对象调用会话代理的该方法来处理身份验证请求。如果应用提供了一个会话代理,并且需要处理身份验证,那么必须在任务级别处理身份验证,或者提供一个任务级别的处理程序,显式地调用每个会话的处理程序。

参数 :

session :包含请求需要身份验证的任务的会话。

task :请求需要身份验证的任务。

challenge :包含身份验证请求的对象。

completionHandler :委托方法必须调用的处理程序。其中参数disposition指示如何处理身份验证验证的几个常量之一;参数credential如果配置为NSURLSessionAuthChallengeUseCredential,则应用于身份验证的凭据,否则为NULL。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                              needNewBodyStream:(void (NS_SWIFT_SENDABLE ^)(NSInputStream * _Nullable bodyStream))completionHandler NS_SWIFT_ASYNC_NAME(urlSession(_:needNewBodyStreamForTask:));

函数描述当任务需要新的请求正文流发送到远程服务器时,通知代理。任务在两种情况下调用此委托方法:

  • 如果使用uploadTaskWithStreamedRequest创建任务,则提供初始请求体流。
  • 如果由于身份验证质询或其他可恢复服务器错误,任务需要重新发送具有正文流的请求,则提供替换请求正文流。

如果代码使用文件URL或NSData对象提供请求主体,则不需要实现此方法。

参数 :

session :包含需要新正文流的任务的会话。

task :需要新正文流的任务。

completionHandler :一个完成处理程序,代理方法应该用新的正文流调用它。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                                didSendBodyData:(int64_t)bytesSent
                                 totalBytesSent:(int64_t)totalBytesSent
                       totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

函数描述定期通知代理向服务器发送正文内容的进度。totalBytesSent和totalBytesExpectedToSend参数也可以作为NSURLSessionTask的countOfBytesSent和countOfBytesExpectedToSend属性。或者由于NSURLSessionTask支持NSProgressReporting,也可以使用任务的进度属性,这可能更方便。

参数 :

session :包含数据任务的会话。

task :数据任务。

bytesSent :自上次调用此委托方法以来发送的字节数。

totalBytesSent :到目前为止发送的字节总数。

totalBytesExpectedToSend :主体数据的预期长度。URL加载系统可以通过三种方式确定上传数据的长度: 1. 从作为上传体提供的NSData对象的长度;2. 来自作为上传任务(不是下载任务)上传主体提供的磁盘上文件的长度;3. 从请求对象中的Content-Length(如果显式地设置了它)开始。否则,如果提供了流或主体数据对象,则值为NSURLSessionTransferSizeUnknown(-1),如果没有提供,则为0。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

函数描述收集完任务的完整统计信息后调用。如果实现这个代理方法,就可以通过该回调的NSURLSessionTaskMetrics 类型参数获取到采集的网络指标,实现对网络请求中DNS的查询、TCP的建立连接、TLS 握手、请求响应等各环节时间的统计。

参数 :

session :收集监控指标的会话。

task :已收集指标的任务。

metrics :收集的指标。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(nullable NSError *)error;

函数描述通知代理任务已完成数据传输。代理通过error参数接收的唯一错误是描述客户端发生的错误,如果要检查服务器端错误,则检查此回调接收到的task参数的响应属性。

参数 :

session :已完成数据传输任务的数据任务会话。

task :已完成数据传输的任务。

error :如果发生错误,则表示传输失败的错误对象,否则为NULL。

NSURLSessionDataTask - URL会话数据任务

一个URL会话任务,它直接将下载的数据返回到内存中的应用程序。NSURLSessionDataTask是NSURLSessionTask的一个具体子类。NSURLSessionDataTask类中的方法被记录在NSURLSessionTask中

数据任务将数据作为一个或多个NSData对象直接返回给在内存中的应用程序。当使用数据任务时可以:

  • 在上传主体数据期间(如果应用程序提供任何数据),会话定期调用其代理的URLSession:task:didSendBodyData: totalbytesessent:totalBytesExpectedToSend:方法报告向服务器发送正文内容的进度。

  • 在接收到初始响应后,会话调用它的委托的URLSession:dataTask:didReceiveResponse:completionHandler:方法,可以检查状态代码和响应头,并可选地将数据任务转换为下载任务。

  • 在传输过程中,会话调用它的委托的URLSession:dataTask:didReceiveData:方法,通知代理数据任务已收到一些预期数据。

  • 任务完成接收所有预期数据后,会话调用它的代理的URLSession:dataTask:willCacheResponse:completionHandler:方法,决定是否应该缓存响应。

NSURLSessionUploadTask - URL会话上传任务

在请求体中将数据上传到网络的URL会话任务。NSURLSessionUploadTask类是NSURLSessionDataTask的子类,而NSURLSessionDataTask又是NSURLSessionTask的具体子类。与NSURLSessionUploadTask类相关的方法被记录在NSURLSessionTask中

上传任务用于发出需要请求体(如POST或PUT)的HTTP请求。它们的行为与数据任务类似,但是通过在会话类上调用不同的方法来创建它们,这些方法旨在更容易地提供要上传的内容。与数据任务一样,如果服务器提供了响应,上传任务将该响应作为内存中的一个或多个NSData对象返回。

与数据任务不同,可以使用上传任务在后台上传内容。

创建上传任务时,提供一个NSURLRequest实例,该实例可能包含需要与上传的数据一起发送的任何附加请求头,例如内容类型、内容处置等。在iOS中,当你在后台会话中为一个文件创建上传任务时,系统会将该文件复制到一个临时位置,并从那里传输数据。

在上传过程中,任务会定期调用会话代理的URLSession:(NSURLSession *)session task: didSendBodyData: totalBytesSent: totalBytesExpectedToSend:方法来提供状态信息。

当请求的上传阶段结束时,该任务的行为类似于数据任务,调用会话代理上的方法提供服务器的响应标头、状态码、内容数据等。

NSURLSessionDataDelegate - 处理数据和上传任务的协议

一种定义方法的协议,定义了NSURLSession实例调用其代理来处理数据和上传任务特有的任务级事件的方法,同时遵循了NSURLSessionTaskDelegate协议。使用时需要为NSURLSessionDelegate分配代理对象,如果不分配代理,NSURLSession将使用系统提供的代理。如果NSURLSession创建任务时使用了dataTaskWithRequest: completionHandler:等带有完成处理程序的方法创建任务,则会调用完成处理程序块的方法,而不会调用用于响应和数据传递的代理方法。

NSURLSessionDataDelegate代理函数
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                 didReceiveResponse:(NSURLResponse *)response
                                  completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionResponseDisposition disposition))completionHandler;

函数描述通知代理数据任务收到了来自服务器的初始应答(响应头)。实现此方法是可选的,除非在需要在第一次接收到响应头时取消传输或将其转换为下载任务。如果不提供此代理方法,则NSURLSession始终允许任务继续。

如果需要支持相当模糊的multipart/x-mix -replace(具有多个部分的内容的MIME(互联网媒体类型)类型,每个部分都替换了前一部分)内容类型,也可以实现此方法。使用该内容类型,服务器发送一系列数据部件,数据每一个部分都用于替换前一个部分。会话在每个部分的开头调用这个方法,然后用该部分的内容调用一个或多个URLSession:dataTask:didReceiveData:方法。每次URLSession:dataTask: didreceiverresponse:completionHandler:方法被一个部分调用时,收集为前一个部分接收的数据(如果有的话),并根据应用程序的需要处理数据。这种处理可以包括将数据存储到文件系统、将其解析为自定义类型或将其显示给用户。接下来,通过使用NSURLSessionResponseAllow常量调用完成处理程序来开始接收下一部分。最后,如果还实现了URLSession:task:didCompleteWithError:方法,NSURLSession将在发送完最后一部分的所有数据后调用它。

参数 :

session :收到初始应答的数据任务会话。

dataTask :接收到初始应答的数据任务。

response :用响应头填充的Url响应对象。

completionHandler :一个完成处理程序,代码调用它来传递一个NSURLSessionResponseDisposition常量用以指示传输应该作为数据任务继续还是应该成为下载任务。

  • NSURLSessionResponseDisposition提供的枚举值:
typedef NS_ENUM(NSInteger, NSURLSessionResponseDisposition) {
    //任务将被取消
    NSURLSessionResponseCancel = 0,
    //该任务将继续作为数据任务                                      
    NSURLSessionResponseAllow = 1,
    //转为下载任务,代理的URLSession:dataTask:didBecomeDownloadTask:方法会被调用,用来提供一个新的下载任务来取代当前的任务。                                     
    NSURLSessionResponseBecomeDownload = 2,       
    //将任务转换为流任务,代理的URLSession:dataTask:didBecomeStreamTask:方法会被调用,用来提供一个新的流任务。来取代当前的任务。                       
    NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 3, 
} API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                              didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;

函数描述通知代理数据任务已更改为下载任务。当在URLSession: dataTask: didReceiveResponse: completionHandler: 代理方法中使用NSURLSessionResponseBecomeDownload来处置将请求数据转换为使用下载时,会话调用这个代理方法提供新的下载任务。在此调用之后,会话的代理将不再接收与原始数据任务相关的其他代理方法的调用。

参数 :

session : 包含被下载任务替换的任务的会话。

dataTask :被下载任务替换的数据任务。

downloadTask :替换数据任务的新下载任务。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask
    API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));

函数描述通知代理数据任务已更改为流任务。当URLSession:dataTask:didReceiveResponse:completionHandler:delegate方法使用NSURLSessionResponseBecomeStream来处置将请求数据转换为使用流任务时,会话调用此代理方法提供新的流任务。在该调用之后,会话的代理将不再接收与原始数据任务相关的代理方法的调用。

对于流式的请求,流任务只允许读取,会立即发送消通知代理对象的URLSession:writeClosedForStreamTask:方法。通过在其NSURLSessionConfiguration对象上设置HTTPShouldUsePipelining属性,可以禁用会话中的所有流式请求,或者通过在NSURLRequest对象上设置HTTPShouldUsePipelining属性来禁用单个流式请求。

参数 :

session :包含被流任务替换的任务的会话。

dataTask :被流任务替换的数据任务。

streamTask :替换数据任务的新流任务。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
                                     didReceiveData:(NSData *)data;

函数描述通知代理数据任务已经接收到一些预期的数据。此代理方法可以被调用多次,并且每次调用只提供自前一次调用以来收到的数据。如果需要这些数据,应用程序来负责积累这些数据。

因为data参数通常是由许多不同的数据对象拼凑在一起的,所以只要可能,就应使用enumerateByteRangesUsingBlock:方法来遍历数据,而不是使用bytes方法(将数据对象压扁为单个内存块)。

参数 :

session :接收到一些预期数据的数据任务会话。

dataTask :接收到一些预期数据的数据任务。

data :包含着接收到的一些预期数据的数据对象。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                  willCacheResponse:(NSCachedURLResponse *)proposedResponse 
                                  completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;

函数描述询问代理数据(或上传)任务是否应将响应存储在缓存中。任务完成接收所有预期数据后,会话调用此代理方法。如果不实现此方法,默认行为是使用会话配置对象中指定的缓存策略。此方法的主要目的是防止缓存特定URL或修改与URL响应关联的userInfo字典。

只有当处理请求的NSURLProtocol决定缓存响应时,才会调用此方法。作为规则,只有当以下所有条件都为真时,响应才会被缓存:

  • 请求是HTTP或HTTPS URL(或您自己的支持缓存的自定义网络协议)。
  • 请求成功(状态代码在200–299范围内)。
  • 所提供的响应来自服务器,而不是缓存。
  • 会话配置的缓存策略允许缓存。
  • 所提供的URLRequest对象的缓存策略(如果适用)允许缓存。
  • 服务器响应中与缓存相关的头(如果存在)允许缓存。
  • 响应大小足够小,可以合理地容纳在缓存中(例如,如果您提供磁盘缓存,响应必须不大于磁盘缓存大小的5%左右)。

参数 :

session :包含数据(或上传)任务的会话。

dataTask :数据(或上传)任务。

proposedResponse :默认的缓存行为。这种行为是基于当前缓存策略和接收到的标头的值决定的,比如Pragma和Cache-Control头。

completionHandler :处理程序必须调用的块,提供原始建议响应、该响应的修改版本或NULL以防止缓存响应。如果代理实现此方法,则必须调用此完成处理程序,否则应用程序会泄漏内存。

NSURLSessionDownloadTask - URL会话下载任务

将下载的数据存储到文件中的URL会话任务。NSURLSessionDownloadTask是NSURLSessionTask的一个具体子类,NSURLSessionTask提供了NSURLSessionDownloadTask类的大部分方法

下载任务直接将服务器的响应数据写入临时文件,当数据从服务器到达时,可以为应用程序提供进度更新。当在后台会话中使用下载任务时,即使应用处于挂起状态或没有运行,这些下载也会继续。

可以暂停(取消)下载任务并稍后恢复它们(假设服务器支持这样做)。还可以恢复由于网络连接问题而失败的下载。

- (void)cancelByProducingResumeData:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable resumeData))completionHandler;

函数描述取消下载,会调用超类中cancel函数。如果条件允许在未来恢复下载,则为完成处理程序提供resumeData对象。它可以与downloadTaskWithResumeData:方法结合使用,以尝试恢复下载。

参数 :

completionHandler :成功取消下载后调用的完成处理程序。如果下载是可恢复的,则为完成处理程序提供resumeData对象。应用程序可以稍后将此对象传递给会话的如果下载是可恢复的,则为完成处理程序提供resumeData对象。您的应用程序可以稍后将此对象传递给会话的downloadTaskWithResumeData: 方法或downloadTaskWithResumeData:completionHandler: 方法来创建一个新任务,在任务停止的地方继续下载。此块不能保证在特定线程上下文中执行。因此可能需要指定一个适当的调度队列,以便在其中执行任何工作。

NSURLSessionDownloadDelegate - 处理下载任务的协议

一种协议,它定义了NSURLSession实例在其代理上调用的方法,以处理特定于下载任务的任务级事件。同时遵循了NSURLSessionTaskDelegate协议。除此协议中的方法外,还需确保实现NSURLSessionTaskDelegate和NSURLSessionDelegate协议中的方法来分别处理所有任务类型和会话级别事件的公共事件。

使用时需要为NSURLSessionDelegate分配代理对象,如果不分配代理,NSURLSession将使用系统提供的代理。如果NSURLSession创建任务时使用了downloadTaskWithRequest: completionHandler:等带有完成处理程序的方法创建任务,则会调用完成处理程序块的方法,而不会调用用于响应和数据传递的代理方法。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;

函数描述通知代理下载任务已完成下载

参数 :

session :包含已完成的下载任务的会话。

downloadTask :已经完成的下载任务。

location :临时文件的文件URL。因为这个文件是临时的,所以在从这个代理方法返回之前,要么必须打开文件进行读取,要么将其移动到应用程序沙箱容器目录中的永久位置。如果选择打开文件进行读取,则应该在另一个线程中进行实际读取,以避免阻塞代理队列。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                           didWriteData:(int64_t)bytesWritten
                                      totalBytesWritten:(int64_t)totalBytesWritten
                              totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;

函数描述定期通知代理下载进度

参数 :

session :包含下载任务的会话。

downloadTask :下载任务。

bytesWritten :自上次调用此代理方法以来传输的字节数。

totalBytesWritten :到目前为止传输的字节总数。

totalBytesExpectedToWrite :文件的预期长度,由Content-Length头提供,如果没有提供该响应头,则值为NSURLSessionTransferSizeUnknown。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                      didResumeAtOffset:(int64_t)fileOffset
                                     expectedTotalBytes:(int64_t)expectedTotalBytes;

函数描述通知代理下载任务已恢复下载。如果可恢复的下载任务被取消或失败,可以请求一个resumeData对象,该对象提供足够的信息以便将来重新启动下载。之后可以调用downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler: 方法并传递resumeData对象恢复下载,此时将得到一个新的下载任务,会话就会使用该新任务调用此方法,以指示下载已恢复。

参数 :

session :包含已恢复的下载任务的会话。

downloadTask :恢复下载的任务。

fileOffset :如果文件的缓存策略或上次修改日期阻止重用现有内容,则该值为0。否则,该值是一个整数,表示磁盘上不需要再次检索的字节数。(在某些情况下,在文件中恢复传输的时间可能早于上一次传输结束的时间。)

expectedTotalBytes :文件的预期长度,由Content-Length响应头提供。如果没有提供该报头,则值为NSURLSessionTransferSizeUnknown。

NSURLSessionStreamTask - URL会话流任务

基于流的URL会话任务。NSURLSessionStreamTask是NSURLSessionTask的一个具体子类。NSURLSessionStreamTask类中的许多方法都记录在NSURLSessionTask中

NSURLSessionStreamTask类提供了一个通过NSURLSession创建的TCP/IP连接的接口。任务可以使用streamTaskWithHostName:port:方法和streamTaskWithNetService:方法从NSURLSession中创建。它们也可能是通过HTTP Upgrade:响应标头和适当使用NSURLSessionConfiguration的HTTPShouldUsePipelining选项来升级NSURLSessionDataTask的结果。

有关Upgrade:报头的信息,需要参阅RFC 2817和RFC 6455。

NSURLSessionStreamTask对象执行异步读写,这些读写在会话代理队列中排队并串行执行。如果任务完成,则执行会话处理程序。如果任务被取消,所有进入队列的读和写将调用它们的完成处理程序,并返回相应的错误。

当使用接受NSStream对象的Api时,可以通过调用captureStreams方法从NSURLSessionStreamTask对象创建NSInputStream和NSOutputStream对象。

- (void)readDataOfMinLength:(NSUInteger)minBytes maxLength:(NSUInteger)maxBytes timeout:(NSTimeInterval)timeout completionHandler:(void (NS_SWIFT_SENDABLE ^) (NSData * _Nullable_result data, BOOL atEOF, NSError * _Nullable error))completionHandler;

函数描述读取minBytes或最多maxBytes字节,并使用数据或错误调用会话代理队列上的完成处理程序。如果发生错误,新的读取请求将立即出错,任何未完成的读取也将失败。

参数 :

minBytes :读取的最小字节数。

maxBytes :要读取的最大字节数。

timeout :读取字节的超时。如果读取没有在指定的时间间隔内完成,则取消读取,并调用completionHandler并返回错误。传递0可以防止读取超时。

completionHandler :当读取所有字节或发生错误时调用的完成处理程序。此处理程序在代理队列上执行。这个完成处理程序接受以下参数:

  • data :从流中读取的数据。
  • atEOF :流是否到达文件结束(EOF),这样就不能再读取数据了。
  • error :一个错误对象,指示读取失败的原因,如果读取成功则为nil。
- (void)writeData:(NSData *)data timeout:(NSTimeInterval)timeout completionHandler:(void (NS_SWIFT_SENDABLE ^) (NSError * _Nullable error))completionHandler;

函数描述将数据完全写入底层套接字。如果所有的字节在超时之前还没有被写入,则会发生超时错误。调用完成处理程序并不保证远程端已经接收到所有字节,只保证它们已经被写入内核。

参数 :

data :要写入的数据。

timeout :写入字节的超时。如果写入操作没有在指定的时间间隔内完成,写入操作将被取消,completionHandler将被调用并返回一个错误。通过0来防止写入超时。

completionHandler :当写入所有字节或发生错误时调用的完成处理程序。此处理程序在代理队列上执行。这个完成处理程序接受以下参数:

  • error :一个错误对象,指示写入失败的原因,如果写入成功则为nil。
- (void)captureStreams;

函数描述完成任何已经进入队列的读写,然后调用URLSession:streamTask:didBecomeInputStream:outputStream: 代理方法。

- (void)closeWrite;

函数描述完成所有排队的读写,然后关闭底层套接字的写入端。在调用该方法后,可以继续使用readDataOfMinLength:maxLength:timeout:completionHandler: 该方法读取数据。但任何对writeData:timeout:completionHandler: 方法的调用都将导致错误。由于服务器可能会继续向客户端写入字节,因此建议继续读取,直到流到达文件结束(EOF)。

- (void)closeRead;

函数描述完成所有排队的读写,然后关闭底层套接字的读取端。在调用该方法后,可以继续使用writeData:timeout:completionHandler: 方法写入数据。但任何对readDataOfMinLength:maxLength:timeout:completionHandler: 方法的调用都将导致错误。

- (void)startSecureConnection;

函数描述完成任何排队的读写,并建立安全连接。如果需要身份验证,会回调会话代理的URLSession:task:didReceiveChallenge:completionHandler: 方法。

NSURLSessionStreamDelegate - 处理流任务的协议

一种协议,它定义了NSURLSession实例在其代理上调用的方法,以处理特定于流任务的任务级事件。同时遵循了NSURLSessionTaskDelegate协议

除此协议中的方法外,还需确保实现NSURLSessionTaskDelegate和NSURLSessionDelegate协议中的方法来分别处理所有任务类型和会话级别事件的公共事件。

- (void)URLSession:(NSURLSession *)session readClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述通知代理基础套接字的读取端已关闭。即使当前没有正在进行的读取操作,也可以调用此方法。此方法并不表示流已到达文件结束(EOF)。

参数 :

session :包含关闭读取操作的流任务的会话。

streamTask :关闭读取的流任务。

- (void)URLSession:(NSURLSession *)session writeClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述通知代理基础套接字的写入端已关闭。即使当前没有正在进行的写操作,也可以调用此方法。

参数 :

session :包含关闭写入操作的流任务的会话。

streamTask :关闭写入的流任务。

- (void)URLSession:(NSURLSession *)session betterRouteDiscoveredForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述告诉代理已为流检测到更好的主机路由。当URL加载系统确定有更好的通往端点主机的路由可用时,将调用此方法。例如,当Wi-Fi接口可用时,可以调用此方法。应该考虑完成挂起的工作并创建一个新的流任务,以便在更好的路由可用时利用它们。

参数 :

session :发现更好路由的流任务的会话。

streamTask :发现更好路由的流任务。

- (void)URLSession:(NSURLSession *)session streamTask:(NSURLSessionStreamTask *)streamTask
                                 didBecomeInputStream:(NSInputStream *)inputStream
                                         outputStream:(NSOutputStream *)outputStream;

函数描述通知代理由于流任务调用captureStreams方法,流任务已经完成。此代理方法仅在流任务的所有入队读写完成后才会被调用。

参数 :

session :已完成的流任务的会话。

streamTask :已完成的流任务。

inputStream :创建的输入流。此NSInputStream对象未打开。

outputStream :创建的输出流。此NSOutputStream对象未打开。

NSURLSessionWebSocketTask - - URL会话WebSocket任务

通过WebSockets协议标准进行通信的URL会话任务。NSURLSessionWebSocketTask是NSURLSessionTask的一个具体子类,它以WebSocket帧的形式在TCP和TLS上提供面向消息的传输协议。它遵循RFC 6455中定义的WebSocket协议

你可以用ws:或wss: URL创建一个NSURLSessionWebSocketTask。创建任务时,还可以提供一个协议列表,以便在握手阶段发布。一旦握手完成,应用程序通过会话的代理接收通知。

使用sendMessage:completionHandler:方法发送数据,用receiveMessageWithCompletionHandler:方法接收数据。该任务异步执行读写,并允许您发送和接收包含二进制帧和UTF-8编码文本帧的消息。该任务将在握手完成之前执行的任何读取或写入排入队列,并在握手完成后执行它们。

NSURLSessionWebSocketTask 与其他类型的任务一样,使用NSURLSessionTaskDelegate中的方法支持重定向和身份验证。WebSocket任务在完成握手之前调用重定向和身份验证代理方法。WebSocket任务还通过将cookie存储到会话配置的HTTPCookieStorage来支持cookie,并将cookie附加到传出的HTTP握手请求。

@property NSInteger maximumMessageSize;

属性描述出错前要缓冲的最大字节数。这包括来自连续帧的所有字节的总和。如果达到此值,接收调用将出错。

@property (readonly) NSURLSessionWebSocketCloseCode closeCode; 

属性描述可以随时查询任务的结束代码。任务未关闭时,将设置为NSURLSessionWebSocketCloseCodeInvalid。

@property (nullable, readonly, copy) NSData *closeReason;

属性描述可以随时查询任务的关闭原因。nil值表示没有任务关闭或任务仍在运行。

- (void)sendMessage:(NSURLSessionWebSocketMessage *)message completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSError * _Nullable error))completionHandler;

函数描述发送WebSocket消息。如果在发送消息时发生错误,任何未完成的工作也将失败。

参数 :

message :要发送的WebSocket消息。

completionHandler :一个接收NSError的块,表示在发送时遇到错误,如果没有发生错误则为nil。

- (void)receiveMessageWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionWebSocketMessage * _Nullable message, NSError * _Nullable error))completionHandler;

函数描述接收WebSocket消息。如果任务在缓冲帧时达到最大MessageSize,则此调用将失败并返回错误。

参数 :

completionHandler :完成处理程序。这个完成处理程序接受以下参数:

  • message :WebSocket消息。
  • error :接收消息时遇到错误的NSError。如果没有发生错误,则错误为nil。
- (void)sendPingWithPongReceiveHandler:(void (NS_SWIFT_SENDABLE ^)(NSError * _Nullable error))pongReceiveHandler;

函数描述处理从服务器接收到pong。当发送多个ping时,任务总是按照发送ping的顺序调用pongReceiveHandler。

参数 :

pongReceiveHandler :任务从服务器接收到pong时调用的块。该块接收一个NSError,该NSError指示连接丢失或其他错误,如果没有错误,则为nil。

- (void)cancelWithCloseCode:(NSURLSessionWebSocketCloseCode)closeCode reason:(nullable NSData *)reason;

函数描述关闭链接,并船队关闭原因。如果在任务上调用cancel而不是这个方法,它会发送一个取消帧,没有关闭码或原因。

参数 :

closeCode :一个NSURLSessionWebSocketCloseCode枚举值,表示关闭连接的原因。

reason :可选的进一步来解释结束的信息。此参数的值由客户端定义,而不是由标准定义。

NSURLSessionWebSocketDelegate - 处理WebSocket任务的协议

一种协议,定义了NSURLSession实例调用其代理来处理特定于WebSocket任务的任务级事件的方法。同时遵循了NSURLSessionTaskDelegate协议。

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didOpenWithProtocol:(nullable NSString *) protocol;

函数描述:通知代理WebSocket任务成功地与端点协商握手,指示协商的协议。如果握手失败,则任务不会调用此代理方法。

参数 :

session :打开的WebSocket任务的会话。

webSocketTask :打开的WebSocket任务。

protocol :在握手阶段选择的协议。如果服务器没有选择协议,或者客户端在创建任务时没有发布协议,则此参数为nil。

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didCloseWithCode:(NSURLSessionWebSocketCloseCode)closeCode reason:(nullable NSData *)reason;

函数描述:通知代理WebSocket任务从服务器端点收到关闭帧,可以选择包含来自服务器的关闭代码和原因。

参数 :

session :WebSocket任务关闭的会话。

webSocketTask :关闭的WebSocket任务。

closeCode :由服务器提供的关闭代码。如果关闭帧不包含关闭代码,则此值为nil。

reason :由服务器提供的关闭原因。如果关闭帧不包含原因,则此值为nil。

相关文章

网友评论

      本文标题:Objective-C的网络请求相关——NSURLSession

      本文链接:https://www.haomeiwen.com/subject/pbeqkdtx.html