NSURLSession

內(nèi)容結(jié)構(gòu)框圖

1.NSURLSession優(yōu)勢(shì)在哪询吴。(為什么要使用NSURLSession來(lái)替代NSURLConnection)

1.1 下載速度

在2015年RFC 7540正式發(fā)表了下一代HTTP協(xié)議衔肢,是1999年以來(lái)HTTP/1.1發(fā)布后的首個(gè)更新叽粹。相對(duì)HTTP1.1,HTTP/2更加快速份企。
  HTTP/2比HTTP/1.1在速度上快很多,iOS9開始,NSURLSession開始全面的支持HTTP/2。

1.2 能夠暫停和恢復(fù)網(wǎng)絡(luò)操作

使用NSURLSession API能夠暫停徐许,停止,恢復(fù)所有的網(wǎng)絡(luò)任務(wù)卒蘸,再也完全不需要子類化NSOperation. 并且默認(rèn)任務(wù)運(yùn)行在其他非主線程中雌隅。

1.3 提高認(rèn)證處理

認(rèn)證是在一個(gè)指定的連接基礎(chǔ)上完成的。在使用NSURLConnection時(shí)缸沃,如果發(fā)出一個(gè)訪問(wèn)恰起,會(huì)返回一個(gè)任意的request。此時(shí)趾牧,你就不能確切的知道哪個(gè)request收到了訪問(wèn)村缸。而在NSURLSession中,就能用代理處理認(rèn)證武氓。

1.4 可配置的容器

對(duì)于NSURLSession里面的requests來(lái)說(shuō)梯皿,每個(gè)NSURLSession都是可配置的容器。舉個(gè)例來(lái)說(shuō)县恕,假如你需要設(shè)置HTTP header選項(xiàng)东羹,你只用做一次,session里面的每個(gè)request就會(huì)有同樣的配置忠烛。

2.NSURLSession介紹属提。

2.1NSURLSession類繼承關(guān)系

2.png

在NSURLSession中,網(wǎng)絡(luò)請(qǐng)求基本由3個(gè)任務(wù)完成:
  1.NSURLSessionData:請(qǐng)求數(shù)據(jù)任務(wù)
  2.NSURLSessionUploadTask:請(qǐng)求上傳任務(wù)
  3.NSURLSessionDownloadTask:請(qǐng)求下載任務(wù)

2.2NSURL代理協(xié)議類繼承關(guān)系

3.png

2.3NSURLSession使用步驟

1.創(chuàng)建一個(gè)URL

NSURL *url = [NSURL URLWithString:@"協(xié)議://主機(jī)地址/路徑?參數(shù)&參數(shù)"];

2.創(chuàng)建NSURLRequest請(qǐng)求

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];

url:資源路徑

cachePolicy:緩存策略美尸。(無(wú)論使用哪種緩存策略冤议,都會(huì)在本地緩存數(shù)據(jù)) NSURLRequestUseProtocolCachePolicy = 0 //默認(rèn)的緩存策略,使用協(xié)議的緩存策略  NSURLRequestReloadIgnoringLocalCacheData = 1 //每次都從網(wǎng)絡(luò)加載 NSURLRequestReturnCacheDataElseLoad = 2 //返回緩存否則加載师坎,很少使用 NSURLRequestReturnCacheDataDontLoad = 3 //只返回緩存恕酸,沒(méi)有也不加載,很少使用

timeoutInterval:超時(shí)時(shí)長(zhǎng)胯陋,默認(rèn)60s.

注意:request還可以設(shè)置一些其他的信息蕊温,比如請(qǐng)求頭,請(qǐng)求體等遏乔。此時(shí)的request要為NSMutableRequest類型义矛。

// 告訴服務(wù)器數(shù)據(jù)為json類型
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
// 設(shè)置請(qǐng)求體(json類型)
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{@"userid":@"123456"} options:NSJSONWritingPrettyPrinted error:nil];
request.HTTPBody = jsonData;

3.創(chuàng)建會(huì)話:NSURLSession
4.通過(guò)會(huì)話創(chuàng)建務(wù):NSURLSessionDataTask,NSURLSessionUploadTask,NSURLSessionDownloadTask
5.調(diào)用resume方法啟動(dòng)任務(wù)。(每一個(gè)任務(wù)都是默認(rèn)掛起的盟萨,需要調(diào)用resume方法)

3.NSURLSession具體使用凉翻。

3.1 NSURLSessionDataTask進(jìn)行GET請(qǐng)求

 //1.創(chuàng)建URL
NSURL *url = [NSURL URLWithString:@"http://test.igenshang.com:8001/openapi/api/event/addEventRecord?"];

//2.NSMutableURLRequest
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.f];
request.HTTPMethod = @"GET";

//3.創(chuàng)建NSURLSession對(duì)象(使用一個(gè)全局會(huì)話對(duì)象)
NSURLSession *session = [NSURLSession sharedSession];

//4.通過(guò)會(huì)話創(chuàng)建任務(wù)
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
    if (!error) {
        
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        
        NSLog(@"%@",dict);
    }
    
}];

