詳細解析幾個和網(wǎng)絡請求有關的類 (一) —— NSURLSession(一)

版本記錄

版本號 時間
V1.0 2018.03.08

前言

我們做APP發(fā)起網(wǎng)絡請求,一般都是使用框架,這些框架的底層也都是蘋果的API,接下來幾篇就一起來看一下和網(wǎng)絡有關的幾個類。

NSURLSession

這個類是網(wǎng)絡請求相關的最重要的類,可以說是網(wǎng)絡請求的基礎,任何請求都是在一個特定的會話中完成的。

NSURLSessionNSURLConnection的替代API。它提供影響政策的各種選擇,以及各方面的政策從中檢索NSURLRequest對象的機制網(wǎng)絡。

NSURLSession可以綁定到代理對象。代理是在會話的整個生命周期中為某些事件調(diào)用,例如服務器認證或確定是否加載資源應該轉換成下載。

NSURLSession實例是線程安全的。

默認的NSURLSession使用系統(tǒng)提供的代理并且是適合用來代替使用的現(xiàn)有代碼
+ [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]

NSURLSession創(chuàng)建表示NSURLSessionTask對象代表正在加載資源的操作。這些與之類似NSURLConnection對象,但提供更多的控制和統(tǒng)一委托模型。

NSURLSessionTask對象始終以掛起狀態(tài)創(chuàng)建必須在執(zhí)行之前發(fā)送- resume消息。

NSURLSessionTask的子類用于語法區(qū)分數(shù)據(jù)和文件下載。

NSURLSessionDataTask以一系列調(diào)用的形式接收資源
URLSession:dataTask:didReceiveData:代理方法。這是一種通常與檢索對象關聯(lián)的任務類型,以便立即解析對象。

NSURLSessionUploadTaskNSURLSessionDataTask不同在它的實例是如何構建的。上傳任務通過引用要上傳的文件或數(shù)據(jù)明確創(chuàng)建對象,或通過利用 - URLSession:task:needNewBodyStream:代理消息提供上傳主體。

NSURLSessionDownloadTask將直接寫入響應數(shù)據(jù)到一個臨時文件。完成后,代理發(fā)送URLSession:downloadTask:didFinishDownloadingToURL:并給予機會將此文件移動到其沙盒容器中的永久位置,或讀取文件。如果取消,NSURLSessionDownloadTask可以產(chǎn)生一個數(shù)據(jù)blob,可用于稍后恢復下載時間。

iOS 9Mac OS X 10.11開始,NSURLSessionStream就是可用作的任務類型。這允許直接的TCP / IP連接到一個給定的主機和端口與可選的安全握手和代理的導航。數(shù)據(jù)任務也可能通過HTTP Upgrade升級到NSURLSessionStream任務:頭和適當?shù)氖褂?code>NSURLSessionConfiguration的流水線選項。請參閱RFC 2817RFC 6455以獲取有關Upgrade:header的信息以及關于將數(shù)據(jù)任務轉換為流任務的注釋。


NSURLSession 的優(yōu)勢

  • NSURLSession 支持 http2.0 協(xié)議
  • 在處理下載任務的時候可以直接把數(shù)據(jù)下載到磁盤
  • 支持后臺下載/上傳
  • 同一個 session 發(fā)送多個請求,只需要建立一次連接(復用了TCP)
  • 提供了全局的 session 并且可以統(tǒng)一配置,使用更加方便
  • 下載的時候是多線程異步處理,效率更高

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對象必須在暫停狀態(tài)下創(chuàng)建,必須發(fā)送- resume消息才執(zhí)行。

/* Creates a data task with the given request.  The request may have a body stream. */
// 根據(jù)給定的請求創(chuàng)建數(shù)據(jù)任務,請求具有體流。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;

