前言
現(xiàn)如今的移動應用開發(fā)仍秤,網絡模塊幾乎成了標配蛋褥。如果你是早期 iOS 開發(fā)者的話,那么你對 NSURLConnection
一定不會陌生浴捆。但其操作起來有許多不便蒜田,這也使得大家更愿意使用第三方庫的解決方案,比如大名鼎鼎的 AFNetworking 你一定有所耳聞汤功。正是因為這一點物邑,蘋果隨著 iOS 7 的發(fā)布,也為開發(fā)者帶來了改進后的原生網絡庫支持滔金,那就是 NSURLSession色解。
今天,就讓我來給你道一道從 NSURLConnection
到 NSURLSession
那些你知道和不知道的事餐茵。
NSURLConnection
NSURLConnection
作為 Core Foundation / CFNetwork 框架的 API 之上的一個抽象科阎,在 2003 年,隨著第一版的 Safari 的發(fā)布就發(fā)布了忿族。NSURLConnection
這個名字锣笨,實際上是指代的 Foundation 框架的 URL 加載系統(tǒng)中一系列相關聯(lián)的組件:NSURLRequest
、NSURLResponse
道批、NSURLProtocol
错英、 NSURLCache
、 NSHTTPCookieStorage
隆豹、NSURLCredentialStorage
以及同名類 NSURLConnection
椭岩。
NSURLRequest
被傳遞給 NSURLConnection
。被委托對象(遵守以前的非正式協(xié)議 <NSURLConnectionDelegate>
和 <NSURLConnectionDataDelegate>
)異步地返回一個 NSURLResponse
以及包含服務器返回信息的 NSData
璃赡。
在一個請求被發(fā)送到服務器之前判哥,系統(tǒng)會先查詢共享的緩存信息,然后根據(jù)策略(policy)以及可用性(availability)的不同碉考,一個已經被緩存的響應可能會被立即返回塌计。如果沒有緩存的響應可用,則這個請求將根據(jù)我們指定的策略來緩存它的響應以便將來的請求可以使用侯谁。
在把請求發(fā)送給服務器的過程中锌仅,服務器可能會發(fā)出鑒權查詢(authentication challenge)章钾,這可以由共享的 cookie 或機密存儲(credential storage)來自動響應,或者由被委托對象來響應热芹。發(fā)送中的請求也可以被注冊的 NSURLProtocol
對象所攔截伍玖,以便在必要的時候無縫地改變其加載行為。
使用步驟
概覽
NSURL
創(chuàng)建一個 NSURL
對象剿吻,設置請求路徑:
NSURL *url = [NSURL URLWithString:@"協(xié)議://主機地址/路徑?參數(shù)&參數(shù)"];
解釋如下:
- 協(xié)議:不同的協(xié)議,代表著不同的資源查找方式串纺、資源傳輸方式丽旅,比如常用的 HTTP、FTP 等
- 主機地址:存放資源的主機的 IP 地址(域名)
- 路徑:資源在主機中的具體位置
- 參數(shù):參數(shù)可有可無纺棺,也可以多個榄笙。如果帶參數(shù)的話,用 “?” 號后面接參數(shù)祷蝌,多個參數(shù)的話之間用 “&” 隔開
NSURLRequest
創(chuàng)建一個 NSURLRequest
對象并傳入 NSURL
茅撞,設置請求頭和請求體:
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
參數(shù)解釋如下:
- requestWithURL:資源路徑
- cachePolicy:緩存策略(無論使用哪種緩存策略,都會在本地緩存數(shù)據(jù))巨朦,類型為枚舉類型米丘,取值如下:
- NSURLRequestUseProtocolCachePolicy = 0 // 默認的緩存策略,使用協(xié)議的緩存策略
- NSURLRequestReloadIgnoringLocalCacheData = 1 // 每次都從網絡加載
- NSURLRequestReturnCacheDataElseLoad = 2 // 返回緩存否則加載糊啡,很少使用
- NSURLRequestReturnCacheDataDontLoad = 3 // 只返回緩存拄查,沒有也不加載,很少使用
- timeoutInterval:超時時長棚蓄,默認 60s
另外堕扶,還可以設置其它一些信息,比如請求頭梭依,請求體等等稍算,如下:
// 告訴服務器數(shù)據(jù)為 JSON 類型
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// 設置請求體(JSON類型)
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{@"userid":@"123456"} options:NSJSONWritingPrettyPrinted error:nil];
request.HTTPBody = jsonData;
注意,上面的 request 應為 NSMutableURLRequest
役拴,即可變類型糊探。(使用 POST 請求的話,那么就必須的使用 NSMutableURLRequest
)
NSURLConnection
使用 NSURLConnection
發(fā)送請求扎狱,通過返回 NSURLResponse
實例和 NSError
實例分析結果侧到,接受服務器返回數(shù)據(jù)。
NSURLConnection
默認的請求類型為 GET淤击,下面分異步和同步介紹 GET 的使用(POST 會在 NSURLSession
中介紹)匠抗。
異步請求
異步是指:在發(fā)送請求之后,一邊在子線程中接收返回數(shù)據(jù)污抬,一邊執(zhí)行之后的代碼汞贸,當返回數(shù)據(jù)接收完畢后绳军,采用回調的方式通知主線程做處理。同時矢腻,異步請求有兩種實現(xiàn)方式门驾。
1.使用 block:
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 有的時候,服務器訪問正常多柑,但是會沒有數(shù)據(jù)
// 以下的 if 是比較標準的錯誤處理代碼
if (connectionError != nil || data == nil) {
//給用戶的提示信息
NSLog(@"網絡不給力");
return;
}
}];
參數(shù)說明如下:
- completionHandler:請求響應后(或者請求超時)執(zhí)行的代碼奶是,queue 為代碼添加到的隊列,即 block執(zhí)行的線程
- NSURLResponse 為服務器的響應竣灌,真實類型為 NSHTTPURLResponse聂沙,通常只在「下載」功能時,才會使用初嘹;下面是協(xié)議頭的參數(shù):
- URL:響應的 URL及汉,有的時候,訪問一個 URL 地址屯烦,服務器可能會出現(xiàn)重定向坷随,會定位到新的地址
- MIMEType(Content-Type):服務器告訴客戶端,可以用什么軟件打開二進制數(shù)據(jù)驻龟。網絡之所以豐富多采温眉,是因為有豐富的客戶端軟件。栗子:Windows 上提示安裝 Flash 插件
- expectedContentLength:預期的內容長度迅脐,要下載的文件長度芍殖,下載文件時非常有用
- suggestedFilename:「建議」的文件名,方便用戶直接保存谴蔑,很多時候豌骏,用戶并不關心要保存成什么名字
- textEncodingName:文本的編碼名稱 @”UTF8”,大多數(shù)都是 UTF8
- statusCode:狀態(tài)碼隐锭,在做下載操作的時候窃躲,需要判斷一下
- allHeaderFields:所有的響應頭字典時候,用戶并不關心要保存成什么名字
- NSURLResponse 為服務器的響應竣灌,真實類型為 NSHTTPURLResponse聂沙,通常只在「下載」功能時,才會使用初嘹;下面是協(xié)議頭的參數(shù):
- NSData:服務器返回的數(shù)據(jù)钦睡,例如:JSON蒂窒、XML
- NSError:網絡訪問錯誤碼
2.使用代理(Delegate):
@interface ViewController ()<NSURLConnectionDataDelegate>
@end
NSURL * url = [NSURL URLWithString:@"http://itangqi.me"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
使用代理可以監(jiān)測下載過程:
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// 開始接收數(shù)據(jù)
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// 正在接收數(shù)據(jù)(會調用多次)
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// 接收數(shù)據(jù)失敗
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
// 接收數(shù)據(jù)完成(成功|失敗)
}
同步
同步是指:數(shù)據(jù)的請求在主線程來執(zhí)行,一旦發(fā)送同步請求荞怒,直至服務器返回數(shù)據(jù)完成洒琢,才可以進行下一步操作,而網絡數(shù)據(jù)加載需要一個時間過程褐桌,這樣的話就會堵塞主線程衰抑,當然這種使用場景很少。
// 同步請求荧嵌,代碼會阻塞在這里一直等待服務器返回呛踊,如果 data 為 nil 則請求失敗砾淌,當獲取少量數(shù)據(jù)時可以使用此方法。
// request 參數(shù)同上谭网。
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSURLSession
不管怎樣汪厨,NSURLConnection
作為網絡基礎架構,已經服務了成千上萬的 iOS 和 Mac OS 程序愉择,并且做的還算相當不錯劫乱。但是這些年,一些用例——尤其是在 iPhone 和 iPad 上面——已經對 NSURLConnection
的幾個核心概念提出了挑戰(zhàn)锥涕,讓蘋果有理由對它進行重構要拂。
在 2013 的 WWDC 上,蘋果推出了 NSURLConnection
的繼任者:NSURLSession
站楚。
和 NSURLConnection
一樣,NSURLSession
指的也不僅是同名類 NSURLSession
搏嗡,還包括一系列相互關聯(lián)的類窿春。NSURLSession
包括了與之前相同的組件,NSURLRequest
與 NSURLCache
采盒,但是把 NSURLConnection
替換成了 NSURLSession
旧乞、NSURLSessionConfiguration
以及 NSURLSessionTask
的 3 個子類:NSURLSessionDataTask
,NSURLSessionUploadTask
磅氨,NSURLSessionDownloadTask
尺栖。
與 NSURLConnection
相比,NSURLsession
最直接的改進就是可以配置每個 session 的緩存烦租,協(xié)議延赌,cookie,以及證書策略(credential policy)叉橱,甚至跨程序共享這些信息挫以。這將允許程序和網絡基礎框架之間相互獨立,不會發(fā)生干擾窃祝。每個 NSURLSession
對象都由一個 NSURLSessionConfiguration
對象來進行初始化掐松,后者指定了剛才提到的那些策略以及一些用來增強移動設備上性能的新選項。
NSURLSession
中另一大塊就是 session task粪小。它負責處理數(shù)據(jù)的加載以及文件和數(shù)據(jù)在客戶端與服務端之間的上傳和下載大磺。NSURLSessionTask
與 NSURLConnection
最大的相似之處在于它也負責數(shù)據(jù)的加載,最大的不同之處在于所有的 task 共享其創(chuàng)造者 NSURLSession
這一公共委托者(common delegate)探膊。
我們先來深入探討 task杠愧,過后再來討論 NSURLSessionConfiguration
。
概覽
Sessions
// 使用靜態(tài)的 sharedSession 的方法突想,該類使用共享的 seesion殴蹄,該 seesion 使用全局的 Cache究抓,Cookie 和證書
+ (NSURLSession *)sharedSession;
// 根據(jù) NSURLSessionConfiguration 創(chuàng)建對應配置的 seesion
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
// 也是根據(jù) NSURLSessionConfiguration 創(chuàng)建對應配置的 seesion,并且可以指定 seesion 的委托和委托所處的隊列
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;
NSURLSessionTask
NSURLSession
本身是不會進行請求的袭灯,而是通過創(chuàng)建 task 的形式進行網絡請求刺下,同一個 NSURLSession 可以創(chuàng)建多個 task,并且這些 task 之間的 cache 和 cookie 是共享的稽荧。那么我們就來看看 NSURLSession 都能創(chuàng)建哪些 task 吧橘茉。
Task 可以翻譯為任務,那么在和網絡請求相關的任務中姨丈,我們可以理解為:數(shù)據(jù)請求任務畅卓、下載任務、上傳任務等蟋恬。
其實從類名就能猜出它們各自的用途:
NSURLSessionDataTask
:使用這個 task 來調用 HTTP GET 方式請求翁潘,從服務器獲取數(shù)據(jù)到內存。返回的數(shù)據(jù)格式是 NSData歼争,可根據(jù)需要自行轉換成 XML拜马、JSON 等數(shù)據(jù)格式NSURLSessionUploadTask
:使用這個 task 來上傳磁盤文件到 web 服務器,典型地通過 HTTP POST 或者 PUT 方式NSURLSessionDownloadTask
:使用這個 task 來從遠程服務器下載文件到臨時文件地址NSURLSessionStreamTask
:使用這個 task 來執(zhí)行異步的讀和寫
你也能暫停沐绒,恢復(開始)和取消 tasks俩莽。
NSURLSessionDataTask POST
/**
* 簡單 Post 請求,POST 和 GET 請求在于對 request 的處理不同乔遮,其余和 GET 相同
*/
- (void)postWithSharedSession {
// 獲取默認 Session
NSURLSession *session = [NSURLSession sharedSession];
// 創(chuàng)建 URL
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
// 創(chuàng)建 request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 請求方法
request.HTTPMethod = @"POST";
// 請求體
request.HTTPBody = [@"username=1234&pwd=4321" dataUsingEncoding:NSUTF8StringEncoding];
// 創(chuàng)建任務 task
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 獲取數(shù)據(jù)后解析并輸出
NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
// 啟動任務
[task resume];
}
NSURLSessionDataDelegate 代理方法
NSURLSession
提供了 block 的方式處理返回的數(shù)據(jù)扮超,但是如果我們想要在接收數(shù)據(jù)的過程中處理數(shù)據(jù),我們可以使用 NSURLSessionDataDelegate
的代理方法蹋肮,分為接收響應出刷、接收數(shù)據(jù)和請求完成三個階段。
- (void)sessionDataDelegate {
// 創(chuàng)建帶有代理方法的自定義 session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
// 創(chuàng)建任務
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/login?username=1234&pwd=4321"]]];
// 啟動任務
[task resume];
}
// 1. 接受到服務器的響應
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
NSLog(@"任務完成");
// 必須設置對響應進行允許處理才會執(zhí)行后面兩個操作坯辩。
completionHandler(NSURLSessionResponseAllow);
}
// 2. 接收到服務器的數(shù)據(jù)(可能調用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 處理每次接收的數(shù)據(jù)
NSLog(@"%s",__func__);
}
// 3. 請求成功或者失斚矧健(如果失敗,error有值)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// 請求完成,成功或者失敗的處理
NSLog(@"SessionTask %s",__func__);
}
NSURLSessionConfiguration
NSURLSessionConfiguration
對象用于對 NSURLSession
對象進行初始化濒翻。從指定可用網絡屁柏,到 cookie,安全性有送,緩存策略淌喻,再到使用自定義協(xié)議,啟動事件的設置雀摘,以及用于移動設備優(yōu)化的幾個新屬性裸删,你會發(fā)現(xiàn)使用 NSURLSessionConfiguration
可以找到幾乎任何你想要進行配置的選項。其有三個類工廠方法:
默認模式(+defaultSessionConfiguration):返回一個標準的 configuration阵赠,工作模式類似于 NSURLConnection涯塔,可以使用緩存的 Cache肌稻,Cookie,證書(credential)
及時模式(+ephemeralSessionConfiguration): 臨時 session 配置匕荸,與默認配置相比爹谭,這個配置不會使用緩存的 Cache,Cookie榛搔,證書诺凡,只會存在內存里,所以當程序退出時践惑,所有的數(shù)據(jù)都會消失腹泌,這對于實現(xiàn)像秘密瀏覽這種功能來說是很理想的
后臺模式(+backgroundSessionConfiguration):它會創(chuàng)建一個后臺 session。后臺 session 不同于常規(guī)的尔觉,普通的 session凉袱,它甚至可以在應用程序掛起,退出或者崩潰的情況下運行上傳和下載任務侦铜。初始化時指定的標識符绑蔫,被用于向任何可能在進程外恢復后臺傳輸?shù)氖刈o進程(daemon)提供上下文
除了這三種預設的模式之外 NSURLSessionConfiguration
還可以進行很多的配置。 timeoutIntervalForRequest
和 timeoutIntervalForResource
可以控制網絡操作的超時時間泵额。 allowsCellularAccess
屬性可以控制是否允許使用無線網絡。HTTPAdditionalHeaders
可以指定 HTTP 請求頭携添。
NSURLSessionConfiguration
幾乎可以完成網絡操作的大多數(shù)配置功能嫁盲,并且這些配置都綁定到當前的 Session 中,我們一旦用配置好的 NSURLSessionConfiguration
初始化 NSURLSession
實例后烈掠,就不能修改這個 NSURLSession
相關的配置了羞秤。所以,一切的配置操作都放在初始化 NSURLSession
之前左敌。
iOS 9
在 iOS 7 后瘾蛋,蘋果推薦使用
NSURLSession
,并在 iOS 9 中廢棄了NSURLConnection
iOS 9 所有網絡連接默認為 HTTPS 服務矫限,為此推出 App Transport Security哺哼,詳情可參見:Networking with NSURLSession
NSURLConnection vs. NSURLSession
后臺上傳和下載:只需在創(chuàng)建
NSURLSession
的時候配置一個選項,就能得到后臺網絡的所有好處叼风。這樣可以延長電池壽命取董,并且還支持 UIKit 的多 task,在進程間使用相同的委托模型能夠暫停和恢復網絡操作:使用 NSURLSession API 能夠暫停无宿,停止茵汰,恢復所有的網絡任務,再也完全不需要子類化 NSOperation
可配置的容器:對于
NSURLSession
里面的 requests 來說孽鸡,每個NSURLSession
都是可配置的容器蹂午。舉個例來說栏豺,假如你需要設置 HTTP header 選項,你只用做一次豆胸,session 里面的每個 request 就會有同樣的配置提高認證處理:認證是在一個指定的連接基礎上完成的奥洼。在使用
NSURLConnection
時,如果發(fā)出一個訪問配乱,會返回一個任意的 request溉卓。此時,你就不能確切的知道哪個 request 收到了訪問搬泥。而在 NSURLSession 中桑寨,就能用代理處理認證豐富的代理模式:在處理認證的時候,
NSURLConnection
有一些基于異步的 block 方法忿檩,但是它的代理方法就不能處理認證尉尾,不管請求是成功或是失敗。在NSURLSession
中,可以混合使用代理和 block 方法處理認證上傳和下載通過文件系統(tǒng):它鼓勵將數(shù)據(jù)(文件內容)從元數(shù)據(jù)(URL 和 settings)中分離出來
要點
請求的緩存策略使用
NSURLRequestReloadIgnoringCacheData
截亦,忽略本地緩存服務器響應結束后丹锹,要記錄 Etag,服務器內容和本地緩存對比是否變化的重要依據(jù)
在發(fā)送請求時肢藐,設置 If-None-Match,并且傳入 etag
連接結束后吱韭,要判斷響應頭的狀態(tài)碼吆豹,如果是 304,說明本地緩存內容沒有發(fā)生變化理盆,此時可以使用本地緩存來加載數(shù)據(jù)痘煤,如果緩存文件被意外刪除,程序依然運行但會報錯猿规,加載數(shù)據(jù)也失敗
GET 緩存的數(shù)據(jù)會保存在 Cache 目錄中 /bundleId 下衷快,Cache.db 中
本文轉自:wakice的博客
其它資料
NSURLSession與NSURLConnection區(qū)別
NSURLSession與NSURLConnection區(qū)別
兩者的區(qū)別主要在以下幾個方面:
1. 使用現(xiàn)狀
NSURLSession是NSURLConnection 的替代者,在2013年蘋果全球開發(fā)者大會(WWDC2013)隨ios7一起發(fā)布姨俩,是對NSURLConnection進行了重構優(yōu)化后的新的網絡訪問接口蘸拔。從iOS9.0開始, NSURLConnection中發(fā)送請求的兩個方法已過期(同步請求环葵,異步請求)都伪,初始化網絡連接(initWithRequest: delegate:)的方法也被設置為過期,系統(tǒng)不再推薦使用积担,建議使用NSURLSession發(fā)送網絡請求陨晶。
2. 普通任務和上傳
NSURLSession針對下載/上傳等復雜的網絡操作提供了專門的解決方案,針對普通、上傳和下載分別對應三種不同的網絡請求任務:NSURLSessionDataTask, NSURLSessionUploadTask和NSURLSessionDownloadTask.先誉。創(chuàng)建的task都是掛起狀態(tài)湿刽,需要resume才能執(zhí)行。
當服務器返回的數(shù)據(jù)較小時褐耳,NSURLSession與NSURLConnection執(zhí)行普通任務的操作步驟沒有區(qū)別诈闺。
執(zhí)行上傳任務時,NSURLSession與NSURLConnection一樣同樣需要設置POST請求的請求體進行上傳铃芦。
3. 下載任務方式
NSURLConnection下載文件時雅镊,先將整個文件下載到內存,然后再寫入沙盒刃滓,如果文件比較大仁烹,就會出現(xiàn)內存暴漲的情況。而使用NSURLSessionUploadTask下載文件咧虎,會默認下載到沙盒中的tem文件夾中卓缰,不會出現(xiàn)內存暴漲的情況,但在下載完成后會將tem中的臨時文件刪除砰诵,需要在初始化任務方法時征唬,在completionHandler回調中增加保存文件的代碼。
以下代碼是實例化網絡下載任務時將下載的文件保存到沙盒的caches文件夾中:
[NSURLSessionDownloadTask [NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://127.0.0.1/dawenjian.zip"] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//獲取沙盒的caches路徑
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"kkk.dmg"];
//生成URL路徑
NSURL *DCurl = [NSURL fileURLWithPath:path];
//將文件保存到指定文件目錄下
[[NSFileManager defaultManager]moveItemAtURL:location toURL:DCurl error:nil]; }]resume];
4. 請求方法的控制
NSURLConnection實例化對象茁彭,實例化開始总寒,默認請求就發(fā)送(同步發(fā)送),不需要調用start方法理肺。而cancel 可以停止請求的發(fā)送摄闸,停止后不能繼續(xù)訪問,需要創(chuàng)建新的請求哲嘲。
NSURLSession有三個控制方法,取消(cancel)媳禁,暫停(suspend)眠副,繼續(xù)(resume),暫停后可以通過繼續(xù)恢復當前的請求任務竣稽。
5. 斷點續(xù)傳的方式
NSURLConnection進行斷點下載囱怕,通過設置訪問請求的HTTPHeaderField的Range屬性,開啟運行循環(huán)毫别,NSURLConnection的代理方法作為運行循環(huán)的事件源娃弓,接收到下載數(shù)據(jù)時代理方法就會持續(xù)調用,并使用NSOutputStream管道流進行數(shù)據(jù)保存岛宦。
NSURLSession進行斷點下載台丛,當暫停下載任務后,如果 downloadTask (下載任務)為非空,調用 cancelByProducingResumeData:(void (^)(NSData *resumeData))*completionHandler*
這個方法挽霉,這個方法接收一個參數(shù)防嗡,完成處理代碼塊,這個代碼塊有一個 NSData 參數(shù) resumeData侠坎,如果 resumeData 非空蚁趁,我們就保存這個對象到視圖控制器的 resumeData 屬性中。在點擊再次下載時实胸,通過調用 [ [self.session downloadTaskWithResumeData:self.resumeData]resume]方法進行繼續(xù)下載操作他嫡。
經過以上比較可以發(fā)現(xiàn),使用NSURLSession進行斷點下載更加便捷庐完。
6. 配置信息
NSURLSession的構造方法(sessionWithConfiguration:delegate:delegateQueue)中有一個 NSURLSessionConfiguration類的參數(shù)可以設置配置信息钢属,其決定了cookie,安全和高速緩存策略假褪,最大主機連接數(shù)署咽,資源管理,網絡超時等配置生音。NSURLConnection不能進行這個配置宁否,相比于 NSURLConnection 依賴于一個全局的配置對象,缺乏靈活性而言缀遍,NSURLSession 有很大的改進了慕匠。
NSURLSession可以設置三種配置信息,分別通過調用三個累方法返回配置對象:
+ (NSURLSessionConfiguration *)defaultSessionConfiguration域醇,配置信息使用基于硬盤的持久話Cache台谊,保存用戶的證書到鑰匙串,使用共享cookie存儲;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration 譬挚,配置信息和default大致相同锅铅。除了,不會把cache减宣,證書盐须,或者任何和Session相關的數(shù)據(jù)存儲到硬盤,而是存儲在內存中漆腌,生命周期和Session一致贼邓。比如瀏覽器無痕瀏覽等功能就可以基于這個來做;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier闷尿,配置信息可以創(chuàng)建一個可以在后臺甚至APP已經關閉的時候仍然在傳輸數(shù)據(jù)的session塑径。注意,后臺Session一定要在創(chuàng)建的時候賦予一個唯一的identifier填具,這樣在APP下次運行的時候统舀,能夠根據(jù)identifier來進行相關的區(qū)分。如果用戶關閉了APP,IOS 系統(tǒng)會關閉所有的background Session。而且绑咱,被用戶強制關閉了以后绰筛,IOS系統(tǒng)不會主動喚醒APP,只有用戶下次啟動了APP描融,數(shù)據(jù)傳輸才會繼續(xù)铝噩。