NSURLSession相关的代理方法

首先看下NSURLSessionDelegate等相关代理方法列表:

NSURLSessionDelegate等代理方法.png

以下为每个代理方法的作用的详细说明
1.NSURLSessionDelegate

@protocol NSURLSessionDelegate 
@optional

/*
当Session invallid(无效)的时候,也是就调用了invalidateAndCancel 和
finishTasksAndInvalidate方法的时候,会调用这个代理方法
 */
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error;

/* 
NSURLSession接收到后台的挑战的时候,我们要在这里进行判断一下
只要请求的地址是HTTPS的, 就会调用这个代理方法
 我们需要在该方法中告诉系统, 是否信任服务器返回的证书
 Challenge: 挑战 质问 (包含了受保护的区域)
 protectionSpace : 受保护区域
 NSURLAuthenticationMethodServerTrust : 证书的类型是 服务器信任
 */
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
                                             completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

/*
 应用在后台,而且后台所有下载任务完成后,
 在所有其他NSURLSession和NSURLSessionDownloadTask委托方法执行完后回调,可以在该方法中做下载数据管理和UI刷新
  */
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

@end

2.NSURLSessionTaskDelegate


@protocol NSURLSessionTaskDelegate 
@optional
/*
系统在发起请求之前会调一个这个回调,
然后在这个completionHandler里面你告诉系统这个请求是否要发出去,是否要修改
(告诉代理现在将开始加载延迟的URL会话任务。
当具有延迟开始时间的后台会话任务(由earliestBeginDate属性设置)准备就绪时,将调用此方法。只有在等待网络负载时请求可能变陈旧并需要被新请求替换时,才应实现此委托方法。
为了继续加载,委托人必须调用完成处理程序,并传递一个处理方式来指示任务应该如何进行。传递NSURLSessionDelayedRequestCancel处置等效于直接调用任务的取消。)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                        willBeginDelayedRequest:(NSURLRequest *)request
                              completionHandler:(void (^)(NSURLSessionDelayedRequestDisposition disposition, NSURLRequest * _Nullable newRequest))completionHandler
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

/*
告诉代理,在开始网络加载之前,任务正在等待,直到合适的连接可用。
 如果NSURLSessionConfiguration的waitsForConnectivity属性为true并且没有足够的连接,则调用此方法。 代表可以利用这个机会来更新用户界面;
 例如通过呈现离线模式或仅限蜂窝模式。
 此方法最多只能在每个任务中调用一次,并且仅在连接最初不可用时调用。 它永远不会被调用后台会话,因为这些会话会忽略waitsForConnectivity。
 */
- (void)URLSession:(NSURLSession *)session taskIsWaitingForConnectivity:(NSURLSessionTask *)task
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

