NSURLSession 教程

為什么要使用NSURLSession?

翻譯原文 ,所有版權(quán)規(guī)其所有喉祭。

well盖喷,先來看一些優(yōu)點(diǎn):

  • 后臺上傳和下載:只需在創(chuàng)建NSURLSession的時(shí)候配置一個(gè)選項(xiàng)爆办,就能得到后臺網(wǎng)絡(luò)的所有好處。這樣可以延長電池壽命课梳,并且還支持UIKit的多task距辆,在進(jìn)程間使用相同的委托模型余佃。

  • 能夠暫停和恢復(fù)網(wǎng)絡(luò)操作:使用NSURLSession API能夠暫停,停止跨算,恢復(fù)所有的網(wǎng)絡(luò)任務(wù)咙冗,再也完全不需要子類化NSOperation.

  • 可配置的容器:對于NSURLSession里面的requests來說,每個(gè)NSURLSession都是可配置的容器漂彤。舉個(gè)例來說,假如你需要設(shè)置HTTP header選項(xiàng)灾搏,你只用做一次挫望,session里面的每個(gè)request就會有同樣的配置。

  • 提高認(rèn)證處理:認(rèn)證是在一個(gè)指定的連接基礎(chǔ)上完成的狂窑。在使用NSURLConnection時(shí)媳板,如果發(fā)出一個(gè)訪問,會返回一個(gè)任意的request泉哈。此時(shí)蛉幸,你就不能確切的知道哪個(gè)request收到了訪問。而在NSURLSession中丛晦,就能用代理處理認(rèn)證奕纫。

  • 豐富的代理模式:在處理認(rèn)證的時(shí)候,NSURLConnection有一些基于異步的block方法烫沙,但是它的代理方法就不能處理認(rèn)證匹层,不管請求是成功或是失敗。在NSURLSession中锌蓄,可以混合使用代理和block方法處理認(rèn)證升筏。

  • 上傳和下載通過文件系統(tǒng):它鼓勵(lì)將數(shù)據(jù)(文件內(nèi)容)從元數(shù)據(jù)(URL和settings)中分離出來。

NSURLSession vs NSURLConnection

“哇喔瘸爽,看起來NSURLSession好復(fù)雜您访!”,你可能會這樣想剪决×橥簦“還是堅(jiān)持用NSURLConnection吧≈绾矗”

別擔(dān)心 — 使用NSURLSession處理簡單task就如使用NSURLConnection一樣容易识虚。例如,我們使用一個(gè)簡單的網(wǎng)絡(luò)調(diào)用妒茬,來得到倫敦最新天氣的JSON數(shù)據(jù)担锤。

假設(shè)你有這樣一個(gè)URL字符串:

NSString *londonWeatherUrl = @"http://api.openweathermap.org/data/2.5/weather?q=London,uk" ;

首先,使用NSURLConnection會這么做:

NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:londonWeatherUrl]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response,
                   NSData *data,
                   NSError *connectionError) {
  // handle response
  }];  

那來看下NSURLSession是怎么做的乍钻。這個(gè)是NSURLSession使用的最簡單方法肛循。隨后你還會看到怎樣配置session铭腕,設(shè)置其他的特性,比如代理多糠。

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
      completionHandler:^(NSData *data,
                          NSURLResponse *response,
                          NSError *error) {
        // handle response
}] resume];  

注意累舷,你不需要指定運(yùn)行哪個(gè)隊(duì)列,默認(rèn)會開辟一個(gè)后臺線程夹孔。如果有兩個(gè)的話被盈,這種設(shè)計(jì)可能就比較難區(qū)分之間的不同。蘋果官方旨在使用dataTaskWithURL來代替NSURLConnection中的sendAsynchronousRequest搭伤。

看吧只怎,NSURLSession就如NSURLConnection一樣易用,并且還有一些額外的功能怜俐。


NSURLSession vs AFNetworking

說到網(wǎng)絡(luò)請求不得不說的就是AFNetworking Framework身堡。這是iOS/OS X上最流行的框架之一,由Mattt Thompson創(chuàng)建拍鲤。
<pre>
<b>注意</b>:學(xué)習(xí)AFNetworking贴谎,可以在github頁面上找到,<a harf="https://github.com/AFNetworking/AFNetworking">https://github.com/AFNetworking/AFNetworking</a>,你還可以看這篇教程<a harf="http://www.raywenderlich.com/30445/afnetworking-crash-course">http://www.raywenderlich.com/30445/afnetworking-crash-course</a>
</pre>

