NSURLSesion

原生網(wǎng)絡(luò)請求NSURLSession

  1. 同一個 session 發(fā)送多個請求,只需要建立一次連接(復(fù)用了TCP)
  2. 提供了全局的 session 并且可以統(tǒng)一配置献丑,使用更加方便
  3. 下載的時候是多線程異步處理涛贯,效率更高

NSURLSessionTask

  • NSURLSessionTask 是一個抽象類诽嘉,如果要使用那么只能使用它的子類
  • 一般使用它的兩個子類
    1. NSURLSessionDataTask 一般的網(wǎng)絡(luò)請求(如GET、POST)弟翘,上傳請求用它的子類NSURLSessionUploadTask虫腋。
    2. NSURLSessionDownloadTask主要用于處理下載請求,有很大的優(yōu)勢

使用示例

  • GET請求
//確定請求路徑
 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520&type=JSON"];
 //創(chuàng)建 NSURLSession 對象
 NSURLSession *session = [NSURLSession sharedSession];

 /**
  根據(jù)對象創(chuàng)建 Task 請求

  url  方法內(nèi)部會自動將 URL 包裝成一個請求對象(默認是 GET 請求)
  completionHandler  完成之后的回調(diào)(成功或失斝普汀)

  param data     返回的數(shù)據(jù)(響應(yīng)體)
  param response 響應(yīng)頭
  param error    錯誤信息
  */
 NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:
             ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

     //解析服務(wù)器返回的數(shù)據(jù)
     NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
     //默認在子線程中解析數(shù)據(jù)
     NSLog(@"%@", [NSThread currentThread]);
 }];
 //發(fā)送請求(執(zhí)行Task)
 [dataTask resume];
  • POST請求
//確定請求路徑
 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
 //創(chuàng)建可變請求對象
 NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
 //修改請求方法
 requestM.HTTPMethod = @"POST";
 //設(shè)置請求體
 requestM.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
 //創(chuàng)建會話對象
 NSURLSession *session = [NSURLSession sharedSession];
 //創(chuàng)建請求 Task
 NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:requestM completionHandler:
             ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

     //解析返回的數(shù)據(jù)
     NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
 }];
 //發(fā)送請求
 [dataTask resume];

代理方式

//確定請求路徑
 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
 //創(chuàng)建可變請求對象
 NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
 //設(shè)置請求方法
 requestM.HTTPMethod = @"POST";
 //設(shè)置請求體
 requestM.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
 //創(chuàng)建會話對象岔乔,設(shè)置代理
 /**
  第一個參數(shù):配置信息
  第二個參數(shù):設(shè)置代理
  第三個參數(shù):隊列,如果該參數(shù)傳遞nil 那么默認在子線程中執(zhí)行
  */
 NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                              delegate:self delegateQueue:nil];
 //創(chuàng)建請求 Task
 NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:requestM];
 //發(fā)送請求
 [dataTask resume];

常用的3個代理方法

