開(kāi)發(fā)只懂 AFN ?搞定 NSURLSession 才是硬道理

目錄

NSURLSession 的優(yōu)勢(shì)

NSURLSessionTask 的子類

NSURLSessionDataTask 發(fā)送 GET 請(qǐng)求

NSURLSessionDataTask 發(fā)送 POST 請(qǐng)求

NSURLSessionDataTask 設(shè)置代理發(fā)送請(qǐng)求

設(shè)置代理之后的強(qiáng)引用問(wèn)題

NSURLSessionDataTask 簡(jiǎn)單下載

NSURLSessionDownloadTask 簡(jiǎn)單下載

dataTask 和 downloadTask 下載對(duì)比

寫(xiě)在最后

【補(bǔ)充】NSURLSession 詳解離線斷點(diǎn)下載的實(shí)現(xiàn)

NSURLSession 的優(yōu)勢(shì)

NSURLSession 支持 http2.0 協(xié)議

在處理下載任務(wù)的時(shí)候可以直接把數(shù)據(jù)下載到磁盤

支持后臺(tái)下載|上傳

同一個(gè) session 發(fā)送多個(gè)請(qǐng)求故响,只需要建立一次連接(復(fù)用了TCP)

提供了全局的 session 并且可以統(tǒng)一配置纷捞,使用更加方便

下載的時(shí)候是多線程異步處理,效率更高

NSURLSessionTask 的子類

NSURLSessionTask 是一個(gè)抽象類被去,如果要使用那么只能使用它的子類

NSURLSessionTask 有兩個(gè)子類

NSURLSessionDataTask,可以用來(lái)處理一般的網(wǎng)絡(luò)請(qǐng)求,如 GET | POST 請(qǐng)求等

NSURLSessionDataTask 有一個(gè)子類為 NSURLSessionUploadTask,用于處理上傳請(qǐng)求的時(shí)候有優(yōu)勢(shì)

NSURLSessionDownloadTask,主要用于處理下載請(qǐng)求奖唯,有很大的優(yōu)勢(shì)

NSURLSession 的子類

NSURLSessionDataTask 發(fā)送 GET 請(qǐng)求

發(fā)送 GET 請(qǐng)求的步驟非常簡(jiǎn)單惨缆,只需要兩步就可以完成:

使用 NSURLSession 對(duì)象創(chuàng)建 Task

執(zhí)行 Task

//確定請(qǐng)求路徑NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520&type=JSON"];//創(chuàng)建 NSURLSession 對(duì)象NSURLSession*session = [NSURLSessionsharedSession];/**

根據(jù)對(duì)象創(chuàng)建 Task 請(qǐng)求

url? 方法內(nèi)部會(huì)自動(dòng)將 URL 包裝成一個(gè)請(qǐng)求對(duì)象(默認(rèn)是 GET 請(qǐng)求)

completionHandler? 完成之后的回調(diào)(成功或失敗)

param data? ? 返回的數(shù)據(jù)(響應(yīng)體)

param response 響應(yīng)頭

param error? ? 錯(cuò)誤信息