/* Creates a data task to retrieve the contents of the given URL. */
// 創(chuàng)建數(shù)據(jù)任務以檢索給定URL的內(nèi)容
- (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 */
// 根據(jù)給定的請求創(chuàng)建一個給定的上傳任務,請求體根據(jù)fileURL文件引用創(chuàng)建
- (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. */
// 根據(jù)給定的請求,創(chuàng)建一個上傳任務,請求體根據(jù)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. */
// 根據(jù)給定的請求創(chuàng)建上傳任務,忽略以前請求的體流設置,當需要加載體的時候,
// 將會調(diào)用URLSession:task:needNewBodyStream: 代理方法。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;

/* Creates a download task with the given request. */
// 根據(jù)指定的請求創(chuàng)建下載任務
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;

/* Creates a download task to download the contents of the given URL. */
// 創(chuàng)建下載任務,下載給定URL的內(nèi)容
- (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. */
// 根據(jù)resume data創(chuàng)建一個下載任務,如果下載不能成功開始,那么會調(diào)用URLSession:task:didCompleteWithError: 
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;

/* Creates a bidirectional stream task to a given host and port.
 */
// 創(chuàng)建給定主機和端口的雙向流任務
- (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識別端點以創(chuàng)建雙向流任務。
// 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對象的類方法,在創(chuàng)建新會話期間會自定義NSURLSession。如果您只需要使用具有自定義配置選項的便利例程,則無需指定代理。 如果您確實指定代理,那么代理將保留直到代理發(fā)送URLSession:didBecomeInvalidWithError:消息。
@property (readonly, retain) NSOperationQueue *delegateQueue;
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
@property (readonly, copy) NSURLSessionConfiguration *configuration;
  • 這里,delegateQueue表示操作隊列,delegate表示遵循NSURLSessionDelegate協(xié)議的代理,configuration表示配置,用于session實例化的配置。
@property (nullable, copy) NSString *sessionDescription;
  • 可以提供對session 的標簽描述。
- (void)finishTasksAndInvalidate;
  • -finishTasksAndInvalidate立即返回,現(xiàn)有任務將被允許運行完成。 新任務可能無法創(chuàng)建。 會話將繼續(xù)進行代理的回調(diào),直到發(fā)布URLSession:didBecomeInvalidWithError:為止。- finishTasksAndInvalidate- invalidateAndCancel對共享會話單例沒有任何影響。 當使后臺會話無效時,在URLSession:didBecomeInvalidWithError:已經(jīng)發(fā)布之前,使用相同的標識符創(chuàng)建另一個后臺會話是不安全的。
- (void)invalidateAndCancel;
  • - invalidateAndCancel充當- finishTasksAndInvalidate,但是會針對此會話的所有未完成任務執(zhí)行取消- cancel。 注意取消任務取決于任務的狀態(tài),某些任務可能在發(fā)送-cancel時已經(jīng)完成。
- (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和憑證,移除磁盤文件,發(fā)送- flushWithCompletionHandler:消息,
// 如果代理隊列不為空的話,就在代理隊列中調(diào)用completionHandler()方法。

- (void)flushWithCompletionHandler:(void (^)(void))completionHandler;    
/* flush storage to disk and clear transient network caches.  Invokes completionHandler() on the delegate queue if not nil. */
// 將存儲清空到磁盤并清除瞬態(tài)網(wǎng)絡緩存。 如果不為nil,則在代理隊列上調(diào)用completionHandler()

- (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler; 
/* invokes completionHandler with outstanding data, upload and download tasks. */
// 用數(shù)據(jù),上傳和下載任務調(diào)用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. */
// 用所有未完成的任務調(diào)用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。 
// 任務對象總是在掛起狀態(tài)創(chuàng)建,并且必須在執(zhí)行之前發(fā)送-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.
 */
// 數(shù)據(jù)任務的便利方法。 這些方法創(chuàng)建繞過普通代理調(diào)用進行響應和數(shù)據(jù)傳遞的任務,
// 并提供一個簡單的可取消異步接口來接收數(shù)據(jù)。 錯誤將在NSURLErrorDomain中返回,
// 請參閱<Foundation / NSURLError.h>。 代理(如果有的話)仍將被要求認證挑戰(zhàn)。
- (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指向一個文件,
// 這個文件必須在完成調(diào)用中進行讀和賦值,文件將被自動移除。
- (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,可以用來處理一般的網(wǎng)絡請求,如 GET | POST 請求等。NSURLSessionDataTask 有一個子類為 NSURLSessionUploadTask,用于處理上傳請求的時候有優(yōu)勢。
  • NSURLSessionDownloadTask,主要用于處理下載請求,有很大的優(yōu)勢。

各種形形色色的代理

我們看一下各種不同的代理。

  • @protocol NSURLSessionDelegate <NSObject>
  • @protocol NSURLSessionTaskDelegate <NSURLSessionDelegate>
  • @protocol NSURLSessionDataDelegate <NSURLSessionTaskDelegate>
  • @protocol NSURLSessionDownloadDelegate <NSURLSessionTaskDelegate>
  • @protocol NSURLSessionStreamDelegate <NSURLSessionTaskDelegate>

大家可以很清楚看到其中的繼承關系。

后記

本篇主要介紹了NSURLSession的各種API接口,以及幾個任務類和代理的繼承關系。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容