详细解析几个和网络请求有关的类 (一) —— NSURLSession(一)

版本记录

版本号 时间
V1.0 2018.03.08

前言

我们做APP发起网络请求,一般都是使用框架,这些框架的底层也都是苹果的API,接下来几篇就一起来看一下和网络有关的几个类。

NSURLSession

这个类是网络请求相关的最重要的类,可以说是网络请求的基础,任何请求都是在一个特定的会话中完成的。

NSURLSessionNSURLConnection的替代API。它提供影响政策的各种选择,以及各方面的政策从中检索NSURLRequest对象的机制网络。

NSURLSession可以绑定到代理对象。代理是在会话的整个生命周期中为某些事件调用,例如服务器认证或确定是否加载资源应该转换成下载。

NSURLSession实例是线程安全的。

默认的NSURLSession使用系统提供的代理并且是适合用来代替使用的现有代码
+ [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]

NSURLSession创建表示NSURLSessionTask对象代表正在加载资源的操作。这些与之类似NSURLConnection对象,但提供更多的控制和统一委托模型。

NSURLSessionTask对象始终以挂起状态创建必须在执行之前发送- resume消息。

NSURLSessionTask的子类用于语法区分数据和文件下载。

NSURLSessionDataTask以一系列调用的形式接收资源
URLSession:dataTask:didReceiveData:代理方法。这是一种通常与检索对象关联的任务类型,以便立即解析对象。

NSURLSessionUploadTaskNSURLSessionDataTask不同在它的实例是如何构建的。上传任务通过引用要上传的文件或数据明确创建对象,或通过利用 - URLSession:task:needNewBodyStream:代理消息提供上传主体。

NSURLSessionDownloadTask将直接写入响应数据到一个临时文件。完成后,代理发送URLSession:downloadTask:didFinishDownloadingToURL:并给予机会将此文件移动到其沙盒容器中的永久位置,或读取文件。如果取消,NSURLSessionDownloadTask可以产生一个数据blob,可用于稍后恢复下载时间。

iOS 9Mac OS X 10.11开始,NSURLSessionStream就是可用作的任务类型。这允许直接的TCP / IP连接到一个给定的主机和端口与可选的安全握手和代理的导航。数据任务也可能通过HTTP Upgrade升级到NSURLSessionStream任务:头和适当的使用NSURLSessionConfiguration的流水线选项。请参阅RFC 2817RFC 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,
    NSHTTPCookieStorageNSURLCredentialStorage对象。
+ (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接口,以及几个任务类和代理的继承关系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容