iOS基礎深入補完計劃--網絡模塊NSURLSession概述

目錄

  • 前言
  • 概述
  • NSURLRequest
  • NSURLSessionConfiguration
  • NSURLSession
  • NSURLSessionTask
  • Deleagte
  • 一些其他的點
  • NSURLCache
  • NSURLResponse/NSHTTPURLResponse
  • NSURLCredential
  • NSURLAuthenticationChallenge
  • NSURLProtectionSpace

前言:

其實是第一次仔細的接觸iOS的網絡模塊、當時培訓的時候學過不過早就已經忘光了(現在只記得AFNetworking、比前端程序員依賴jQuery更甚)。

準備先了解個大概、然后再逐一深入。
所以本篇并沒寫Demo、也沒有涉及太具體的請求代碼。
旨在通過一篇文章能對NSURLSession了解個大概(最起碼面試簡單扯皮夠用)
也整理了大部分相關的API、有興趣可以自己翻閱(在本文最后)
然后本文主要的學習大綱是通過《IOS網絡開發NSURLSession詳解》整理的、推薦閱讀


概述

對于iOS而言、網絡變成主要依賴兩種方式:NSURLSession以及NSURLConnection。對于NSURLConnection、我入行甚至培訓iOS的時候、就淘汰并且被NSURLSession取代了。也不太有精力學一個已經廢棄的東西就為了寫點東西、所以沒啥可說的(如果有精力可以去找一篇總結二者區別比較全面的貼出來)。

咳、簡單總結一下:
1、下載任務時:
NSURLConnection會先放在內存、最后寫入沙盒。可能引起內存暴漲。
NSURLSession會直接寫在沙盒和tem文件夾中、最后需要手動轉移。
2、請求控制:
NSURLConnection創建好了對象、便開始網絡請求。
只能cancel并不能恢復。
NSURLSession則在掛起狀態需要手動resume。
可以取消(cancel)、暫停(suspend)、繼續(resume)。
3、斷點續傳:
NSURLConnection通過設置訪問請求的HTTPHeaderField的Range屬性、繼續下載剩余的部分。
NSURLSession通過將任務暫停時候代理返回的resumeData傳入downloadTaskWithResumeData:方法進行續傳。
4、配置信息:
NSURLConnection只能全局配置。
NSURLSession每一個實例都可以通過NSURLSessionConfiguration進行配置。

詳閱:《NSURLSession與NSURLConnection區別》

了解NSURLSession的話。該從哪里切入呢?寫一個網絡請求就知道了

- (void)NSURLSessionTest {
    
    /******1、NSURLRequest********/
    NSString *urlString = @"http://api.androidhive.info/volley/person_object.json";
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
    
    /******2、NSURLSessionConfiguration********/
    NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    /******3、NSURLSession********/
    NSURLSession *sharedSession = [NSURLSession sessionWithConfiguration:configuration];

    /******4、NSURLSessionTask********/
    NSURLSessionDataTask *dataTask = [sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSLog(@"data=%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        } else {
            NSLog(@"error=%@",error);
        }
    }];
    [dataTask resume];
}

很直觀的、至少有四個部分:NSURLRequestNSURLSessionConfigurationNSURLSession以及NSURLSessionTask
但實際上有一個很重要的部分----代理、他可以比block細致的多的管理我們的網絡請求。
所以主要是五個部分。


NSURLRequest

  • NSURLRequest

兩種創建方式
1、直接通過NSURL創建:
默認超時60s、緩存策略NSURLRequestUseProtocolCachePolicy

+ (instancetype)requestWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL;

2、通過NSURL超時時間緩存策略共同創建:

+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;

不論哪種方式、默認都是通過Get方式傳輸。

你可以通過NSURLRequest的屬性獲取很多相關的信息:
包括超時時間、請求的URL、緩存目錄、是否支持蜂窩網絡等等。
需要注意的是這些都是readonly、不能被修改。
但是對于比如請求方式、請求頭、請求體、cookie等HTTP方面的屬性。是可以修改的(iOS為NSURLRequest寫了個NSHTTPURLRequest擴展、這種思路其實可以借鑒一下)

  • NSMutableURLRequest