下面是對于同樣的數(shù)據(jù)請求,AFNetworking 1.x的代碼:

NSURLRequest *request = [NSURLRequest requestWithURL:
                     [NSURL URLWithString:londonWeatherUrl]];

AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request,
          NSHTTPURLResponse *response,
          id JSON) {
// handle response
} failure:nil];
[operation start];  

使用AFNetworking的好處之一是季稳,它的處理響應(yīng)數(shù)據(jù)是數(shù)據(jù)類型類擅这,AFJSONRequestOperation(或類似XML,plist)的返回成功的block里面已經(jīng)解析出了你要的數(shù)據(jù)绞幌。而NSURLSession接收到的是NSData類型蕾哟,你需要把它再轉(zhuǎn)換成JSON類型。

<pre>
<b>注意:</b>用NSJSONSerialization可以輕松的將NSData類型轉(zhuǎn)換為JSON類型莲蜘。
</pre>

那么谭确,你是喜歡用AFNetworking還是NSURLSession呢?
個(gè)人認(rèn)為票渠,簡單的需求最好用NSURlSession-這可減少工程里面第三方庫的依賴逐哈。當(dāng)然了,現(xiàn)在AFNetworking也添加了新的代理问顷,配置昂秃,基于task的API等等特性。

如果你使用了AFNetworking2.0的新特性杜窄,比如系列化肠骆,并且還集成了UIKit(加入了一些UIImageView的類目方法),現(xiàn)在就很難說服你不用它了塞耕。

<pre>
<b>注意:</b>在AFNetworking2.0的分支蚀腿,他們已經(jīng)轉(zhuǎn)成使用NSURLSession。
<a harf="https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-2.0-Migration-Guide">https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-2.0-Migration-Guide</a>
</pre>

譯者注:中間這里有一部分講到了Dropbox,這里就不翻譯了。對于Dropbox莉钙,國內(nèi)墻得厲害廓脆,完全打不開。

NSURLSession 類套(suite of classes)

蘋果公司描述了新類NSURLSession磁玉,及其類套停忿。包括新的上傳,下載蚊伞,處理認(rèn)證等工具席赂,能處理http協(xié)議中的所用事情。

在編碼前时迫,重要的先理解它們是怎樣協(xié)同工作的氧枣。

NSurLSessionNSuRLSessionConfiguration和可選代理(optional delegate)構(gòu)成。再根據(jù)你的網(wǎng)絡(luò)需求通過NSURLSessionTask來創(chuàng)建session别垮。


NSURLSessionConfiguration

有三個(gè)方法用來創(chuàng)建NSURLSessionConfiguration:

  • defaultSessionConfiguration- 使用全局的cache,cookie和credential storage objects來創(chuàng)建configuration對象。

  • ephemeralSessionConfiguration – 這個(gè)configuration用于“private” sessions扎谎,還有對于cache, cookie, or credential storage objects的非永久存儲碳想。

  • backgroundSessionConfiguration – 做遠(yuǎn)程push通知或是應(yīng)用程序掛起的時(shí)候就要用到這個(gè)configuration。

一旦創(chuàng)建了NSURLSessionConfiguration就可以給它設(shè)置各種屬性:

NSURLSessionConfiguration *sessionConfig =
[NSURLSessionConfiguration defaultSessionConfiguration];

// 1
sessionConfig.allowsCellularAccess = NO;

// 2
[sessionConfig setHTTPAdditionalHeaders:
      @{@"Accept": @"application/json"}];

// 3
sessionConfig.timeoutIntervalForRequest = 30.0;
sessionConfig.timeoutIntervalForResource = 60.0;
sessionConfig.HTTPMaximumConnectionsPerHost = 1;
  1. 限制了網(wǎng)絡(luò)只能是wifi毁靶。
  2. 設(shè)置了所有的請求只接收J(rèn)SON數(shù)據(jù)
  3. 配置網(wǎng)絡(luò)超時(shí)胧奔,限制一個(gè)主機(jī)只有一個(gè)網(wǎng)絡(luò)連接。

