版本記錄
| 版本號 | 時間 |
|---|---|
| V1.0 | 2018.03.08 |
前言
我們做APP發(fā)起網(wǎng)絡請求,一般都是使用框架,這些框架的底層也都是蘋果的API,接下來幾篇就一起來看一下和網(wǎng)絡有關的幾個類。
NSURLSession
這個類是網(wǎng)絡請求相關的最重要的類,可以說是網(wǎng)絡請求的基礎,任何請求都是在一個特定的會話中完成的。
NSURLSession是NSURLConnection的替代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)的任務類型,以便立即解析對象。
NSURLSessionUploadTask與NSURLSessionDataTask不同在它的實例是如何構建的。上傳任務通過引用要上傳的文件或數(shù)據(jù)明確創(chuàng)建對象,或通過利用 - URLSession:task:needNewBodyStream:代理消息提供上傳主體。
NSURLSessionDownloadTask將直接寫入響應數(shù)據(jù)到一個臨時文件。完成后,代理發(fā)送URLSession:downloadTask:didFinishDownloadingToURL:并給予機會將此文件移動到其沙盒容器中的永久位置,或讀取文件。如果取消,NSURLSessionDownloadTask可以產(chǎn)生一個數(shù)據(jù)blob,可用于稍后恢復下載時間。
從iOS 9和Mac OS X 10.11開始,NSURLSessionStream就是可用作的任務類型。這允許直接的TCP / IP連接到一個給定的主機和端口與可選的安全握手和代理的導航。數(shù)據(jù)任務也可能通過HTTP Upgrade升級到NSURLSessionStream任務:頭和適當?shù)氖褂?code>NSURLSessionConfiguration的流水線選項。請參閱RFC 2817和RFC 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,
NSHTTPCookieStorage和NSURLCredentialStorage對象。
+ (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接口,以及幾個任務類和代理的繼承關系。