顧名思義、他可以修改絕大部分(或者應該說是所有?我并沒有逐個去查找對比、但是絕大部分平時用得到的東西都是能修改的)屬性。


NSURLSessionConfiguration

NSURLSession提供一個配置策略、NSURLSession在初始化時會copyNSURLSessionConfiguration。所以如果需要不同的策略、需要不同的Configuration來生成新的session。
通常的使用就是以下三種:

  • @property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
    默認配置:會將緩存、鑰匙串、cookie都保存下來。
  • @property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
    可以看錯無痕瀏覽:所有東西隨著session的廢棄而廢棄。

(說句題外話、defaultSessionConfigurationephemeralSessionConfiguration看其他帖子好像以前是類方法、原來還有class這種寫法、為啥非要這么寫呢、沒發現什么必要性)

  • +(NSURLSessionConfiguration*)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
    正常來講APP在退出到后臺的時候、網絡傳輸將會停止。
    但通過background配置的session、當APP被切入后臺的時候依舊可以進行網絡會話。
    甚至進程被關閉后重新開啟、只要有同一個identifier、也能繼續會話(這不就是斷點續傳么?)。
除此之外、NSURLSessionConfiguration還可以配置很多東西。

比如:請求頭信息、傳輸的類型、是否允許蜂窩傳輸、超時時間、cookie的控制、證書的存儲、緩存(NSURLCache)、緩存策略(NSURLRequestCachePolicy)、最大連接數等等。

需要注意的是

NSURLSessionConfiguration所能配置的策略、有一些和NSURLRequest能配置的會沖突。
這時候、會優先使用NSURLRequest中的配置(比如超時、請求頭等等)。


NSURLSession

NSURLSession是iOS網絡會話的最核心模塊。
由NSURLSessionConfiguration來配置、針對NSURLRequest創建出NSURLSessionTask進行網絡會話。

其本身不進行網絡會話的工作。但是通過代理或者block的方式、可以捕獲網絡會話的不同狀態并加以處理。

  • 產出task、并通過block捕獲最終狀態
//生成session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//產出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  //taks完成
}];
//開始task
[dataTask resume];
  • 直接產出task、并且通過代理控制
//生成session并綁定代理
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
//產出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL]];
//開始task
[dataTask resume];

/* 
  各種各樣的代理、包括session(`證書、重定向`)方面
  以及task(`鏈接成功、每次buffer的返回、傳輸完畢等等`)方面
*/

NSURLSessionTask

偷一張圖



簡單明了、NSURLSessionTask本身是個抽象類、不進行任何工作。

  • DataTask:
    用來請求資源、后臺模式下不支持。

  • Upload Task:
    基于DataTask、但是提供了request body可以傳遞具體的文件或者二進制Data。后臺模式下也支持Upload Task。

  • Download Task:
    下載任務。所有模式的session都支持。

  • 需要注意的是:

創建出的所有task都是在掛起狀態的、需要[dataTask resume];手動開啟。具體的創建方式可以參閱《iOS基礎深入補完計劃--NSURLSession相關API》中關于task創建的API。


Deleagte

代理是很大的一塊、準備在開一篇帖子寫幾個Demo把每個代理都用一遍看看。
簡單來講:

  • NSURLSessionDelegate
    針對整體網絡會話:證書、重定向等
  • NSURLSessionTaskDelegate
    針對網絡任務:開始、結束、單次proposedResponse等
  • NSURLSessionDownloadDelegate
    針對下載任務的特殊代理
  • NSURLSessionStreamDelegate
    為數據流上傳提供數據源的特殊代理

其實這些代理都是NSURLSessionDelegate的子類或者子子類、只是為了分工更加明確罷了。

詳情可以參閱《iOS基礎深入補完計劃--NSURLSession代理使用詳解(附Demo)》


一些其他的點