*/NSURLSessionDataTask*dataTask = [session dataTaskWithURL:url completionHandler:? ? ? ? ? ? ^(NSData* _Nullable data,NSURLResponse* _Nullable response,NSError* _Nullable error) {//解析服務(wù)器返回的數(shù)據(jù)NSLog(@"%@", [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding]);//默認(rèn)在子線程中解析數(shù)據(jù)NSLog(@"%@", [NSThreadcurrentThread]); }];//發(fā)送請(qǐng)求(執(zhí)行Task)[dataTask resume];

NSURLSessionDataTask 發(fā)送 POST 請(qǐng)求

發(fā)送 POST 請(qǐng)求的步驟與發(fā)送 GET 請(qǐng)求一樣:

使用 NSURLSession 對(duì)象創(chuàng)建 Task

執(zhí)行 Task

//確定請(qǐng)求路徑NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login"];//創(chuàng)建可變請(qǐng)求對(duì)象NSMutableURLRequest*requestM = [NSMutableURLRequestrequestWithURL:url];//修改請(qǐng)求方法requestM.HTTPMethod=@"POST";//設(shè)置請(qǐng)求體requestM.HTTPBody= [@"username=520&pwd=520&type=JSON"dataUsingEncoding:NSUTF8StringEncoding];//創(chuàng)建會(huì)話對(duì)象NSURLSession*session = [NSURLSessionsharedSession];//創(chuàng)建請(qǐng)求 TaskNSURLSessionDataTask*dataTask = [session dataTaskWithRequest:requestM completionHandler:? ? ? ? ? ? ^(NSData* _Nullable data,NSURLResponse* _Nullable response,NSError* _Nullable error) {//解析返回的數(shù)據(jù)NSLog(@"%@", [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding]); }];//發(fā)送請(qǐng)求[dataTask resume];

NSURLSessionDataTask 設(shè)置代理發(fā)送請(qǐng)求

創(chuàng)建 NSURLSession 對(duì)象設(shè)置代理

使用 NSURLSession 對(duì)象創(chuàng)建 Task

執(zhí)行 Task

//確定請(qǐng)求路徑NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login"];//創(chuàng)建可變請(qǐng)求對(duì)象NSMutableURLRequest*requestM = [NSMutableURLRequestrequestWithURL:url];//設(shè)置請(qǐng)求方法requestM.HTTPMethod=@"POST";//設(shè)置請(qǐng)求體requestM.HTTPBody= [@"username=520&pwd=520&type=JSON"dataUsingEncoding:NSUTF8StringEncoding];//創(chuàng)建會(huì)話對(duì)象丰捷,設(shè)置代理/**

第一個(gè)參數(shù):配置信息

第二個(gè)參數(shù):設(shè)置代理

第三個(gè)參數(shù):隊(duì)列坯墨,如果該參數(shù)傳遞nil 那么默認(rèn)在子線程中執(zhí)行

*/NSURLSession*session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? delegate:selfdelegateQueue:nil];//創(chuàng)建請(qǐng)求 TaskNSURLSessionDataTask*dataTask = [session dataTaskWithRequest:requestM];//發(fā)送請(qǐng)求[dataTask resume];

遵守協(xié)議,實(shí)現(xiàn)代理方法(常用的有三種代理方法)

-(void)URLSession:(NSURLSession*)session dataTask:(nonnullNSURLSessionDataTask*)dataTask didReceiveResponse:(nonnullNSURLResponse*)response completionHandler:(nonnullvoid(^)(NSURLSessionResponseDisposition))completionHandler {//子線程中執(zhí)行NSLog(@"接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用 -- %@", [NSThreadcurrentThread]);self.dataM= [NSMutableDatadata];//默認(rèn)情況下不接收數(shù)據(jù)//必須告訴系統(tǒng)是否接收服務(wù)器返回的數(shù)據(jù)completionHandler(NSURLSessionResponseAllow);}-(void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveData:(NSData*)data {NSLog(@"接受到服務(wù)器返回?cái)?shù)據(jù)的時(shí)候調(diào)用,可能被調(diào)用多次");//拼接服務(wù)器返回的數(shù)據(jù)[self.dataMappendData:data];}-(void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error {NSLog(@"請(qǐng)求完成或者是失敗的時(shí)候調(diào)用");//解析服務(wù)器返回?cái)?shù)據(jù)NSLog(@"%@", [[NSStringalloc] initWithData:self.dataMencoding:NSUTF8StringEncoding]);}

設(shè)置代理之后的強(qiáng)引用問(wèn)題

NSURLSession 對(duì)象在使用的時(shí)候病往,如果設(shè)置了代理捣染,那么 session 會(huì)對(duì)代理對(duì)象保持一個(gè)強(qiáng)引用,在合適的時(shí)候應(yīng)該主動(dòng)進(jìn)行釋放

可以在控制器調(diào)用 viewDidDisappear 方法的時(shí)候來(lái)進(jìn)行處理停巷,可以通過(guò)調(diào)用 invalidateAndCancel 方法或者是 finishTasksAndInvalidate 方法來(lái)釋放對(duì)代理對(duì)象的強(qiáng)引用

invalidateAndCancel 方法直接取消請(qǐng)求然后釋放代理對(duì)象

finishTasksAndInvalidate 方法等請(qǐng)求完成之后釋放代理對(duì)象耍攘。

[self.sessionfinishTasksAndInvalidate];

NSURLSessionDataTask 簡(jiǎn)單下載

在前面請(qǐng)求數(shù)據(jù)的時(shí)候就相當(dāng)于一個(gè)簡(jiǎn)單的下載過(guò)程,NSURLSessionDataTask 下載文件具體的步驟與上類似:

使用 NSURLSession 對(duì)象創(chuàng)建一個(gè) Task 請(qǐng)求

執(zhí)行請(qǐng)求

[[[NSURLSessionsharedSession] dataTaskWithURL:[NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"]? ? ? completionHandler:^(NSData* _Nullable data,NSURLResponse* _Nullable response,NSError* _Nullable error) {//解析數(shù)據(jù)UIImage*image = [UIImageimageWithData:data];//回到主線程設(shè)置圖片dispatch_async(dispatch_get_main_queue(), ^{self.imageView.image= image;? ? }); }] resume];

NSURLSessionDownloadTask 簡(jiǎn)單下載

使用 NSURLSession 對(duì)象創(chuàng)建下載請(qǐng)求

在下載請(qǐng)求中移動(dòng)文件到指定位置

執(zhí)行請(qǐng)求

//確定請(qǐng)求路徑NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];//創(chuàng)建請(qǐng)求對(duì)象NSURLRequest*request = [NSURLRequestrequestWithURL:url];//創(chuàng)建會(huì)話對(duì)象NSURLSession*session = [NSURLSessionsharedSession];//創(chuàng)建會(huì)話請(qǐng)求//優(yōu)點(diǎn):該方法內(nèi)部已經(jīng)完成了邊接收數(shù)據(jù)邊寫(xiě)沙盒的操作畔勤,解決了內(nèi)存飆升的問(wèn)題NSURLSessionDownloadTask*downTask = [session downloadTaskWithRequest:request? ? ? completionHandler:^(NSURL* _Nullable location,NSURLResponse* _Nullable response,NSError* _Nullable error) {//默認(rèn)存儲(chǔ)到臨時(shí)文件夾 tmp 中蕾各,需要剪切文件到 cacheNSLog(@"%@", location);//目標(biāo)位置NSString*fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) lastObject]? ? ? ? ? ? ? ? ? ? ? ? ? stringByAppendingPathComponent:response.suggestedFilename];/**

fileURLWithPath:有協(xié)議頭

URLWithString:無(wú)協(xié)議頭

*/[[NSFileManagerdefaultManager] moveItemAtURL:location toURL:[NSURLfileURLWithPath:fullPath] error:nil]; }];//發(fā)送請(qǐng)求[downTask resume];

以上方法無(wú)法監(jiān)聽(tīng)下載進(jìn)度,如要獲取下載進(jìn)度庆揪,可以使用代理的方式進(jìn)行下載式曲。

dataTask 和 downloadTask 下載對(duì)比

NSURLSessionDataTask

下載文件可以實(shí)現(xiàn)離線斷點(diǎn)下載,但是代碼相對(duì)復(fù)雜

NSURLSessionDownloadTask

下載文件可以實(shí)現(xiàn)斷點(diǎn)下載缸榛,但不能離線斷點(diǎn)下載

內(nèi)部已經(jīng)完成了邊接收數(shù)據(jù)邊寫(xiě)入沙盒的操作

解決了下載大文件時(shí)的內(nèi)存飆升問(wèn)題

寫(xiě)在最后

關(guān)于使用 NSURLSession 進(jìn)行上傳文件操作吝羞,我只想說(shuō)真的很麻煩,建議大家時(shí)間充沛且有興趣的可以研究一下内颗,如果不想研究也是可以的钧排,繼續(xù)使用我們偉大的 AFN 框架就好。至于 AFN 框架的使用均澳,這里就不贅述了卖氨,后期如果有時(shí)間會(huì)更新一些常用的 AFN 使用方法会烙,敬請(qǐng)期待。

附:使用 NSURLSession 上傳文件主要步驟及注意點(diǎn)

主要步驟:

確定上傳請(qǐng)求的路徑( NSURL )

創(chuàng)建可變的請(qǐng)求對(duì)象( NSMutableURLRequest )

修改請(qǐng)求方法為 POST

設(shè)置請(qǐng)求頭信息(告知服務(wù)器端這是一個(gè)文件上傳請(qǐng)求)

按照固定的格式拼接要上傳的文件等參數(shù)

根據(jù)請(qǐng)求對(duì)象創(chuàng)建會(huì)話對(duì)象( NSURLSession 對(duì)象)

根據(jù) session 對(duì)象來(lái)創(chuàng)建一個(gè) uploadTask 上傳請(qǐng)求任務(wù)

執(zhí)行該上傳請(qǐng)求任務(wù)(調(diào)用 resume 方法)

得到服務(wù)器返回的數(shù)據(jù)筒捺,解析數(shù)據(jù)(上傳成功 | 上傳失敯啬濉)

注意點(diǎn):

創(chuàng)建可變的請(qǐng)求對(duì)象,因?yàn)樾枰薷恼?qǐng)求方法為 POST系吭,設(shè)置請(qǐng)求頭信息

設(shè)置請(qǐng)求頭這個(gè)步驟可能會(huì)被遺漏

要處理上傳參數(shù)的時(shí)候五嫂,一定要按照固定的格式來(lái)進(jìn)行拼接

需要采用合適的方法來(lái)獲得上傳文件的二進(jìn)制數(shù)據(jù)類型( MIMEType,獲取方式如下)

點(diǎn)擊這里搜索

對(duì)著該文件發(fā)送一個(gè)網(wǎng)絡(luò)請(qǐng)求肯尺,接收到該請(qǐng)求響應(yīng)的時(shí)候沃缘,可以通過(guò)響應(yīng)頭信息中的 MIMEType 屬性得到

使用通用的二進(jìn)制數(shù)據(jù)類型表示任意的二進(jìn)制數(shù)據(jù) application/octet-stream

調(diào)用 C 語(yǔ)言的 API 來(lái)獲取

[self mimeTypeForFileAtPath:@"此處為上傳文件的路徑"]

文/Mortal_Master(簡(jiǎn)書(shū)作者)

原文鏈接:http://www.reibang.com/p/b0ddadd34037

著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)则吟,并標(biāo)注“簡(jiǎn)書(shū)作者”槐臀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市氓仲,隨后出現(xiàn)的幾起案子水慨,更是在濱河造成了極大的恐慌,老刑警劉巖敬扛,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晰洒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡啥箭,警方通過(guò)查閱死者的電腦和手機(jī)谍珊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)急侥,“玉大人砌滞,你說(shuō)我怎么就攤上這事』倒郑” “怎么了布持?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)陕悬。 經(jīng)常有香客問(wèn)我题暖,道長(zhǎng),這世上最難降的妖魔是什么捉超? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任胧卤,我火速辦了婚禮,結(jié)果婚禮上拼岳,老公的妹妹穿的比我還像新娘枝誊。我一直安慰自己,他們只是感情好惜纸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布叶撒。 她就那樣靜靜地躺著绝骚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祠够。 梳的紋絲不亂的頭發(fā)上压汪,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音古瓤,去河邊找鬼止剖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛落君,可吹牛的內(nèi)容都是我干的穿香。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼绎速,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼皮获!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起纹冤,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洒宝,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后赵哲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡君丁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年枫夺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绘闷。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橡庞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出印蔗,到底是詐尸還是另有隱情扒最,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布华嘹,位于F島的核電站吧趣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏耙厚。R本人自食惡果不足惜强挫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望薛躬。 院中可真熱鬧俯渤,春花似錦、人聲如沸型宝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至梨树,卻和暖如春坑夯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背劝萤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工渊涝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人床嫌。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓跨释,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親厌处。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鳖谈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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