/* 
告诉委托远程服务器请求HTTP重定向。
此方法仅适用于默认和临时会话中的任务。 后台会话中的任务会自动遵循重定向。
需要后台返回statusCode=302/301这两种状态同时要配置上新的request
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                     willPerformHTTPRedirection:(NSHTTPURLResponse *)response
                                     newRequest:(NSURLRequest *)request
                              completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler;

/* 
响应来自远程服务器的认证请求,从代理请求凭证。
 该方法处理任务级别的身份验证挑战。 NSURLSessionDelegate协议还提供了会话级别的身份验证委托方法。所调用的方法取决于身份验证挑战的类型:
对于会话级挑战-NSURLAuthenticationMethodNTLM,NSURLAuthenticationMethodNegotiate,NSURLAuthenticationMethodClientCertificate或NSURLAuthenticationMethodServerTrust - NSURLSession对象调用会话委托的URLSession:didReceiveChallenge:completionHandler:方法。如果您的应用程序未提供会话委托方法,则NSURLSession对象会调用任务委托人的URLSession:task:didReceiveChallenge:completionHandler:方法来处理该挑战。
对于非会话级挑战(所有其他挑战),NSURLSession对象调用会话委托的URLSession:task:didReceiveChallenge:completionHandler:方法来处理挑战。如果您的应用程序提供会话委托,并且您需要处理身份验证,那么您必须在任务级别处理身份验证,或者提供明确调用每会话处理程序的任务级别处理程序。会话委托的URLSession:didReceiveChallenge:completionHandler:方法不针对非会话级别的挑战进行调用。
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                            didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
                              completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

/* 
当任务需要新的请求主体流发送到远程服务器时,告诉委托。
这种委托方法在两种情况下被调用:
1、如果使用uploadTaskWithStreamedRequest创建任务,则提供初始请求正文流:
2、如果任务因身份验证质询或其他可恢复的服务器错误需要重新发送包含正文流的请求,则提供替换请求正文流。
注:如果代码使用文件URL或NSData对象提供请求主体,则不需要实现此功能。
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                              needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler;

/* 
定期通知代理向服务器发送主体内容的进度。(上传进度) 
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                                didSendBodyData:(int64_t)bytesSent
                                 totalBytesSent:(int64_t)totalBytesSent
                       totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

/*
 告诉代理该会话完成了该任务的收集指标。
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

/* 
告诉代理该任务完成传输数据。
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(nullable NSError *)error;

@end

3.NSURLSessionDataDelegate

@optional
/* 
告诉代理数据任务从服务器收到初始回复(headers)。
//取消加载, 与[task cancel]一致 
NSURLSessionResponseCancel = 0,   
// 继续加载 
NSURLSessionResponseAllow = 1,    
//转为下载                              
NSURLSessionResponseBecomeDownload = 2,  
//转为任务流                     
NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 3
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                 didReceiveResponse:(NSURLResponse *)response
                                  completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;

/* 
告诉代理数据任务已更改为下载任务。
当委托的URLSession:dataTask:didReceiveResponse:completionHandler:方法决定将数据请求的处置更改为下载时,会话将调用此委托方法为你提供新的下载任务。 在此调用之后,会话委托不会收到与原始数据任务相关的其他委托方法调用
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                              didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;

/*
告诉委托数据任务已更改为流任务
当委托的URLSession:dataTask:didReceiveResponse:completionHandler:方法决定将处置从数据请求更改为流时,会话将调用此委托方法为你提供新的流任务。 在此调用之后,会话委托不会收到与原始数据任务相关的其他委托方法调用。

对于pipelined的请求,流任务将只允许读取,并且对象将立即发送委托消息URLSession:writeClosedForStreamTask :. 通过在其NSURLSessionConfiguration对象上设置HTTPShouldUsePipelining属性,或通过在NSURLRequest对象上设置HTTPShouldUsePipelining属性来为各个请求设置会话中的所有请求,可以禁用管道传输。
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask;

/* 
告诉代理该数据任务已经收到了一些预期的数据。 
由于NSData对象通常是由许多不同的数据对象拼凑而成的,因此尽可能使用NSData的enumerateByteRangesUsingBlock:方法遍历数据,而不是使用bytes方法(将NSData对象平化为单个内存块)。
此委托方法可能被多次调用,并且每次调用仅提供自上次调用后收到的数据。 如果需要,该应用负责积累这些数据。
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                     didReceiveData:(NSData *)data;

/*
询问委托数据(或上传)任务是否应将响应存储在缓存中。
会话在任务完成接收所有预期数据后调用此委托方法。如果未实现此方法,则默认行为是使用会话配置对象中指定的缓存策略。此方法的主要目的是防止特定URL的缓存或修改与URL响应关联的userInfo字典。
只有在处理请求的NSURLProtocol决定缓存响应时才调用此方法。通常,只有满足以下所有条件时才会缓存响应:
1、请求是针对HTTP或HTTPS URL(或你自己的支持缓存的自定义网络协议)。
2、请求成功(状态码在200-299范围内)。
3、提供的响应来自服务器,而不是缓存。
4、会话配置的缓存策略允许缓存。
5、提供的NSURLRequest对象的缓存策略(如果适用)允许缓存。
6、服务器响应中的缓存相关头(如果存在)允许缓存。
7、响应大小足够小,可以合理地放入缓存中。 (例如,如果您提供磁盘缓存,则响应不得超过磁盘缓存大小的5%。)
注:如果委托实现此方法,则它必须调用completionHandler完成处理程序;否则,应用程序会泄漏内存。
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                  willCacheResponse:(NSCachedURLResponse *)proposedResponse 
                                  completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;

@end

4.NSURLSessionDownloadDelegate

/* 
告诉委托下载任务已完成下载。
location:
临时文件的文件URL。 由于该文件是临时文件,因此必须先打开文件进行阅读或将其移至应用程序的沙箱容器目录中的永久位置,然后才能从此委派方法返回。
如果选择打开文件进行阅读,则应该在另一个线程中进行实际阅读,以避免阻塞委托队列。
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;

@optional
/* 
定期通知代理有关下载的进度。 
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                           didWriteData:(int64_t)bytesWritten
                                      totalBytesWritten:(int64_t)totalBytesWritten
                              totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;

/*
告诉委托下载任务已经恢复下载。
filrOffest:
如果文件的缓存策略或上次修改日期阻止重新使用现有内容,则该值为零。否则,该值是一个整数,表示磁盘上不需要再次检索的字节数。

如果可恢复的下载任务被取消或失败,可以请求resumeData对象,该对象将提供足够的信息以重新开始下载。稍后,你可以调用downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler:使用该数据。
当你调用这些方法时,你会得到一个新的下载任务。只要恢复该任务,会话就会使用该新任务调用其委托的URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:方法,以指示恢复下载。
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                      didResumeAtOffset:(int64_t)fileOffset
                                     expectedTotalBytes:(int64_t)expectedTotalBytes;

@end

5.NSURLSessionStreamDelegate

@optional

/* 
告诉委托底层套接字的读取面已经关闭。
即使当前过程没有读取,也可以调用此方法。 此方法并不表示流达到end-of-file(EOF),从而不能读取更多数据。
*/
- (void)URLSession:(NSURLSession *)session readClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

/* 
告诉委托底层套接字的写入端已关闭。 
即使当前过程没有写入,也可以调用此方法。
 */
- (void)URLSession:(NSURLSession *)session writeClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

/* 
告诉委托流已经检测到通往主机更好的路由
 */
- (void)URLSession:(NSURLSession *)session betterRouteDiscoveredForStreamTask:(NSURLSessionStreamTask *)streamTask;

/* 
告诉委托,流任务已完成,由于流任务调用captureStreams方法。
此委托方法仅在流任务的所有入队读取和写入操作完成后才会调用。
 */
- (void)URLSession:(NSURLSession *)session streamTask:(NSURLSessionStreamTask *)streamTask
                                 didBecomeInputStream:(NSInputStream *)inputStream
                                         outputStream:(NSOutputStream *)outputStream;

@end

参考文献:https://www.jianshu.com/p/2ab336db172c

你可能感兴趣的:(NSURLSession相关的代理方法)