NSURLSession 大致说明
你的App如何管理NSURLSession对象?你是每一个请求创建一个NSURLSession对象管理还是创建少量NSURLSession管理?或者创建一个NSURLSession对象管理?一般情况下我们强烈建议后者,频繁的创建可能会导致一些问题,数据证据我们还在收集之中。
这句话是苹果官方维护人员说的
在Mac OS X 10.10之前,i386目标不能使用NSURLSession。
NSURLSession是NSURLConnection的替代API。它提供了影响策略的选项,以及从网络中检索NSURLRequest对象的机制的各个方面。
可以将NSURLSession绑定到委托对象。在会话的生命周期中,将为某些事件调用委托,例如服务器身份验证或确定要加载的资源是否应转换为下载。
NSURLSession实例是线程安全的。默认的NSURLSession使用一个系统提供的委托,可以替代使用该委托的现有代码 +[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
NSURLSession创建NSURLSessionTask对象,该对象表示正在加载的资源的操作。这些类似于NSURLConnection对象,但提供了更多的控制和统一的委托模型。
NSURLSessionTask对象总是在挂起状态下创建的,在执行之前必须发送-resume消息。
NSURLSessionTask的子类用于在语法上区分数据和文件下载。
NSURLSessionDataTask以对URLSession:dataTask:didReceiveData: delegate方法的一系列调用的形式接收资源。这是一种最常见的与检索对象关联的任务类型,以便使用者立即进行解析。
NSURLSessionUploadTask与NSURLSessionDataTask的区别在于它的实例是如何构造的。上传任务是通过引用要上传的文件或数据对象显式创建的,或者使用-URLSession:task:needNewBodyStream: delegate消息来提供上传主体。
NSURLSessionDownloadTask将直接将响应数据写入临时文件。当完成时,委托将被发送URLSession:downloadTask:didFinishDownloadingToURL:并获得将该文件移动到其沙箱容器中的永久位置的机会,或以其他方式读取文件。如果取消,NSURLSessionDownloadTask可以生成一个数据blob,用于稍后恢复下载。
从iOS 9和Mac OS X 10.11开始,NSURLSessionStream作为任务类型可用。这允许使用可选的安全握手和代理导航将TCP/IP直接连接到给定的主机和端口。数据任务也可以通过HTTP Upgrade: header和适当使用NSURLSessionConfiguration的管道选项升级到NSURLSessionStream任务。有关升级的信息,请参见RFC2817和RFC 6455: header,以及下面关于将数据任务转换为流任务的注释。
NSURLSession 属性和方法说明
@property (class, readonly, strong) NSURLSession *sharedSession;
共享单例会话对象。
对于基本请求,NSURLSession类提供了一个共享的单例会话对象,为创建任务提供了一个合理的默认行为。使用共享会话仅用几行代码将URL的内容获取到内存中。
与其他会话类型不同,您不创建共享会话;您只需直接使用此属性来访问它。因此,您不需要提供委托或配置对象。
共享会话使用当前设置的全局NSURLCache、NSHTTPCookieStorage和NSURLCredentialStorage对象。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
创建具有指定会话配置的会话。
调用此方法等价于使用nil委托和队列调用sessionWithConfiguration:delegate:delegateQueue:。
指定某些行为的配置对象,如缓存策略、超时、代理、管道、要支持的TLS版本、cookie策略、凭据存储等等。
有关更多信息,请参见NSURLSessionConfiguration。
NSURLSession的自定义发生在创建新会话期间。
如果只需要使用带有自定义配置选项的便利例程,则不需要指定委托。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id )delegate delegateQueue:(nullable NSOperationQueue *)queue;
使用指定的会话配置、委托和操作队列创建会话。
指定某些行为的配置对象,如缓存策略、超时、代理、管道、要支持的TLS版本、cookie策略和凭据存储。
有关更多信息,请参见NSURLSessionConfiguration。
处理身份验证请求和其他与会话相关的事件的会话委托对象。
这个委托对象负责处理身份验证挑战、做出缓存决策以及处理其他与会话相关的事件。如果为空,则该类只应与接受完成处理程序的方法一起使用。
session对象保持对委托的强引用,直到应用程序退出或显式地使会话无效。如果您没有通过调用invalidateAndCancel或finishTasksAndInvalidate方法使会话无效,则应用程序会泄漏内存,直到它退出为止。
用于调度委托调用和完成处理程序的操作队列。队列应该是串行队列,以确保回调的正确顺序。如果为空,会话将创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。
如果您指定了一个委托,那么该委托将被保留,直到URLSession:didBecomeInvalidWithError: message发送给委托之后。
@property (readonly, retain) NSOperationQueue *delegateQueue;
创建此对象时提供的操作队列。
与会话相关的所有委托方法调用和完成处理程序都在此队列上执行。会话对象保持对该队列的强引用,直到应用程序退出或会话对象被释放。如果不使会话无效,应用程序将泄漏内存,直到它退出为止。
此队列必须在对象创建时设置,并且不能更改。
@property (nullable, readonly, retain) id delegate;
创建此对象时分配的委托。
这个委托对象负责处理身份验证挑战、做出缓存决策以及处理其他与会话相关的事件。
session对象保持对该委托的强引用,直到应用程序退出或显式地使会话无效。如果不使会话无效,应用程序将泄漏内存,直到它退出为止。
此委托对象必须在对象创建时设置,且不可更改。
@property (readonly, copy) NSURLSessionConfiguration *configuration;
此会话的配置对象的副本。
从ios9和OS X 10.11开始,NSURLSession对象存储传递给初始化器的NSURLSessionConfiguration对象的副本,使会话的配置在初始化之后是不可变的。对传递给会话初始化器的配置对象上的可变属性或从会话的配置属性返回的值的任何进一步更改都不会影响该会话的行为。但是,您可以使用修改后的configuration对象创建一个新的会话。
在iOS和macOS之前的版本中,实现中的一个bug导致NSURLSession对象存储对传递给初始化器的配置对象的引用,而不是副本。通过修改传递给会话初始化器的配置对象或从会话的配置属性返回的值,可以在初始化之后进一步配置会话的行为。通过显式调用传递给NSURLSession初始化器或从configuration属性返回的配置对象上的copy,可以确保跨不同平台版本的行为一致。
@property (nullable, copy) NSString *sessionDescription;
会话的app定义的描述性标签。
此属性包含可用于调试目的的人类可读字符串。
这个值可以是nil,默认值为nil。会话将忽略该值。
开发人员可以使用sessionDescription属性为会话提供描述性标签。
- (void)finishTasksAndInvalidate;
使会话无效,允许任何未完成的任务完成。
此方法无需等待任务完成即可立即返回。一旦会话失效,就不能在会话中创建新任务,但是现有任务将一直持续到完成。在最后一个任务完成后,会话发出与这些任务相关的最后一个委托调用,会话调用其委托上的URLSession:didBecomeInvalidWithError: 方法,然后中断对委托和回调对象的引用。失效后,会话对象不能重用。
要取消所有未完成的任务,请调用invalidateAndCancel。
在sharedSession方法返回的会话上调用此方法没有效果。
- (void)invalidateAndCancel;
取消所有未完成的任务,然后使会话无效。
一旦无效,对委托和回调对象的引用就会中断。失效后,会话对象不能重用。
要让未完成的任务一直运行到完成,可以调用finishtaskandinvalidate。
在sharedSession方法返回的会话上调用此方法没有效果。
- (void)resetWithCompletionHandler:(void (^)(void))completionHandler;
清空所有cookie、缓存和凭据存储、删除磁盘文件、将正在进行的下载刷新到磁盘,并确保将来的请求发生在新的套接字上。
completionHandler:当重置操作完成时调用的完成处理程序。此处理程序在委托队列上执行。
- (void)flushWithCompletionHandler:(void (^)(void))completionHandler;
将cookie和凭据刷新到磁盘,清除临时缓存,并确保将来的请求发生在新的TCP连接上。
completionHandler:当刷新操作完成时调用的完成处理程序。此处理程序在委托队列上执行。
- (void)getTasksWithCompletionHandler:(void (^)(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks))completionHandler;
使用会话中的所有数据、上载和下载任务异步调用完成回调。
传递给完成处理程序的数组包含在会话中创建的任何任务,不包括在完成、失败或被取消后无效的任何任务。
completionHandler:要使用任务列表调用的完成处理程序。此处理程序在委托队列上执行。
- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
使用会话中的所有任务异步调用完成回调
completionHandler:要使用任务列表调用的完成处理程序。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
创建一个任务,该任务基于指定的URL请求对象检索URL的内容。
通过基于请求对象创建任务,可以调优任务行为的各个方面,包括缓存策略和超时间隔。
创建任务之后,必须通过调用它的resume方法来启动它。
request:URL请求对象,提供特定于请求的信息,如URL、缓存策略、请求类型和主体数据或主体流。
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
创建一个任务,检索指定URL的内容。
创建任务之后,必须通过调用它的resume方法来启动它。任务调用会话委托上的方法,为您提供响应元数据、响应数据等等。
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
创建一个任务,该任务执行一个HTTP请求来上传指定的文件。
HTTP上传请求是任何包含请求体的请求,例如POST或PUT请求。上载任务要求您创建一个请求对象,以便为上载提供元数据,比如HTTP请求头。
创建任务之后,必须通过调用它的resume方法来启动它。该任务调用会话委托上的方法,为您提供上载的进度、响应元数据、响应数据等等。
request:提供URL、缓存策略、请求类型等的URL请求对象。此请求对象中的主体流和主体数据将被忽略。
fileURL:要上载的文件的URL。
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
创建一个任务,该任务为指定的URL请求对象执行HTTP请求并上传提供的数据。
HTTP上载请求是包含请求主体的任何请求,例如POST或PUT请求。上载任务要求您创建一个请求对象,以便为上载提供元数据,比如HTTP请求头。
创建任务之后,必须通过调用它的resume方法来启动它。该任务调用会话委托上的方法,为您提供上载的进度、响应元数据、响应数据等等。
request:提供URL、缓存策略、请求类型等的URL请求对象。此请求对象中的主体流和主体数据将被忽略。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
创建一个任务,该任务根据指定的URL请求为上传数据执行HTTP请求。
HTTP上载请求是包含请求主体的任何请求,例如POST或PUT请求。上载任务要求您提供一个请求对象,以便为上载提供元数据,例如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), tvos(9.0)) __WATCHOS_PROHIBITED;
创建一个任务,该任务建立到指定主机名和端口的双向TCP/IP连接。
创建任务之后,必须通过调用它的resume方法来启动它。
hostname:连接端点的主机名。
port:连接端点的端口。
- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
创建使用指定的网络服务建立双向TCP/IP连接的任务。
创建任务之后,必须通过调用它的resume方法来启动它。
service:用于确定TCP/IP连接端点的NSNetService对象。在将任何数据读取或写入结果流任务之前解析此网络服务。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
创建一个任务,该任务基于指定的URL请求对象检索URL的内容,并在完成时调用处理程序。
通过基于请求对象创建任务,可以调优任务行为的各个方面,包括缓存策略和超时间隔。
通过使用完成处理程序,任务绕过调用委托用于响应和数据交付的方法,而是在完成处理程序中提供任何结果NSData、NSURLResponse和NSError对象。但是,仍然调用处理身份验证挑战的委托方法。
只有在会话中的委托包含URLSession:dataTask:didReceiveData:方法的会话中创建任务时,才应该传递nil完成处理程序。
创建任务之后,必须通过调用它的resume方法来启动它。
如果请求成功完成,completion handler块的数据参数包含资源数据,error参数为nil。如果请求失败,数据参数为nil,错误参数包含关于失败的信息。如果接收到来自服务器的响应,无论请求是否成功完成或失败,响应参数都包含该信息。
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
创建一个任务,该任务检索指定URL的内容,然后在完成时调用处理程序。
创建任务之后,必须通过调用它的resume方法来启动它。
通过使用完成处理程序,任务绕过调用委托用于响应和数据交付的方法,而是在完成处理程序中提供任何结果NSData、NSURLResponse和NSError对象。但是,仍然调用处理身份验证挑战的委托方法。
只有在会话中的委托包含URLSession:dataTask:didReceiveData:方法的会话中创建任务时,才应该传递nil完成处理程序。
如果请求成功完成,completion handler块的数据参数包含资源数据,error参数为nil。如果请求失败,数据参数为nil,错误参数包含关于失败的信息。如果接收到来自服务器的响应,无论请求是否成功完成或失败,响应参数都包含该信息。
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
创建一个任务,该任务执行一个HTTP请求来上传指定的文件,然后在完成时调用一个处理程序。
HTTP上载请求是包含请求主体的任何请求,例如POST或PUT请求。上载任务要求您创建一个请求对象,以便为上载提供元数据,比如HTTP请求头。
与uploadTaskWithRequest:fromFile:不同,此方法在完全接收响应体之后返回响应体,并且不需要编写自定义委托来获取响应体。
通过使用完成处理程序,任务绕过调用委托用于响应和数据交付的方法,而是在完成处理程序中提供任何结果数据、响应或错误。但是,仍然调用处理身份验证挑战的委托方法。
通常,只有在会话中的委托包含URLSession:dataTask:didReceiveData:方法的会话中创建任务时,才会传递nil完成处理程序。但是,如果不需要响应数据,则使用key-value observe来监视任务状态的更改,以确定任务何时完成。
创建任务之后,必须通过调用它的resume方法来启动它。
如果请求成功完成,completion handler块的数据参数包含资源数据,error参数为nil。如果请求失败,数据参数为nil, error参数包含关于失败的信息。如果接收到来自服务器的响应,无论请求是否成功完成或失败,响应参数都包含该信息。
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
创建一个任务,该任务为指定的URL请求对象执行HTTP请求,上传提供的数据,并在完成时调用处理程序。
HTTP上载请求是包含请求主体的任何请求,例如POST或PUT请求。上载任务要求您创建一个请求对象,以便为上载提供元数据,比如HTTP请求头。
与uploadTaskWithRequest:fromData:不同,此方法在完全接收响应体之后返回响应体,并且不需要编写自定义委托来获取响应体。
通过使用完成处理程序,任务绕过调用委托用于响应和数据交付的方法,而是在完成处理程序中提供任何结果数据、响应或错误。但是,仍然调用处理身份验证挑战的委托方法。
通常,只有当在其委托包含URLSession:dataTask:didReceiveData:方法的会话中创建任务时,才会传递nil完成处理程序。但是,如果不需要响应数据,则使用key-value observe来监视任务状态的更改,以确定任务何时完成。
创建任务之后,必须通过调用它的resume方法来启动它。
如果请求成功完成,completion handler块的数据参数包含资源数据,error参数为nil。如果请求失败,数据参数为nil, error参数包含关于失败的信息。如果接收到来自服务器的响应,无论请求是否成功完成或失败,响应参数都包含该信息。
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
创建一个下载任务,该任务基于指定的URL请求对象检索URL的内容,将结果保存到文件中,并在完成时调用处理程序。
通过基于请求对象创建任务,可以调优任务行为的各个方面,包括缓存策略和超时间隔。
通过使用完成处理程序,任务绕过调用委托用于响应和数据交付的方法,而是在完成处理程序中提供任何结果NSURL、NSURLResponse和NSError对象。但是,仍然调用处理身份验证挑战的委托方法。
只有在会话中创建任务时,其委托包含URLSession:downloadTask:didFinishDownloadingToURL:方法时,才应该传递nil完成处理程序。
创建任务之后,必须通过调用它的resume方法来启动它。
如果请求成功完成,completion handler块的location参数包含临时文件的位置,error参数为nil。如果请求失败,location参数为nil, error参数包含关于失败的信息。如果接收到来自服务器的响应,无论请求是否成功完成或失败,响应参数都包含该信息。
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
参考上面
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
参考上面
涉及相关类(未深度研究的)
NSNetService