這里僅僅只做了一些簡單的配置预吆,看文檔去了解更多的屬性吧龙填。


NSURLSession

NSURLSession是為了代替NSURLConnection而設(shè)計(jì)的。Sessions的所有工作都是通過它的小弟拐叉,也就是NSURLSessionTask的對象岩遗。可以用block,delegate,或者兩者混合來創(chuàng)建task凤瘦。舉個(gè)例子宿礁,你要下載圖片,就要?jiǎng)?chuàng)建NSURLSessionDownloadTask蔬芥。

首先需要?jiǎng)?chuàng)建session:

// 1
NSString *imageUrl =
@"http://www.raywenderlich.com/images/store/    iOS7_PDFonly_280@2x_authorTBA.png";

// 2
NSURLSessionConfiguration *sessionConfig =[NSURLSessionConfiguration defaultSessionConfiguration];

// 3
NSURLSession *session =[NSURLSession sessionWithConfiguration:sessionConfig
                            delegate:self
                       delegateQueue:nil];

ok,這個(gè)看上去和前面的只有點(diǎn)不同梆靖,一步一步看:

  1. 這里下載一張圖片(譯者改:原文匪夷所思)。
  2. 創(chuàng)建NSURLConfiguration笔诵。
  3. 用當(dāng)前類對象作為代理創(chuàng)建session返吻。

之后,通過創(chuàng)建帶有完成處理的task來下載圖片:

// 1
NSURLSessionDownloadTask *getImageTask =
[session downloadTaskWithURL:[NSURL URLWithString:imageUrl]

completionHandler:^(NSURL *location,
                    NSURLResponse *response,
                    NSError *error) {
// 2
UIImage *downloadedImage =
      [UIImage imageWithData:
          [NSData dataWithContentsOfURL:location]];
//3
dispatch_async(dispatch_get_main_queue(), ^{
    // do stuff with image
    _imageWithBlock.image = downloadedImage;
  });
  }];

// 4
[getImageTask resume];  

很好乎婿,現(xiàn)在看起來像網(wǎng)絡(luò)請求代碼了测僵!

  1. task由session創(chuàng)建。上面是創(chuàng)建了一個(gè)基于block的方法次酌。你還可以用NSURLSessionDownloadDelegate跟蹤下載進(jìn)度:

     -URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:  
    
  2. 通過location變量來得到image指針恨课。

  3. 然后是更新UIImageView的圖片舆乔。

  4. 開始這個(gè)task。

  5. session能夠輕松的創(chuàng)建task剂公,并發(fā)送到代理方法希俩,通知你完成。

這是像上面使用相同的session:

// 1
NSURLSessionDownloadTask *getImageTask = [session downloadTaskWithURL:[NSURL URLWithString:imageUrl]];

[getImageTask resume];  
  1. 如果你接下來什么都不做的話纲辽,我們就使用這些代碼颜武。那么,就需要實(shí)現(xiàn)這個(gè)協(xié)議中的代理方法NSURLSessionDownloadDelegate拖吼。首先是鳞上,收到下載完成的通知:

     -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { 
     // use code above from completion handler 
     }  
    

這里再一次給你提供了location,然后用它就能獲取image吊档。

最后篙议,如果需要跟蹤下載進(jìn)度:

-(void)URLSession:(NSURLSession *)session
     downloadTask:(NSURLSessionDownloadTask *)downloadTask
     didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
  NSLog(@"%f / %f", (double)totalBytesWritten,
(double)totalBytesExpectedToWrite);
}  


NSURLSessionTask

上面看了NSURLSessionDataTaskNSURLSessionDownloadTask的使用。這兩個(gè)都是繼承至NSURLSessionTask

NSURLSessionTask是session中task的基類怠硼,它們只能由session或session的子類創(chuàng)建鬼贱。

NSURLSessionDataTask

這個(gè)task調(diào)用HTTP GET請求從服務(wù)器獲取數(shù)據(jù)。返回的數(shù)據(jù)格式是NSData香璃≌饽眩可能需要你自己轉(zhuǎn)換成XML,JSON,UIimage等..

NSURLSessionDataTask *jsonData = [session dataTaskWithURL:yourNSURL
  completionHandler:^(NSData *data,
                      NSURLResponse *response,
                      NSError *error) {
    // handle NSData
}];  