//5.啟動(dòng)任務(wù)
[task resume];

4.會(huì)話Session控制。

一般情況下全局的Session我們夠用了捻激,但是如果遇到兩個(gè)連接使用不同配置的情況制轰,就得重新配置session

NSURLSession支持的3種會(huì)話配置

1.defaultSessionConfiguration (default)
進(jìn)程內(nèi)會(huì)話(默認(rèn)會(huì)話),用硬盤來(lái)緩存數(shù)據(jù)

2.ephemeralSessionConfiguration (ephemeral)
臨時(shí)的進(jìn)程內(nèi)會(huì)話铺罢,不會(huì)將cookie,緩存儲(chǔ)存到本地艇挨,只會(huì)放在內(nèi)存中,當(dāng)應(yīng)用程序退出后數(shù)據(jù)也會(huì)消失韭赘。(瀏覽器的無(wú)痕瀏覽模式)

3.backgroundSessionConfiguration (background)
后臺(tái)會(huì)話缩滨,相比默認(rèn)會(huì)話,該會(huì)話會(huì)在后臺(tái)開啟一個(gè)線程進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)處理泉瞻。

配置一個(gè)默認(rèn)session

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = 5.0f;//請(qǐng)求超時(shí)時(shí)間
sessionConfig.allowsCellularAccess = true;//是否允許蜂窩網(wǎng)絡(luò)下載(2G/3G/4G)
//創(chuàng)建會(huì)話脉漏,指定配置和代理
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig 
                                                  delegate:self 
                                             delegateQueue:nil];    

NSURLSession代理協(xié)議

NSURLSessionDelegate:NSObject
會(huì)話父協(xié)議
NSURLSessionTaskDelegate:NSURLSessionDelegate
任務(wù)協(xié)議
NSURLSessionDataDelegate:NSURLSessionTaskDelegate
數(shù)據(jù)協(xié)議
NSURLSessionDownloadDelegate: NSURLSessionTaskDelegate
下載協(xié)議
NSURLSessionStreamDelegate:NSURLSessionTaskDelegate
網(wǎng)絡(luò)流協(xié)議

NSURLSessionDownloadDelegate 協(xié)議(常用)

/**
 *  1.下載中會(huì)多次調(diào)用
 *
 *  @param session                   會(huì)話
 *  @param downloadTask              下載任務(wù)
 *  @param bytesWritten              此次下載完成的字節(jié)數(shù)
 *  @param totalBytesWritten         已經(jīng)下載完成的總字節(jié)數(shù)
 *  @param totalBytesExpectedToWrite 需要下載完成的總字節(jié)數(shù)
 */
- (void)URLSession:(NSURLSession *)session
                downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask
                didWriteData:(int64_t)bytesWritten
                totalBytesWritten:(int64_t)totalBytesWritten
                totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite  
                 
 /**
 *  2.成功下載后調(diào)用
 */
- (void)URLSession:(NSURLSession *)session
                downloadTask:(NSURLSessionDownloadTask *)downloadTask
                didFinishDownloadingToURL:(NSURL *)location                                         

/**
 * 3.任務(wù)完成后調(diào)用,不管下載是否成功
 */
- (void)URLSession:(NSURLSession *)session
          task:(NSURLSessionTask *)task
            didCompleteWithError:(NSError *)error

NSURLSessionTask 任務(wù)操作方法

1.取消任務(wù)            
- (void)cancel;

2.掛起任務(wù)(暫停任務(wù))
- (void)suspend;

3.啟動(dòng)任務(wù)
- (void)resume;

使用DownloadTask 自制Configuration 代碼

-(void)downloadFile{

    1.創(chuàng)建url
    NSString *fileName = _textField.text;
    NSString *urlStr = [NSString stringWithFormat: @"http://192.168.1.208/FileDownload.aspx?file=%@",fileName];
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:urlStr];
    2.創(chuàng)建request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    3.創(chuàng)建session
    3.1創(chuàng)建configuration
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfig.timeoutIntervalForRequest = 5.0f;//請(qǐng)求超時(shí)時(shí)間
    sessionConfig.allowsCellularAccess = true;//是否允許蜂窩網(wǎng)絡(luò)下載(2G/3G/4G)

    3.2創(chuàng)建session
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig 
                                                      delegate:self 
                                                 delegateQueue:nil];
    4.創(chuàng)建任務(wù)
    _downloadTask = [session downloadTaskWithRequest:request];
    5.啟動(dòng)任務(wù)
    [_downloadTask resume];
    
}

pragma mark 點(diǎn)擊取消下載

-(void)cancelDownload{

    [_downloadTask cancel];
}

pragma mark 點(diǎn)擊掛起下載

-(void)suspendDownload{

    [_downloadTask suspend];
}

pragma mark 點(diǎn)擊恢復(fù)下載

-(void)resumeDownload{

    [_downloadTask resume];
}

pragma mark - 下載任務(wù)代理

pragma mark 下載中(會(huì)多次調(diào)用,可以記錄下載進(jìn)度)

