目錄
- 前言
- 概述
- NSURLRequest
- NSURLSessionConfiguration
- NSURLSession
- NSURLSessionTask
- Deleagte
- 一些其他的點
- NSURLCache
- NSURLResponse/NSHTTPURLResponse
- NSURLCredential
- NSURLAuthenticationChallenge
- NSURLProtectionSpace
前言:
其實是第一次仔細(xì)的接觸iOS的網(wǎng)絡(luò)模塊匣屡、當(dāng)時培訓(xùn)的時候?qū)W過不過早就已經(jīng)忘光了(現(xiàn)在只記得AFNetworking溪王、比前端程序員依賴jQuery更甚)水孩。
準(zhǔn)備先了解個大概铃在、然后再逐一深入策彤。
所以本篇并沒寫Demo奥吩、也沒有涉及太具體的請求代碼册养。
旨在通過一篇文章能對NSURLSession了解個大概(最起碼面試簡單扯皮夠用
)
也整理了大部分相關(guān)的API傲绣、有興趣可以自己翻閱(在本文最后
)
然后本文主要的學(xué)習(xí)大綱是通過《IOS網(wǎng)絡(luò)開發(fā)NSURLSession詳解》整理的、推薦閱讀
概述
對于iOS而言巩踏、網(wǎng)絡(luò)變成主要依賴兩種方式:NSURLSession以及NSURLConnection秃诵。對于NSURLConnection、我入行甚至培訓(xùn)iOS的時候塞琼、就淘汰并且被NSURLSession取代了菠净。也不太有精力學(xué)一個已經(jīng)廢棄的東西就為了寫點東西、所以沒啥可說的(如果有精力可以去找一篇總結(jié)二者區(qū)別比較全面的貼出來
)彪杉。
咳毅往、簡單總結(jié)一下:
1、下載任務(wù)時:
NSURLConnection會先放在內(nèi)存派近、最后寫入沙盒煞抬。可能引起內(nèi)存暴漲构哺。
NSURLSession會直接寫在沙盒和tem文件夾中、最后需要手動轉(zhuǎn)移战坤。
2曙强、請求控制:
NSURLConnection創(chuàng)建好了對象、便開始網(wǎng)絡(luò)請求途茫。
只能cancel并不能恢復(fù)碟嘴。
NSURLSession則在掛起狀態(tài)需要手動resume。
可以取消(cancel)囊卜、暫停(suspend)娜扇、繼續(xù)(resume)。
3栅组、斷點續(xù)傳:
NSURLConnection通過設(shè)置訪問請求的HTTPHeaderField的Range屬性雀瓢、繼續(xù)下載剩余的部分。
NSURLSession通過將任務(wù)暫停時候代理返回的resumeData傳入downloadTaskWithResumeData:方法進行續(xù)傳玉掸。
4刃麸、配置信息:
NSURLConnection只能全局配置。
NSURLSession每一個實例都可以通過NSURLSessionConfiguration進行配置司浪。
詳閱:《NSURLSession與NSURLConnection區(qū)別》
了解NSURLSession的話泊业。該從哪里切入呢?寫一個網(wǎng)絡(luò)請求就知道了
- (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];
}
很直觀的篮奄、至少有四個部分:NSURLRequest
、NSURLSessionConfiguration
、NSURLSession
以及NSURLSessionTask
宦搬。
但實際上有一個很重要的部分----代理牙瓢、他可以比block細(xì)致的多的管理我們的網(wǎng)絡(luò)請求。
所以主要是五個部分间校。
NSURLRequest
-
NSURLRequest
兩種創(chuàng)建方式
1矾克、直接通過NSURL
創(chuàng)建:
默認(rèn)超時60s
、緩存策略NSURLRequestUseProtocolCachePolicy
+ (instancetype)requestWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL;
2憔足、通過NSURL
胁附、超時時間
、緩存策略
共同創(chuàng)建:
+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
不論哪種方式滓彰、默認(rèn)都是通過Get方式傳輸控妻。
你可以通過NSURLRequest
的屬性獲取很多相關(guān)的信息:
包括超時時間、請求的URL揭绑、緩存目錄弓候、是否支持蜂窩網(wǎng)絡(luò)等等。
需要注意的是這些都是readonly
他匪、不能被修改菇存。
但是對于比如請求方式、請求頭邦蜜、請求體依鸥、cookie等HTTP方面的屬性。是可以修改的(iOS為NSURLRequest寫了個NSHTTPURLRequest擴展悼沈、這種思路其實可以借鑒一下
)
-
NSMutableURLRequest
顧名思義贱迟、他可以修改絕大部分(或者應(yīng)該說是所有?我并沒有逐個去查找對比絮供、但是絕大部分平時用得到的東西都是能修改的
)屬性衣吠。
NSURLRequest (NSHTTPURLRequest)
針對HTTP請求進行了特化。比如請求頭請求體壤靶、請求方式等等蒸播。更詳細(xì)的API可以參閱《iOS基礎(chǔ)深入補完計劃--NSURLRequest/NSURLResponse相關(guān)API》
NSURLSessionConfiguration
對NSURLSession
提供一個配置策略、NSURLSession
在初始化時會copyNSURLSessionConfiguration
萍肆。所以如果需要不同的策略袍榆、需要不同的Configuration來生成新的session。
通常的使用就是以下三種:
-
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
默認(rèn)配置:會將緩存塘揣、鑰匙串包雀、cookie都保存下來。 -
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
可以看錯無痕瀏覽:所有東西隨著session的廢棄而廢棄亲铡。
(說句題外話才写、defaultSessionConfiguration
葡兑、ephemeralSessionConfiguration
看其他帖子好像以前是類方法、原來還有class
這種寫法赞草、為啥非要這么寫呢讹堤、沒發(fā)現(xiàn)什么必要性)
-
+(NSURLSessionConfiguration*)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
正常來講APP在退出到后臺的時候、網(wǎng)絡(luò)傳輸將會停止厨疙。
但通過background配置的session洲守、當(dāng)APP被切入后臺的時候依舊可以進行網(wǎng)絡(luò)會話。
甚至進程被關(guān)閉后重新開啟沾凄、只要有同一個identifier
梗醇、也能繼續(xù)會話(這不就是斷點續(xù)傳么?
)。
除此之外撒蟀、NSURLSessionConfiguration還可以配置很多東西叙谨。
比如:請求頭信息、傳輸?shù)念愋捅M汀⑹欠裨试S蜂窩傳輸手负、超時時間、cookie的控制姑尺、證書的存儲竟终、緩存(NSURLCache
)、緩存策略(NSURLRequestCachePolicy
)股缸、最大連接數(shù)等等。
- 更詳細(xì)的API可以參閱 《iOS基礎(chǔ)深入補完計劃--NSURLSessionConfiguration相關(guān)API》)
需要注意的是
NSURLSessionConfiguration
所能配置的策略吱雏、有一些和NSURLRequest
能配置的會沖突敦姻。
這時候、會優(yōu)先使用NSURLRequest
中的配置(比如超時歧杏、請求頭等等)镰惦。
NSURLSession
NSURLSession是iOS網(wǎng)絡(luò)會話的最核心模塊。
由NSURLSessionConfiguration來配置犬绒、針對NSURLRequest創(chuàng)建出NSURLSessionTask進行網(wǎng)絡(luò)會話旺入。
其本身不進行網(wǎng)絡(luò)會話的工作。但是通過代理或者block的方式凯力、可以捕獲網(wǎng)絡(luò)會話的不同狀態(tài)并加以處理茵瘾。
- 產(chǎn)出task、并通過block捕獲最終狀態(tài)
//生成session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//產(chǎn)出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//taks完成
}];
//開始task
[dataTask resume];
- 直接產(chǎn)出task咐鹤、并且通過代理控制
//生成session并綁定代理
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
//產(chǎn)出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL]];
//開始task
[dataTask resume];
/*
各種各樣的代理拗秘、包括session(`證書、重定向`)方面
以及task(`鏈接成功祈惶、每次buffer的返回雕旨、傳輸完畢等等`)方面
*/
可以看出
通過block方式的粒度較大扮匠、只關(guān)注結(jié)果、使用方便凡涩。
通過代理方式的粒度很小棒搜、可以做很多復(fù)雜的操作。更詳細(xì)的API可以參閱 《iOS基礎(chǔ)深入補完計劃--NSURLSession相關(guān)API》
NSURLSessionTask
偷一張圖
簡單明了活箕、NSURLSessionTask本身是個抽象類力麸、不進行任何工作。
DataTask:
用來請求資源讹蘑、后臺模式下不支持末盔。Upload Task:
基于DataTask、但是提供了request body可以傳遞具體的文件或者二進制Data座慰。后臺模式下也支持Upload Task陨舱。Download Task:
下載任務(wù)。所有模式的session都支持版仔。-
需要注意的是:
創(chuàng)建出的所有task都是在掛起狀態(tài)的游盲、需要[dataTask resume];
手動開啟。具體的創(chuàng)建方式可以參閱《iOS基礎(chǔ)深入補完計劃--NSURLSession相關(guān)API》中關(guān)于task創(chuàng)建的API蛮粮。
Deleagte
代理是很大的一塊益缎、準(zhǔn)備在開一篇帖子寫幾個Demo把每個代理都用一遍看看。
簡單來講:
- NSURLSessionDelegate
針對整體網(wǎng)絡(luò)會話:證書然想、重定向等 - NSURLSessionTaskDelegate
針對網(wǎng)絡(luò)任務(wù):開始莺奔、結(jié)束、單次proposedResponse等 - NSURLSessionDownloadDelegate
針對下載任務(wù)的特殊代理 - NSURLSessionStreamDelegate
為數(shù)據(jù)流上傳提供數(shù)據(jù)源的特殊代理
其實這些代理都是NSURLSessionDelegate的子類或者子子類变泄、只是為了分工更加明確罷了令哟。
詳情可以參閱《iOS基礎(chǔ)深入補完計劃--NSURLSession代理使用詳解(附Demo)》
一些其他的點
NSURLCache
在IOS應(yīng)用程序開發(fā)中、為了減少與服務(wù)端的交互次數(shù)妨蛹、加快用戶的響應(yīng)速度屏富、一般都會在IOS設(shè)備中加一個緩存的機制。使用緩存的目的是為了使用的應(yīng)用程序能更快速的響應(yīng)用戶輸入蛙卤、是程序高效的運行狠半。有時候我們需要將遠(yuǎn)程web服務(wù)器獲取的數(shù)據(jù)緩存起來、減少對同一個url多次請求颤难。使用sdk中的NSURLCache類神年、可以很方便的實現(xiàn)此功能。
NSURLCache可以做到完全的離線緩存行嗤、即在沒有網(wǎng)絡(luò)的情況下打開離線內(nèi)容瘤袖。通過自定義的實現(xiàn)、將緩存文件存放到沙盒路徑下昂验、緩存空間沒有大小限制捂敌“纾可以借鑒H5離線緩存中的Manifest文件,來定義緩存策略占婉。Manifest文件從服務(wù)器端下載下來泡嘴,在本地做版本對比,來實現(xiàn)存儲和更新逆济。
NSURLCache攔截不到WKWebView中發(fā)出的任何網(wǎng)絡(luò)請求酌予。所以如果使用WKWebView的話、NSURLCache實現(xiàn)不了離線緩存的功能奖慌。
可以通過NSURLSessionConfiguration的requestCachePolicy屬性進行session層面的整體配置抛虫。也可以通過NSURLRequest/NSMutableURLRequest對單一請求進行配置。
更多的使用可以移步:《NSURLCache緩存使用簡介》
NSURLResponse/NSHTTPURLResponse
網(wǎng)絡(luò)請求的返回信息简僧。
NSURLResponse
可以以只讀的方式獲攘掣省:鏈接咧欣、響應(yīng)類型、響應(yīng)長度、編碼等等碗脊。NSHTTPURLResponse
NSURLResponse
的子類没佑、和Request一樣也是主要是針對HTTP協(xié)議進行了特化:狀態(tài)碼百姓、響應(yīng)頭楣颠、HTTP版本等。更詳細(xì)的API可以參閱《iOS基礎(chǔ)深入補完計劃--NSURLRequest/NSURLResponse相關(guān)API》
NSURLCredential
證書對象夏志、有三種驗證方式
通過用戶名乃坤、密碼
通過客戶端本地證書
通過對服務(wù)器證書認(rèn)證并且由客戶端信任
更詳細(xì)的API可以參閱《基礎(chǔ)深入補完計劃--證書與驗證相關(guān)API》
NSURLAuthenticationChallenge
在訪問資源的時候、可能服務(wù)器會返回需要授權(quán)(需要我們提供一個NSURLCredential
對象)沟蔑、會走以下兩個代理:
//服務(wù)器驗證客戶端證書時:(`initWithIdentity`)
//客戶端驗證服務(wù)器證書時:(`initWithTrust`)
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;
具體的寫法可以看看《關(guān)于ios項目繞過證書訪問https》
需要的授權(quán)信息會保存在這個類的對象里湿诊。
幾個常用的屬性
- error
最后一次授權(quán)失敗的錯誤信息 - failureResponse
最后一次授權(quán)失敗的錯誤信息 - previousFailureCount
授權(quán)失敗的次數(shù) - proposedCredential
建議使用的證書 - protectionSpace
NSURLProtectionSpace對象,包括了地址端口等信息溉贿。
NSURLProtectionSpace
這個類的對象代表了服務(wù)器上的一塊需要授權(quán)信息的區(qū)域枫吧、英文叫realm浦旱。通過這個對象的信息來響應(yīng)Challenge宇色。
比如、如果服務(wù)器需要一個基于用戶名密碼的認(rèn)證颁湖、那么應(yīng)該先參考下NSURLProtectionSpace對象的host宣蠕、port、realm甥捺、protocol等信息抢蚀、然后依照這個信息提供證書。
大概的結(jié)構(gòu)是這樣:(都是可以取出來看的镰禾、依舊是只讀
)
NSURLProtectionSpace *defaultSpace = [[NSURLProtectionSpace alloc] initWithHost:@"yourbankingdomain.com"
port:443
protocol:NSURLProtectionSpaceHTTPS
realm:@"mobile"
authenticationMethod:NSURLAuthenticationMethodDefault];
參考資料
官方文檔
IOS網(wǎng)絡(luò)開發(fā)NSURLSession詳解--主要的學(xué)習(xí)大綱就是通過這篇文章整理的皿曲、推薦閱讀
iOS網(wǎng)絡(luò)NSURLSession使用詳解
iOS基礎(chǔ)深入補完計劃--NSURLSessionConfiguration相關(guān)API
iOS基礎(chǔ)深入補完計劃--NSURLRequest/NSURLResponse相關(guān)API
iOS基礎(chǔ)深入補完計劃--NSURLSession相關(guān)API
iOS基礎(chǔ)深入補完計劃--證書與驗證相關(guān)API
NSURLCache緩存使用簡介
NSURLSession與NSURLConnection區(qū)別