NSURLSessionUploadTask

這個(gè)類是上傳用的,在數(shù)據(jù)傳輸過程中葡秒,這個(gè)代理方法能觀察網(wǎng)絡(luò)狀況姻乓。
上傳一張圖片:

NSData *imageData = UIImageJPEGRepresentation(image, 0.6);

NSURLSessionUploadTask *uploadTask = [upLoadSession uploadTaskWithRequest:request fromData:imageData];

這個(gè)task由session創(chuàng)建,上傳圖片的NSData眯牧。其他上傳方法還有上傳文件蹋岩,或是數(shù)據(jù)流。

NSURLSessionDownloadTask

NSURLSessionDownloadTask下載文件更簡單学少,可以在下載中掛起星澳,恢復(fù)。它有一點(diǎn)點(diǎn)不同于其他兩個(gè)子類旱易。

  1. task的類型直接寫到一個(gè)臨時(shí)文件中禁偎。
  2. 下載過程中會調(diào)用URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: 去更新狀態(tài)。
  3. 當(dāng)task完成阀坏,URLSession:downloadTask:didFinishDownloadingToURL:會被調(diào)用如暖。此時(shí)你可以將臨時(shí)文件保存到永久文件中。
  4. 下載失敗或是取消還可以得到已經(jīng)下載的那一部分?jǐn)?shù)據(jù)忌堂。

使用這個(gè)掛起task:

//[uploadTask resume];  
[uploadTask suspend];  

同時(shí)管理多個(gè)task時(shí)盒至,可以用taskIdentifier屬性來唯一標(biāo)識task。

well,現(xiàn)在了解了NSURLSession類套中主要的類。

后面還有一部分枷遂,還是與Dropbox有關(guān)的樱衷,就不再翻譯了。

轉(zhuǎn)載請注明出處酒唉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矩桂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子痪伦,更是在濱河造成了極大的恐慌侄榴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件网沾,死亡現(xiàn)場離奇詭異癞蚕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辉哥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門桦山,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人醋旦,你說我怎么就攤上這事度苔。” “怎么了浑度?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸦概。 經(jīng)常有香客問我箩张,道長,這世上最難降的妖魔是什么窗市? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任先慷,我火速辦了婚禮,結(jié)果婚禮上咨察,老公的妹妹穿的比我還像新娘论熙。我一直安慰自己,他們只是感情好摄狱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布脓诡。 她就那樣靜靜地躺著,像睡著了一般媒役。 火紅的嫁衣襯著肌膚如雪祝谚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天酣衷,我揣著相機(jī)與錄音交惯,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛席爽,可吹牛的內(nèi)容都是我干的意荤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼只锻,長吁一口氣:“原來是場噩夢啊……” “哼玖像!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炬藤,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤御铃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沈矿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體上真,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年羹膳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了睡互。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陵像,死狀恐怖就珠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情醒颖,我是刑警寧澤妻怎,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站泞歉,受9級特大地震影響逼侦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腰耙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一榛丢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挺庞,春花似錦晰赞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至援制,卻和暖如春锨用,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隘谣。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工增拥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啄巧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓掌栅,卻偏偏與公主長得像秩仆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子猾封,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在蘋果徹底棄用NSURLConnection之后自己總結(jié)的一個(gè)網(wǎng)上的內(nèi)容澄耍,加上自己寫的小Demo,很多都是借鑒網(wǎng)絡(luò)...
    付寒宇閱讀 4,268評論 2 13
  • NSURLSession概述1. NSURLSession session類型NSURLSession包括下面3種...
    瞎嘚嘚閱讀 1,873評論 2 2
  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會牽扯到網(wǎng)絡(luò)開發(fā)晌缘,例如說新浪微博齐莲、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,644評論 2 7
  • NSURLSession 使用步驟使用NSURLSession對象創(chuàng)建Task磷箕,然后執(zhí)行Task -(void)g...
    BEYOND黃閱讀 900評論 0 0
  • 8月21日是開學(xué)的第一天选酗。我認(rèn)識了許多的朋友,共有六個(gè)岳枷。然后組長帶著我們上樓吃了飯芒填,我是第一次上樓吃飯呢!吃完飯空繁,...
    劉璐琳閱讀 224評論 1 1