NSURLCache

  • 在IOS應用程序開發中、為了減少與服務端的交互次數、加快用戶的響應速度、一般都會在IOS設備中加一個緩存的機制。使用緩存的目的是為了使用的應用程序能更快速的響應用戶輸入、是程序高效的運行。有時候我們需要將遠程web服務器獲取的數據緩存起來、減少對同一個url多次請求。使用sdk中的NSURLCache類、可以很方便的實現此功能。

  • NSURLCache可以做到完全的離線緩存、即在沒有網絡的情況下打開離線內容。通過自定義的實現、將緩存文件存放到沙盒路徑下、緩存空間沒有大小限制。可以借鑒H5離線緩存中的Manifest文件,來定義緩存策略。Manifest文件從服務器端下載下來,在本地做版本對比,來實現存儲和更新。

  • NSURLCache攔截不到WKWebView中發出的任何網絡請求。所以如果使用WKWebView的話、NSURLCache實現不了離線緩存的功能。

  • 可以通過NSURLSessionConfiguration的requestCachePolicy屬性進行session層面的整體配置。也可以通過NSURLRequest/NSMutableURLRequest對單一請求進行配置。

更多的使用可以移步:《NSURLCache緩存使用簡介》


NSURLResponse/NSHTTPURLResponse

網絡請求的返回信息。


NSURLCredential

證書對象、有三種驗證方式


NSURLAuthenticationChallenge

在訪問資源的時候、可能服務器會返回需要授權(需要我們提供一個NSURLCredential對象)、會走以下兩個代理:

//服務器驗證客戶端證書時:(`initWithIdentity`)
//客戶端驗證服務器證書時:(`initWithTrust`)
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;

具體的寫法可以看看《關于ios項目繞過證書訪問https》

需要的授權信息會保存在這個類的對象里。
幾個常用的屬性

  • error
    最后一次授權失敗的錯誤信息
  • failureResponse
    最后一次授權失敗的錯誤信息
  • previousFailureCount
    授權失敗的次數
  • proposedCredential
    建議使用的證書
  • protectionSpace
    NSURLProtectionSpace對象,包括了地址端口等信息。

NSURLProtectionSpace

這個類的對象代表了服務器上的一塊需要授權信息的區域、英文叫realm。通過這個對象的信息來響應Challenge。
比如、如果服務器需要一個基于用戶名密碼的認證、那么應該先參考下NSURLProtectionSpace對象的host、port、realm、protocol等信息、然后依照這個信息提供證書。
大概的結構是這樣:(都是可以取出來看的、依舊是只讀)

NSURLProtectionSpace *defaultSpace = [[NSURLProtectionSpace alloc] initWithHost:@"yourbankingdomain.com"  
                                                                           port:443  
                                                                       protocol:NSURLProtectionSpaceHTTPS  
                                                                          realm:@"mobile"  
                                                           authenticationMethod:NSURLAuthenticationMethodDefault]; 

參考資料

官方文檔
IOS網絡開發NSURLSession詳解--主要的學習大綱就是通過這篇文章整理的、推薦閱讀
iOS網絡NSURLSession使用詳解
iOS基礎深入補完計劃--NSURLSessionConfiguration相關API
iOS基礎深入補完計劃--NSURLRequest/NSURLResponse相關API
iOS基礎深入補完計劃--NSURLSession相關API
iOS基礎深入補完計劃--證書與驗證相關API
NSURLCache緩存使用簡介
NSURLSession與NSURLConnection區別

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

推薦閱讀更多精彩內容

  • 在蘋果徹底棄用NSURLConnection之后自己總結的一個網上的內容,加上自己寫的小Demo,很多都是借鑒網絡...
    付寒宇閱讀 4,316評論 2 13
  • iOS開發系列--網絡開發 概覽 大部分應用程序都或多或少會牽扯到網絡開發,例如說新浪微博、微信等,這些應用本身可...
    lichengjin閱讀 3,721評論 2 7
  • 1.移動互聯網時代,工具型產品的整體焦慮 簡評:支付寶為什么一定要做社交?這背后,工具型產品面臨著共同的瓶頸——變...
    何夕一言堂閱讀 386評論 0 1
  • 錯把昨天當今天,告別一圈結果還要再賴一天…… 今天蛋蛋說班里要求學唱《同一首歌》,選20個人最后參加表演。這實在是...
    潘語閱讀 369評論 0 6
  • import UIKit class ViewController: UIViewController { @IB...
    hope7th閱讀 526評論 0 0