NSURLSession使用注意事項

Snip20151216_3.png

NSURLSession使用注意事項


  • NSURLSession

    • 所謂網絡會話,就是一段同服務器之間的通訊。一個session可以由數個數據傳輸任務構成。
    • session類型由NSURLSessionConfiguration對象決定:
      • Default Session / 默認會話
        • 功能類似于NSURLConnection
        • 磁盤緩存。
        • keychain保存證書。
      • Ephemeral Session / 臨時會話
        • 內存緩存。
        • 不保存證書。
        • invalidate后,所有信息會被抹去
      • Background Session / 后臺會話
        • 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。

/*
后臺任務執行流程
*/

(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進行強引用
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容