-(void)URLSession:(NSURLSession *)session 
            downloadTask:(NSURLSessionDownloadTask *)downloadTask 
            didWriteData:(int64_t)bytesWritten             
       totalBytesWritten:(int64_t)totalBytesWritten
       totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite    
        {    
            [self setUIStatus:totalBytesWritten expectedToWrite:totalBytesExpectedToWrite];//設(shè)置界面狀態(tài)
        }

pragma mark 下載完成

-(void)URLSession:(NSURLSession *)session 
               downloadTask:(NSURLSessionDownloadTask *)downloadTask 
  didFinishDownloadingToURL:(NSURL *)location
{
    NSError *error;
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *savePath = [cachePath stringByAppendingPathComponent:_textField.text];
    NSURL *saveUrl = [NSURL fileURLWithPath:savePath];
    [[NSFileManager defaultManager] copyItemAtURL:location toURL:saveUrl error:&error];
}

pragma mark 任務(wù)完成袖牙,不管是否下載成功

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
                      didCompleteWithError:(NSError *)error
{
    [self setUIStatus:0 expectedToWrite:0];//設(shè)置界面狀態(tài)
}

5.session后臺(tái)開啟任務(wù)

session后臺(tái)開啟任務(wù)的意義:

場(chǎng)景: APP下載一個(gè)比較大的文件侧巨,用戶開始下載后,讓APP進(jìn)入后臺(tái)鞭达,他去做別的事情司忱。
    當(dāng)程序進(jìn)入后臺(tái)后皇忿,下載繼續(xù)進(jìn)行,下載完成后坦仍,用戶正常打開應(yīng)該為100%位置鳍烁。但是程序在后臺(tái)無(wú)法更新UI,此時(shí)可以通過(guò)應(yīng)用程序的代理進(jìn)行UI更新繁扎。

AppDelegate.m添加函數(shù)

/* 
    有其中幾個(gè)任務(wù)完成后幔荒,系統(tǒng)會(huì)調(diào)用此應(yīng)用程序的該方法
    此方法會(huì)包含一個(gè)competionHandler,通常我們會(huì)保存此對(duì)象
    competionHandler此操作表示應(yīng)用完成所有處理工作
**/

- (void)application:(UIApplication *)application 
    handleEventsForBackgroundURLSession:(NSString *)identifier 
                      completionHandler:(void (^)())completionHandler
{
    //backgroundSessionCompletionHandler是自定義的一個(gè)屬性
    self.backgroundSessionCompletionHandler = completionHandler;
}

在實(shí)現(xiàn)NSURLSessionDelegate代理方法

/* 
直到最后一個(gè)任務(wù)完成梳玫,系統(tǒng)會(huì)調(diào)用該方法爹梁。
在這個(gè)方法中通常可以進(jìn)行UI更新提澎,并調(diào)用completionHandler通知系統(tǒng)已經(jīng)完成所有操作姚垃。
*/
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    //這中間就可以寫更新UI的代碼了

    if (appDelegate.backgroundSessionCompletionHandler) {
        void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
        appDelegate.backgroundSessionCompletionHandler = nil;
        completionHandler();  
    }
}

文章中有些內(nèi)容是引用了其他文章的內(nèi)容,時(shí)間久了虱朵,找不到具體的鏈接了莉炉,如有原文作者看到,請(qǐng)聯(lián)系我碴犬,我加上你原文地址絮宁,同時(shí)也感謝你寫的文章給了我很多的幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末服协,一起剝皮案震驚了整個(gè)濱河市绍昂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偿荷,老刑警劉巖窘游,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跳纳,居然都是意外死亡忍饰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門寺庄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)艾蓝,“玉大人,你說(shuō)我怎么就攤上這事斗塘∮” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵馍盟,是天一觀的道長(zhǎng)于置。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贞岭,這世上最難降的妖魔是什么八毯? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任搓侄,我火速辦了婚禮,結(jié)果婚禮上宪彩,老公的妹妹穿的比我還像新娘休讳。我一直安慰自己,他們只是感情好尿孔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筹麸,像睡著了一般活合。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上物赶,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天白指,我揣著相機(jī)與錄音,去河邊找鬼酵紫。 笑死告嘲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奖地。 我是一名探鬼主播橄唬,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼参歹!你這毒婦竟也來(lái)了仰楚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤犬庇,失蹤者是張志新(化名)和其女友劉穎僧界,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臭挽,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捂襟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了欢峰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葬荷。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赤赊,靈堂內(nèi)的尸體忽然破棺而出闯狱,到底是詐尸還是另有隱情,我是刑警寧澤抛计,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布哄孤,位于F島的核電站,受9級(jí)特大地震影響吹截,放射性物質(zhì)發(fā)生泄漏瘦陈。R本人自食惡果不足惜凝危,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晨逝。 院中可真熱鬧蛾默,春花似錦、人聲如沸捉貌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)趁窃。三九已至牧挣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間醒陆,已是汗流浹背瀑构。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刨摩,地道東北人寺晌。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像澡刹,于是被迫代替她去往敵國(guó)和親呻征。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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