详细解析几个和网络请求有关的类 (一) —— NSURLSess
版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.03.08 |
前言
我们做APP发起网络请求,一般都是使用框架,这些框架的底层也都是苹果的API,接下来几篇就一起来看一下和网络有关的几个类。
NSURLSession
这个类是网络请求相关的最重要的类,可以说是网络请求的基础,任何请求都是在一个特定的会话中完成的。
NSURLSession
是NSURLConnection
的替代API。它提供影响政策的各种选择,以及各方面的政策从中检索NSURLRequest对象的机制网络。
NSURLSession可以绑定到代理对象。代理是在会话的整个生命周期中为某些事件调用,例如服务器认证或确定是否加载资源应该转换成下载。
NSURLSession
实例是线程安全的。
默认的NSURLSession
使用系统提供的代理并且是适合用来代替使用的现有代码
+ [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
NSURLSession
创建表示NSURLSessionTask
对象代表正在加载资源的操作。这些与之类似NSURLConnection
对象,但提供更多的控制和统一委托模型。
NSURLSessionTask
对象始终以挂起状态创建必须在执行之前发送- resume
消息。
NSURLSessionTask
的子类用于语法区分数据和文件下载。
NSURLSessionDataTask
以一系列调用的形式接收资源
URLSession:dataTask:didReceiveData:
代理方法。这是一种通常与检索对象关联的任务类型,以便立即解析对象。
NSURLSessionUploadTask
与NSURLSessionDataTask
不同在它的实例是如何构建的。上传任务通过引用要上传的文件或数据明确创建对象,或通过利用 - URLSession:task:needNewBodyStream:
代理消息提供上传主体。
NSURLSessionDownloadTask
将直接写入响应数据到一个临时文件。完成后,代理发送URLSession:downloadTask:didFinishDownloadingToURL:
并给予机会将此文件移动到其沙盒容器中的永久位置,或读取文件。如果取消,NSURLSessionDownloadTask
可以产生一个数据blob
,可用于稍后恢复下载时间。
从iOS 9
和Mac OS X 10.11
开始,NSURLSessionStream
就是可用作的任务类型。这允许直接的TCP / IP连接到一个给定的主机和端口与可选的安全握手和代理的导航。数据任务也可能通过HTTP Upgrade
升级到NSURLSessionStream
任务:头和适当的使用NSURLSessionConfiguration
的流水线选项。请参阅RFC 2817
和RFC 6455
以获取有关Upgrade:
header的信息以及关于将数据任务转换为流任务的注释。
NSURLSession 的优势
-
NSURLSession
支持 http2.0 协议 - 在处理下载任务的时候可以直接把数据下载到磁盘
- 支持后台下载/上传
- 同一个 session 发送多个请求,只需要建立一次连接(复用了TCP)
- 提供了全局的 session 并且可以统一配置,使用更加方便
- 下载的时候是多线程异步处理,效率更高
NSURLSession API
1. NSURLSession类
NS_CLASS_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0)
@interface NSURLSession : NSObject
/*
* The shared session uses the currently set global NSURLCache,
* NSHTTPCookieStorage and NSURLCredentialStorage objects.
*/
@property (class, readonly, strong) NSURLSession *sharedSession;
/*
* Customization of NSURLSession occurs during creation of a new session.
* If you only need to use the convenience routines with custom
* configuration options it is not necessary to specify a delegate.
* If you do specify a delegate, the delegate will be retained until after
* the delegate has been sent the URLSession:didBecomeInvalidWithError: message.
*/
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
@property (readonly, retain) NSOperationQueue *delegateQueue;
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
@property (readonly, copy) NSURLSessionConfiguration *configuration;
/*
* The sessionDescription property is available for the developer to
* provide a descriptive label for the session.
*/
@property (nullable, copy) NSString *sessionDescription;
/* -finishTasksAndInvalidate returns immediately and existing tasks will be allowed
* to run to completion. New tasks may not be created. The session
* will continue to make delegate callbacks until URLSession:didBecomeInvalidWithError:
* has been issued.
*
* -finishTasksAndInvalidate and -invalidateAndCancel do not
* have any effect on the shared session singleton.
*
* When invalidating a background session, it is not safe to create another background
* session with the same identifier until URLSession:didBecomeInvalidWithError: has
* been issued.
*/
- (void)finishTasksAndInvalidate;
/* -invalidateAndCancel acts as -finishTasksAndInvalidate, but issues
* -cancel to all outstanding tasks for this session. Note task
* cancellation is subject to the state of the task, and some tasks may
* have already have completed at the time they are sent -cancel.
*/
- (void)invalidateAndCancel;
- (void)resetWithCompletionHandler:(void (^)(void))completionHandler; /* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue if not nil. */
- (void)flushWithCompletionHandler:(void (^)(void))completionHandler; /* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue if not nil. */
- (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler; /* invokes completionHandler with outstanding data, upload and download tasks. */
- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); /* invokes completionHandler with all outstanding tasks. */
/*
* NSURLSessionTask objects are always created in a suspended state and
* must be sent the -resume message before they will execute.
*/
// NSURLSessionTask对象必须在暂停状态下创建,必须发送- resume消息才执行。
/* Creates a data task with the given request. The request may have a body stream. */
// 根据给定的请求创建数据任务,请求具有体流。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
/* Creates a data task to retrieve the contents of the given URL. */
// 创建数据任务以检索给定URL的内容
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
/* Creates an upload task with the given request. The body of the request will be created from the file referenced by fileURL */
// 根据给定的请求创建一个给定的上传任务,请求体根据fileURL文件引用创建
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
/* Creates an upload task with the given request. The body of the request is provided from the bodyData. */
// 根据给定的请求,创建一个上传任务,请求体根据bodyData提供
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
/* Creates an upload task with the given request. The previously set body stream of the request (if any) is ignored and the URLSession:task:needNewBodyStream: delegate will be called when the body payload is required. */
// 根据给定的请求创建上传任务,忽略以前请求的体流设置,当需要加载体的时候,
// 将会调用URLSession:task:needNewBodyStream: 代理方法。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
/* Creates a download task with the given request. */
// 根据指定的请求创建下载任务
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
/* Creates a download task to download the contents of the given URL. */
// 创建下载任务,下载给定URL的内容
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
/* Creates a download task with the resume data. If the download cannot be successfully resumed, URLSession:task:didCompleteWithError: will be called. */
// 根据resume data创建一个下载任务,如果下载不能成功开始,那么会调用URLSession:task:didCompleteWithError:
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
/* Creates a bidirectional stream task to a given host and port.
*/
// 创建给定主机和端口的双向流任务
- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
/* Creates a bidirectional stream task with an NSNetService to identify the endpoint.
* The NSNetService will be resolved before any IO completes.
*/
// 使用NSNetService识别端点以创建双向流任务。
// NSNetService将在任何IO完成之后解决
- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
@end
下面我们就一起来看一下这些API的用法。
@property (class, readonly, strong) NSURLSession *sharedSession;
-
sharedSession
属性表示使用当前的全局的NSURLCache
,
NSHTTPCookieStorage
和NSURLCredentialStorage
对象。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
- 这两个方法是用于返回
NSURLSession
对象的类方法,在创建新会话期间会自定义NSURLSession。如果您只需要使用具有自定义配置选项的便利例程,则无需指定代理。 如果您确实指定代理,那么代理将保留直到代理发送URLSession:didBecomeInvalidWithError:
消息。
@property (readonly, retain) NSOperationQueue *delegateQueue;
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
@property (readonly, copy) NSURLSessionConfiguration *configuration;
- 这里,delegateQueue表示操作队列,delegate表示遵循
NSURLSessionDelegate
协议的代理,configuration表示配置,用于session实例化的配置。
@property (nullable, copy) NSString *sessionDescription;
- 可以提供对session 的标签描述。
- (void)finishTasksAndInvalidate;
-
-finishTasksAndInvalidate
立即返回,现有任务将被允许运行完成。 新任务可能无法创建。 会话将继续进行代理的回调,直到发布URLSession:didBecomeInvalidWithError:
为止。- finishTasksAndInvalidate
和- invalidateAndCancel
对共享会话单例没有任何影响。 当使后台会话无效时,在URLSession:didBecomeInvalidWithError:
已经发布之前,使用相同的标识符创建另一个后台会话是不安全的。
- (void)invalidateAndCancel;
-
- invalidateAndCancel
充当- finishTasksAndInvalidate
,但是会针对此会话的所有未完成任务执行取消- cancel
。 注意取消任务取决于任务的状态,某些任务可能在发送-cancel
时已经完成。
- (void)resetWithCompletionHandler:(void (^)(void))completionHandler;
/* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue if not nil. */
// 清空所有的cookie、cache和凭证,移除磁盘文件,发送- flushWithCompletionHandler:消息,
// 如果代理队列不为空的话,就在代理队列中调用completionHandler()方法。
- (void)flushWithCompletionHandler:(void (^)(void))completionHandler;
/* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue if not nil. */
// 将存储清空到磁盘并清除瞬态网络缓存。 如果不为nil,则在代理队列上调用completionHandler()
- (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler;
/* invokes completionHandler with outstanding data, upload and download tasks. */
// 用数据,上传和下载任务调用completionHandler
- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));
/* invokes completionHandler with all outstanding tasks. */
// 用所有未完成的任务调用completionHandler
2. NSURLSession分类NSURLSessionAsynchronousConvenience
/*
* NSURLSession convenience routines deliver results to
* a completion handler block. These convenience routines
* are not available to NSURLSessions that are configured
* as background sessions.
*
* Task objects are always created in a suspended state and
* must be sent the -resume message before they will execute.
*/
// NSURLSession便捷例程将结果传递给完成处理程序块。 这些便利例程不适用于配置为后台会话的NSURLSessions。
// 任务对象总是在挂起状态创建,并且必须在执行之前发送-resume消息。
@interface NSURLSession (NSURLSessionAsynchronousConvenience)
/*
* data task convenience methods. These methods create tasks that
* bypass the normal delegate calls for response and data delivery,
* and provide a simple cancelable asynchronous interface to receiving
* data. Errors will be returned in the NSURLErrorDomain,
* see <Foundation/NSURLError.h>. The delegate, if any, will still be
* called for authentication challenges.
*/
// 数据任务的便利方法。 这些方法创建绕过普通代理调用进行响应和数据传递的任务,
// 并提供一个简单的可取消异步接口来接收数据。 错误将在NSURLErrorDomain中返回,
// 请参阅<Foundation / NSURLError.h>。 代理(如果有的话)仍将被要求认证挑战。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
/*
* upload convenience method.
*/
// 上传任务便利化方法
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
/*
* download task convenience methods. When a download successfully
* completes, the NSURL will point to a file that must be read or
* copied during the invocation of the completion routine. The file
* will be removed automatically.
*/
// 下载任务便利化方法,当成功下载完成时,URL指向一个文件,
// 这个文件必须在完成调用中进行读和赋值,文件将被自动移除。
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (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;
@end
各种形形色色的任务
下面我们就看一下这些各种不同的任务。
@interface NSURLSessionTask : NSObject <NSCopying, NSProgressReporting>
@interface NSURLSessionDataTask : NSURLSessionTask
@interface NSURLSessionUploadTask : NSURLSessionDataTask
@interface NSURLSessionDownloadTask : NSURLSessionTask
这几个任务类的继承关系如下。
NSURLSessionTask
是一个抽象类,如果要使用那么只能使用它的子类,NSURLSessionTask
有两个子类。
-
NSURLSessionDataTask
,可以用来处理一般的网络请求,如 GET | POST 请求等。NSURLSessionDataTask 有一个子类为NSURLSessionUploadTask
,用于处理上传请求的时候有优势。 -
NSURLSessionDownloadTask
,主要用于处理下载请求,有很大的优势。
各种形形色色的代理
我们看一下各种不同的代理。
@protocol NSURLSessionDelegate <NSObject>
@protocol NSURLSessionTaskDelegate <NSURLSessionDelegate>
@protocol NSURLSessionDataDelegate <NSURLSessionTaskDelegate>
@protocol NSURLSessionDownloadDelegate <NSURLSessionTaskDelegate>
@protocol NSURLSessionStreamDelegate <NSURLSessionTaskDelegate>
大家可以很清楚看到其中的继承关系。
后记
本篇主要介绍了NSURLSession的各种API接口,以及几个任务类和代理的继承关系。