NSURLSessionTask官方文档阅读
2017-06-02 本文已影响60人
AppleTTT
NSURLSessionTask
NSURLSessionTask类是NSURLSession中任务的基类。 任务总是Session的一部分; 我们可以通过调用NSURLSession对象上的任务创建方法之一来创建任务。 我们调用的方法决定了任务的类型
Overview
NSURLSession提供三种类型的任务:数据任务,上传任务和下载任务。这些任务分别是NSURLSessionDataTask,NSURLSessionUploadTask,NSURLSessionDownloadTask,NSURLSessionStreamTask。
Symbols
Controlling the Task State
1. - (void)cancel
取消任务;
该方法立即返回,将任务标记为已取消。 一旦任务被标记为被取消,URLSession:task:didCompleteWithError:代理方法将会调用,并给NSURLErrorDomain传递一个错误码NSURLErrorCancelled。 在某些情况下,任务可能会在取消确认之前给其代理发送消息。(不是很懂~~~)
可能会对暂停的任务调用此方法。
2. - (void)resume
对被暂停的任务恢复其执行;
3. - (void)suspend
临时暂停执行任务;
任务暂停时,不会产生网络流量,不会超时。 下载任务可以在以后继续传输数据。 所有其他任务必须重新开始。
4. state
任务的当前状态
NSURLSessionTaskStateRunning = 0
NSURLSessionTaskStateSuspended = 1
NSURLSessionTaskStateCanceling = 2
NSURLSessionTaskStateCompleted = 3
5. priority
处理任务的相对优先级,指定为0.0(最低优先级)和1.0(最高优先级)之间的浮点值。
指定优先级仅提供提示,并不保证性能。 如果不指定优先级,则URL会话任务的优先级为NSURLSessionTaskPriorityDefault,值为0.5。
可以使用三个命名的优先级:NSURLSessionTaskPriorityDefault,NSURLSessionTaskPriorityLow和NSURLSessionTaskPriorityHigh。
我们可以随时指定或更改任务的优先级,但并不是所有网络协议在任务开始后都响应更改。 没有API可以让我们从系统的角度确定任务的有效优先级。
Obtaining Task Progress
1. countOfBytesExpectedToReceive
期望在响应主体中接收的字节数。
该值基于从服务器接收的Content-Length头部确定。 如果该值不存在,则值为NSURLSessionTransferSizeUnknown。
2. countOfBytesReceived
任务从服务器接收到的response body的字节数。
要在此值更改时收到消息,请执行URLSession:dataTask:didReceiveData:代理方法(用于数据和上传任务)或URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:方法(用于下载任务)。
3. countOfBytesExpectedToSend
任务期望在请求body中发送的字节数。
URL加载系统可以通过三种方式确定上传数据的长度:
a. 从作为上传body提供的NSData对象的长度。
b. 从作为上传任务的上传body(不是下载任务)提供的磁盘上的文件的长度。
c. 从请求对象中的Content-Length,如果我们明确设置它。
否则,如果您提供了流或身体数据对象,则该值为NSURLSessionTransferSizeUnknown(-1),否则为0(0)。
4. countOfBytesSent
任务已发送到请求body到服务器的字节数。
Obtaining General Task Information
1. currentRequest
当前由任务处理的URL请求对象。
该值通常与初始请求(originalRequest)相同,除非服务器已对初始请求作出响应,重定向到不同的URL。
2. originalRequest
创建任务时传递的原始请求对象。
3. response
服务器对当前请求的响应。
此对象提供有关服务器提供的请求的信息。 此信息始终包含原始URL。 它还可以包括预期长度,MIME类型信息,编码信息,建议的文件名,或这些的组合。
4. taskDescription
对当前任务的描述
5. taskIdentifier
session内任务的唯一标识;
该值仅在单个会话的上下文中是唯一的; 其他会话中的任务可能具有相同的taskIdentifier值。
6. error
任务失败的错误信息;
NSURLSessionDataTask
数据任务会将服务器返回的数据作为一个或多个NSData对象保存在内存中。 使用数据任务时:
1. 在上传body数据(如果请求有提供)时,session会定期调用其带有状态信息的代理方法URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:。
2. 在收到初始响应后,session将调用其代理的URLSession:dataTask:didReceiveResponse:completionHandler:方法,以便检查状态代码和头部信息,并可选择将数据任务转换为下载任务。
3. 在数据传输过程中,session调用其代理的URLSession:dataTask:didReceiveData:方法,为我们提供服务器返回的数据。
4. 数据接收完成后,session将调用其代理的URLSession:dataTask:willCacheResponse:completionHandler:方法,以确定响应是否应被缓存。
NSURLSessionUploadTask
NSURLSessionDataTask的子类;上传任务用于需要请求体(如POST或PUT)的HTTP请求。它们的行为与data task类似,但是我们可以通过在会话中调用不同的方法来创建它们,以便于更容易地提供要上传的内容。与data task一样,如果服务器提供响应,上传任务将该响应作为一个或多个NSData对象返回到内存中。
NOTE:与data task不同,我们可以使用上传任务在后台上传内容。
当我们创建上传任务时,我们需要提供一个NSURLRequest或NSMutableURLRequest对象,该对象包含我们可能需要与上传一起发送的头部信息,例如content type,content disposition等。在iOS中,当我们为后台会话中的文件创建上载任务时,系统会将该文件复制到临时位置,并从那里流出数据。
当上传正在进行时,任务会调用会话代理的URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:方法来定期向我们提供状态信息。
当请求的上传阶段完成时,该任务的行为就像一个数据任务,在会话代理上调用方法来提供服务器的响应头,状态码,内容数据等。
NSURLSessionDownloadTask
Overview
下载任务直接将服务器的响应数据写入临时文件,同时也会提供下载进度的更新。当我们在后台会话中使用下载任务时,即使应用被挂起或其他方式未运行,这些下载任务也会继续进行。
我们可以暂停(取消)下载任务并稍后恢复(假设服务器支持这样做);还可以恢复由于网络连接问题而失败的下载。
使用下载任务时:
1. 在下载期间,会话定期调用代理的带有状态信息的方法:URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:。
2. 成功完成后,会话将调用代理的URLSession:downloadTask:didFinishDownloadingToURL:方法或completionHandler。在该方法中,我们必须打开该文件进行读取或将其移动到应用程序的沙盒目录中保存下来。
3. 在下载失败后,会话将调用委托的URLSession:task:didCompleteWithError:方法或completionHandler。与NSURLSessionDataTask或NSURLSessionUploadTask不同,NSURLSessionDownloadTask将通过HTTP状态码将服务器端错误给相应的NSError对象,如下表格:
HTTPS Status | NSError Code |
---|---|
401 (未授权) | NSURLErrorUserAuthenticationRequired(需要验证才能访问资源时返回) |
403 (被禁止的) | NSURLErrorNoPermissionsToReadFile(由于权限不足,无法读取资源时返回) |
407 (需要代理验证) | NSURLErrorUserAuthenticationRequired(需要验证才能访问资源时返回) |
Other | NSURLErrorFileDoesNotExist(当文件不存在时返回) |
Symbols
1. - (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
取消下载并在回调中使用resumeData以便之后恢复下载。
completionHandler:
当下载取消成功时被调用。
如果下载是可恢复的,则completionHandler将提供一个resumeData对象。 我们可以稍后将此对象传递到会话的downloadTaskWithResumeData或downloadTaskWithResumeData:completionHandler:方法来创建一个新的任务,以恢复下载的位置。
该block不能保证在特定线程上下文中执行。 因此,我们需要指定适当的调度队列来执行它。
Discussion
只有满足以下条件,才能恢复下载:
1. 首次请求资源后,资源没有变化
2. 该任务是HTTP或HTTPS GET请求
3. 服务器在其响应中提供ETag或Last-Modified头(或两者)
4. 服务器支持字节范围请求
5. 临时文件尚未被系统删除以缓解磁盘空间压力
NSURLSessionStreamTask
Overview
NSURLSessionStreamTask类提供了一个通过NSURLSession创建TCP/IP连接的接口。 该任务可以使用NSURLSession的streamTaskWithHostName:port:和streamTaskWithNetService:方法创建。 它们也可能是HTTP Upgrade: header.NSURLSessionDataTask来升级响应头和适当使用NSURLSessionConfiguration的HTTPShouldUsePipelining选项的结果(不懂~~~)。
NOTE:有关Upgrade:header的信息,请参阅RFC 2817和RFC 6455。
NSURLSessionStreamTask对象执行异步读取和写入,这些对象被顺序执行,在session 代理队列完成后调用回调。 如果任务被取消,则所有入队读取和写入都将使用适当的错误来调用回调block。
当使用带有NSStream对象的API时,可以通过调用NSURLSessionStreamTask对象的captureStreams方法创建NSInputStream和NSOutputStream对象。
Symbols
Reading and Writing Data
1. - (void)readDataOfMinLength:(NSUInteger)minBytes maxLength:(NSUInteger)maxBytes timeout:(NSTimeInterval)timeout completionHandler:(void (^)(NSData *data, BOOL atEOF, NSError *error))completionHandler
从流中异步读取多个字节,并在完成后调用completionHandler;
minBytes:读取的最小字节数;
maxBytes:读取的最大字节数;
timeout:读取字节的超时。 如果读取在指定的时间间隔内未完成,则读取将被取消,调用completionHandler并发生错误。 通过传0以防止读取超时。
completionHandler:读取所有字节完成或者发生错误时的回调。 该completionHandler在代理队列中执行。参数如下:
a. data: 从流中读取的数据;
b. atEOF:流是否到达文件末尾(EOF),以便不再读取更多的数据。
c. error:发生错误时返回的错误信息,如果成功则为nil;
2. - (void)writeData:(NSData *)data timeout:(NSTimeInterval)timeout completionHandler:(void (^)(NSError *error))completionHandler;
将指定的数据异步写入流中,并在完成后调用completionHandler。
completionHandler参数见1;
不能保证流的服务端在完成Handler被调用时已经接收到所有写入的字节,只有确定所有的数据都已写入内核。
Capturing Streams
1. - (void)captureStreams
完成所有已经入队的读写操作,然后调用URLSession:streamTask:didBecomeInputStream:outputStream:代理方法。
Closing Read and Write Sockets
1. - (void)closeRead
完成队列中所有的读取和写入,然后关闭底层套接字的读取端。
调用此方法后,可以使用writeData:timeout:completionHandler:方法继续写入数据。 调用此方法后会导致readDataOfMinLength:maxLength:timeout:completionHandler: 方法返回错误。
2. - (void)closeWrite
完成队列中所有的读取和写入,然后关闭底层套接字的写入端。
调用此方法后,可以使用readDataOfMinLength:maxLength:timeout:completionHandler: 继续读取数据;
但是对writeData:timeout:completionHandler:方法的调用都会返回错误;
因为服务器可能会继续向客户端写入字节,所以建议您继续读取,直到流到达文件末尾(EOF)。
Starting and Stopping Secure Connections
1. - (void)startSecureConnection
完成队列中所有的读取和写入操作,并建立安全连接。
使用URLSession:task:didReceiveChallenge:completionHandler:方法进行身份安全认证。
2. - (void)stopSecureConnection
完成队列中所有的读取和写入操作,并关闭安全连接。