-(void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask 
didReceiveResponse:(nonnull NSURLResponse *)response 
completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
     //子線程中執(zhí)行
     NSLog(@"接收到服務(wù)器響應(yīng)的時候調(diào)用 -- %@", [NSThread currentThread]);

     self.dataM = [NSMutableData data];
     //默認情況下不接收數(shù)據(jù)
     //必須告訴系統(tǒng)是否接收服務(wù)器返回的數(shù)據(jù)
     completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {

     NSLog(@"接受到服務(wù)器返回數(shù)據(jù)的時候調(diào)用,可能被調(diào)用多次");
     //拼接服務(wù)器返回的數(shù)據(jù)
     [self.dataM appendData:data];
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

     NSLog(@"請求完成或者是失敗的時候調(diào)用");
     //解析服務(wù)器返回數(shù)據(jù)
     NSLog(@"%@", [[NSString alloc] initWithData:self.dataM encoding:NSUTF8StringEncoding]);
}

設(shè)置代理之后的強引用問題

NSURLSession 對象在使用的時候滚躯,如果設(shè)置了代理雏门,那么 session 會對代理對象保持一個強引用,在合適的時候應(yīng)該主動進行釋放

可以在控制器調(diào)用 viewDidDisappear 方法的時候來進行處理掸掏,可以通過調(diào)用 invalidateAndCancel 方法或者是 finishTasksAndInvalidate 方法來釋放對代理對象的強引用

  • invalidateAndCancel 方法直接取消請求然后釋放代理對象
  • finishTasksAndInvalidate 方法等請求完成之后釋放代理對象茁影。

[self.session finishTasksAndInvalidate];

  • NSURLSessionDownloadTask下載請求
//確定請求路徑
 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];
 //創(chuàng)建請求對象
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 //創(chuàng)建會話對象
 NSURLSession *session = [NSURLSession sharedSession];
 //創(chuàng)建會話請求
 //優(yōu)點:該方法內(nèi)部已經(jīng)完成了邊接收數(shù)據(jù)邊寫沙盒的操作,解決了內(nèi)存飆升的問題
 NSURLSessionDownloadTask *downTask = [session downloadTaskWithRequest:request 
     completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

     //默認存儲到臨時文件夾 tmp 中丧凤,需要剪切文件到 cache
     NSLog(@"%@", location);//目標(biāo)位置
     NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]  
                         stringByAppendingPathComponent:response.suggestedFilename];

     /**
      fileURLWithPath:有協(xié)議頭
      URLWithString:無協(xié)議頭
      */
     [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];

 }];
 //發(fā)送請求
 [downTask resume];
  • NSURLSessionDataTask下載請求
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:
     @"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 = [UIImage imageWithData:data];
     //回到主線程設(shè)置圖片
     dispatch_async(dispatch_get_main_queue(), ^{
         self.imageView.image = image;
     });

 }] resume];

如要獲取下載進度募闲,可以使用代理的方式進行下載

dataTask 和 downloadTask 下載對比

  • NSURLSessionDataTask下載文件可以實現(xiàn)離線斷點下載,但是代碼相對復(fù)雜
  • NSURLSessionDownloadTask
    下載文件可以實現(xiàn)斷點下載愿待,但不能離線斷點下載
    內(nèi)部已經(jīng)完成了邊接收數(shù)據(jù)邊寫入沙盒的操作
    解決了下載大文件時的內(nèi)存飆升問題

參考:http://www.reibang.com/p/b0ddadd34037

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浩螺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仍侥,更是在濱河造成了極大的恐慌要出,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件农渊,死亡現(xiàn)場離奇詭異患蹂,居然都是意外死亡,警方通過查閱死者的電腦和手機砸紊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門传于,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人醉顽,你說我怎么就攤上這事沼溜。” “怎么了游添?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵盛末,是天一觀的道長弹惦。 經(jīng)常有香客問我,道長悄但,這世上最難降的妖魔是什么棠隐? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮檐嚣,結(jié)果婚禮上助泽,老公的妹妹穿的比我還像新娘。我一直安慰自己嚎京,他們只是感情好嗡贺,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鞍帝,像睡著了一般诫睬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帕涌,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天摄凡,我揣著相機與錄音,去河邊找鬼蚓曼。 笑死亲澡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纫版。 我是一名探鬼主播床绪,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼其弊!你這毒婦竟也來了癞己?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤梭伐,失蹤者是張志新(化名)和其女友劉穎痹雅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體籽御,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年惰匙,在試婚紗的時候發(fā)現(xiàn)自己被綠了技掏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡项鬼,死狀恐怖哑梳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绘盟,我是刑警寧澤鸠真,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布悯仙,位于F島的核電站,受9級特大地震影響吠卷,放射性物質(zhì)發(fā)生泄漏锡垄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一祭隔、第九天 我趴在偏房一處隱蔽的房頂上張望货岭。 院中可真熱鬧,春花似錦疾渴、人聲如沸千贯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搔谴。三九已至,卻和暖如春桩撮,著一層夾襖步出監(jiān)牢的瞬間敦第,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工距境, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留申尼,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓垫桂,卻偏偏與公主長得像师幕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诬滩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

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