Snip20151216_3.png
NSURLSession使用注意事項
-
NSURLSession
- 所謂
網絡會話
,就是一段同服務器之間的通訊
。一個session
可以由數個數據傳輸任務
構成。 - session類型由
NSURLSessionConfiguration
對象決定:-
Default Session / 默認會話
- 功能類似于
NSURLConnection
。 - 磁盤緩存。
- 用
keychain
保存證書。
- 功能類似于
-
Ephemeral Session / 臨時會話
- 內存緩存。
- 不保存證書。
-
invalidate
后,所有信息會被抹去
。
-
Background Session / 后臺會話
- app退出后,
數據傳輸任務
被移動至一個獨立的進程中繼續執行
。 - 任務在后臺執行時,遇到錯誤會
自動重試
。 - 除了某些限制之外,其它同特性
默認會話
相似。
- app退出后,
-
- 所謂
-
NSURLSessionTask
- 會話期間所執行的
數據傳輸任務
。 - task類型(所有的task都通過
NSURLSession
創建)-
NSURLSessionDataTask / 數據任務
- 以
NSData
的形式接收服務器返回的數據
。 -
分段監測
數據。 - 適用于
頻繁的短小通訊
。
- 以
-
NSURLSessionDownloadTask / 下載任務
- 以
文件
的形式接收服務器返回的數據。 - 解決了大文件下載的
內存管理
問題。 - 能夠
斷點續傳
:- 其
cancelByProducingResumeData:
會生成一個XML
數據,保存了續傳所需的信息
。 - 利用這個數據重新創建
download task
,以繼續下載。 - 只有通過
GET
方法獲取的文件才可以斷點續傳。
- 其
- 支持
后臺下載
。
- 以
-
NSURLSessionUploadTask / 上傳任務
- 向服務器發送
文件數據
。 - 支持
后臺上傳
。 - 一般不使用,原因如下:
-
不能
自動封裝請求體,即仍然需要手動創建Request body
。 - 如果上傳的是
NSData
數據,可以使用POST
方法;但對于磁盤文件
,只能使用PUT
方法,現在基本沒有服務器支持這一方法。
-
- 向服務器發送
-
- 會話期間所執行的
-
后臺任務
- session必須通過
backgroundSessionConfigurationWithIdentifier:
創建。 - 在一個
獨立進程
中執行。 - 必須使用
delegate
實現回調。 - 只支持
HTTP/HTTPs協議
。 - 自動接受
Redirection
。 - 上傳任務必須
從文件上傳
。 - 如果任務開始時
app處于后臺
,那么configuration
對象的discretinary
屬性被設置為YES。
- session必須通過
/*
后臺任務執行流程
*/
(app已退出)后臺任務進行中--->
==================================
情況A:任務完成 / 需要驗證證書--->
1. app代理方法application:handleEventsForBackgroundURLSession:completionHandler:被調用
2. 在其中所需執行的操作:
- 保存completionHandler
- 根據identifier創建一個background configuration
- 創建background session
--->
3. 后臺任務被自動納入新建session--->
4. 所有任務完成,session代理方法URLSessionDidFinishEventsForBackgroundURLSession:被調用--->
5. 執行之前保存的completionHandler(注意,其屬于UIKit,必須在主線程上執行)
==================================
情況B:用戶再次啟動app--->
1. 在app代理方法application:didFinishLaunchingWithOptions:中根據identifier,創建仍有未完成任務的session對象(一個或多個)
--->
2. 后臺任務被自動納入新建session--->
- 示例代碼
/*
Session代理方法
*/
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
{
NSLog(@"所有后臺任務已經完成");
if (session.configuration.identifier) {
// 執行實現保存的后臺session回調
self.backgrondSessionCompletionHandler();
}
}
======================================
/*
app代理方法
*/
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
// 創建配置對象
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
// 根據配置對象創建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self.sessionDelegate delegateQueue:[NSOperationQueue new]];
NSLog(@"session被重新創建");
// 保存completionHandler
self.backgrondSessionCompletionHandler = completionHandler;
}
-
SSL / TLS 驗證
-
Session-Level Challenges / 會話級別驗證
,首先嘗試調用session代理方法URLSession:didReceiveChallenge:completionHandler:
。其次嘗試調用task打理方法URLSession:task:didReceiveChallenge:completionHandler:
。 -
Non-Session-Level Challenges / 非會話級別驗證
,只調用task代理方法URLSession:task:didReceiveChallenge:completionHandler:
。
-
-
注意事項
- session的數據傳輸任務能且只能
在子線程上執行
。 - 只有NSURLConnection才支持
同步任務
。 - 同時實現
回調block
和代理方法
,默認只調用前者
。 - 如果采用block進行回調,系統會對session進行默認
代理支持
。 - session的
delegate
負責處理session和task級別的回調。 - 用完的session
必須釋放
,否則會造成內存泄漏
。因為session會對其delegate
進行強引用
。
- session的數據傳輸任務能且只能