詳細解析幾個和網(wǎng)絡請求有關(guān)的類(十二) —— URL Session的生命周期(八)

版本記錄

版本號 時間
V1.0 2018.03.13

前言

我們做APP發(fā)起網(wǎng)絡請求,一般都是使用框架,這些框架的底層也都是蘋果的API,接下來幾篇就一起來看一下和網(wǎng)絡有關(guān)的幾個類样刷。感興趣的可以看上面幾篇文章。
1. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類 (一) —— NSURLSession
2. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(二) —— NSURLRequest和NSMutableURLRequest
3. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(三) —— NSURLConnection
4. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(四) —— NSURLSession和NSURLConnection的區(qū)別
5. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(五) —— 關(guān)于NSURL加載系統(tǒng)(一)
6. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(六) —— 使用NSURLSession(二)
7. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(七) —— URL數(shù)據(jù)的編碼和解碼(三)
8. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(八) —— 處理重定向和其他請求更改(四)
9. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(九) —— 身份驗證挑戰(zhàn)和TLS鏈驗證(五)
10. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(十) —— 理解獲取緩存(六)
11. 詳細解析幾個和網(wǎng)絡請求有關(guān)的類(十一) —— Cookies和自定義協(xié)議(七)

回顧

上一篇主要講述關(guān)于Cookies和自定義協(xié)議览爵,這一篇我們主要看一下URL Session的生命周期置鼻。


Life Cycle of a URL Session - URL Session的生命周期

您可以通過兩種方式使用NSURLSession API:使用系統(tǒng)提供的代理或使用您自己的代理。一般來說蜓竹,如果您的應用程序執(zhí)行以下任何操作箕母,您必須使用您自己的代理:

  • 當您的應用程序未運行時,使用后臺會話下載或上傳內(nèi)容俱济。
  • 執(zhí)行自定義驗證嘶是。
  • 執(zhí)行自定義SSL證書驗證。
  • 決定傳輸是下載到磁盤還是根據(jù)服務器返回的MIME類型或其他類似標準顯示蛛碌。
  • 上傳來自正文流的數(shù)據(jù)(與NSData對象相反)聂喇。
  • 以編程方式限制緩存。
  • 以編程方式限制HTTP重定向蔚携。

如果您的應用不需要執(zhí)行任何這些操作希太,則您的應用可以使用系統(tǒng)提供的代理。根據(jù)您選擇的技術(shù)酝蜒,您應該閱讀以下部分之一:

  • 使用Life Cycle of a URL Session with System-Provided Delegates提供了一個輕量級的視圖誊辉,顯示您的代碼如何創(chuàng)建和使用URL會話。即使您打算編寫自己的代理亡脑,也應該閱讀本節(jié)芥映,因為它可以讓您完整了解代碼的配置對象并使用它。
  • 使用Life Cycle of a URL Session with Custom Delegates提供了URL會話操作中每個完整參考步驟远豺。您應參考本節(jié)以幫助您了解會話如何與其代理進行交互奈偏。特別是,這解釋了何時調(diào)用每個代理方法躯护。

Life Cycle of a URL Session with System-Provided Delegates - 使用系統(tǒng)提供的代理的URL會話的生命周期

如果您在未提供代理對象的情況下使用NSURLSession類惊来,則系統(tǒng)提供的委托將為您處理許多細節(jié)。這是您的應用程序必須完成的方法調(diào)用的基本順序棺滞,以及在使用系統(tǒng)提供的代理使用NSURLSession時應用程序接收到的完成處理程序調(diào)用裁蚁。

    1. 創(chuàng)建會話配置。對于后臺會話继准,此配置必須包含唯一標識符枉证。存儲該標識符,并在應用程序崩潰或終止或掛起時使用該標識符與會話重新關(guān)聯(lián)移必。
    1. 創(chuàng)建一個會話室谚,指定一個配置對象和一個nil代理。
    1. 在每個表示資源請求的會話中創(chuàng)建任務對象。
      每個任務都以暫停狀態(tài)開始。在您的應用程序調(diào)用任務的resume方法后,它開始下載指定的資源仅仆。任務對象是NSURLSessionTask-NSURLSessionDataTask,NSURLSessionUploadTask或NSURLSessionDownloadTask的子類陈瘦,具體取決于您嘗試實現(xiàn)的行為。

盡管您的應用程序可以(并且通常應該)向會話添加多個任務潮售,但為了簡單起見痊项,其余步驟按照單個任務來描述生命周期。

重要提示:如果您在未提供委托的情況下使用NSURLSession類酥诽,則您的應用程序必須使用帶有completionHandler參數(shù)的調(diào)用來創(chuàng)建任務线婚,否則它無法從類中獲取數(shù)據(jù)。

    1. 對于下載任務盆均,在從服務器傳輸期間塞弊,如果用戶通知您的應用程序暫停下載,則通過調(diào)用cancelByProducingResumeData:方法來取消該任務泪姨。稍后游沿,將返回的resume數(shù)據(jù)傳遞給downloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:方法以創(chuàng)建一個新的下載任務,以繼續(xù)下載肮砾。
    1. 當任務完成時诀黍,NSURLSession對象調(diào)用任務的完成處理程序。

注意:NSURLSession不會通過錯誤參數(shù)報告服務器錯誤仗处。您的應用程序通過error參數(shù)收到的唯一錯誤是客戶端錯誤眯勾,例如無法解析主機名或連接到主機。 URL Loading System Error Codes中描述了錯誤代碼婆誓。通過NSHTTPURLResponse對象中的HTTP狀態(tài)代碼報告服務器端錯誤吃环。有關(guān)更多信息,請閱讀NSHTTPURLResponseNSURLResponse類的文檔洋幻。

    1. 當您的應用程序不再需要會話時郁轻,通過調(diào)用invalidateAndCancel(取消未完成的任務)或finishTasksAndInvalidate(以允許未完成的任務在使對象失效之前完成)來使其失效。

Life Cycle of a URL Session with Custom Delegates - 自定義代理的URL會話的生命周期

您通澄牧簦可以在不提供代理的情況下使用NSURLSession API好唯。但是,如果您使用NSURLSession API進行后臺下載和上載燥翅,或者您需要以非默認方式處理身份驗證或緩存骑篙,則必須提供遵循會話代理協(xié)議的代理,一個或多個任務代理協(xié)議或這些協(xié)議的一些組合森书。這個代理有許多用途:

  • 與下載任務一起使用時靶端,NSURLSession對象使用代理為您的應用程序提供文件URL谎势,以便它可以獲取下載的數(shù)據(jù)。所有后臺下載和上傳都需要代理躲查。這些代理必須提供NSURLSessionDownloadDelegate協(xié)議中的所有代理方法。
  • 代理們可以處理特定的認證挑戰(zhàn)译柏。
  • 代理提供正文流以將基于流的數(shù)據(jù)上傳到遠程服務器镣煮。
  • 代理可以決定是否遵循HTTP重定向。
  • NSURLSession對象使用代理為您的應用程序提供每次傳輸?shù)臓顟B(tài)鄙麦。數(shù)據(jù)任務代理既可以接收初始調(diào)用(可以將請求轉(zhuǎn)換為下載)典唇,也可以接收隨后的調(diào)用,這些調(diào)用在從遠程服務器到達時提供數(shù)據(jù)片段胯府。
  • 代理是NSURLSession對象在傳輸完成時可以告訴您的應用程序的一種方式介衔。

如果您正在使用具有URL會話的自定義代理(后臺任務需要),則URL會話的完整生命周期更加復雜骂因。以下是您的應用程序必須進行的方法調(diào)用的基本順序炎咖,以及使用帶有自定義代理的NSURLSession時你的APP接收的代理調(diào)用。

    1. 創(chuàng)建會話配置寒波。對于后臺會話乘盼,此配置必須包含唯一標識符。存儲該標識符俄烁,并在應用程序崩潰或終止或掛起時使用該標識符與會話重新關(guān)聯(lián)绸栅。
    1. 創(chuàng)建一個會話,指定一個配置對象以及一個可選的代理页屠。
    1. 在每個表示資源請求的會話中創(chuàng)建任務對象粹胯。每個任務都以暫停狀態(tài)開始。在您的應用程序調(diào)用任務resume方法后辰企,它開始下載指定的資源风纠。任務對象是NSURLSessionTask-NSURLSessionDataTask,NSURLSessionUploadTask或NSURLSessionDownloadTask的子類牢贸,具體取決于您嘗試實現(xiàn)的行為议忽。盡管您的應用程序可以(并且通常應該)向會話添加多個任務,但為了簡單起見十减,下面其余步驟按照單個任務來描述生命周期栈幸。
    1. 如果遠程服務器返回一個狀態(tài)碼,該狀態(tài)碼指示需要身份驗證帮辟,并且該身份驗證需要連接級別質(zhì)詢(如SSL客戶端證書)速址,則NSURLSession將調(diào)用身份驗證質(zhì)詢代理方法。
    • 對于會話級挑戰(zhàn)-NSURLAuthenticationMethodNTLM由驹,NSURLAuthenticationMethodNegotiate芍锚,NSURLAuthenticationMethodClientCertificate或NSURLAuthenticationMethodServerTrust - NSURLSession對象調(diào)用會話委托的URLSession:didReceiveChallenge:completionHandler:方法昔园。如果您的應用程序未提供會話代理方法,則NSURLSession對象會調(diào)用任務代理的URLSession:task:didReceiveChallenge:completionHandler:方法來處理該挑戰(zhàn)并炮。
    • 對于非會話級挑戰(zhàn)(所有其他挑戰(zhàn))默刚,NSURLSession對象調(diào)用會話代理的URLSession:task:didReceiveChallenge:completionHandler:方法來處理挑戰(zhàn)。如果您的應用程序提供了會話代理逃魄,并且您需要處理身份驗證荤西,那么您必須在任務級別處理身份驗證,或者提供明確調(diào)用每會話處理程序的任務級別處理程序伍俘。會話代理的URLSession:didReceiveChallenge:completionHandler:方法低于非會話級別的挑戰(zhàn)不會調(diào)用邪锌。

注意:Kerberos身份驗證是透明處理的。

如果上傳任務的認證失敗癌瘾,如果任務的數(shù)據(jù)是從流中提供的觅丰,則NSURLSession對象將調(diào)用代理的URLSession:task:needNewBodyStream:代理方法。代理必須提供一個新的NSInputStream對象來為新的請求提供正文數(shù)據(jù)妨退。

有關(guān)為NSURLSession編寫身份驗證代理方法的更多信息妇萄,請參閱Authentication Challenges and TLS Chain Validation

稍后剪廉,如果用戶要求您的應用程序繼續(xù)下載,請將所返回的resume數(shù)據(jù)傳遞給downloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:方法以創(chuàng)建一個可繼續(xù)下載的新下載任務炕檩,然后轉(zhuǎn)到步驟3(創(chuàng)建并恢復任務對象)斗蒋。

    1. 對于數(shù)據(jù)任務,NSURLSession對象調(diào)用代理的URLSession:dataTask:willCacheResponse:completionHandler:方法笛质。然后你的應用程序應該決定是否允許緩存泉沾。如果您未實現(xiàn)此方法,則默認行為是使用會話配置對象中指定的緩存策略妇押。
    1. 如果下載任務成功完成跷究,則NSURLSession對象調(diào)用任務的URLSession:downloadTask:didFinishDownloadingToURL:方法并獲取臨時文件的位置。在此代理方法返回之前敲霍,您的應用必須從此文件讀取響應數(shù)據(jù)或?qū)⑵湟浦翍蒙诚淙萜髂夸浿械挠谰梦恢谩?/li>
    1. 當任何任務完成時俊马,NSURLSession對象調(diào)用返回錯誤對象或nil(如果任務成功完成)的代理的URLSession:task:didCompleteWithError:方法。如果任務失敗肩杈,則大多數(shù)應用程序都應該重試請求柴我,直到用戶取消下載或服務器返回錯誤,表明請求永遠不會成功扩然。但是艘儒,您的應用不應該立即重試。相反夫偶,它應該使用reachability API來確定服務器是否可聯(lián)通界睁,并且僅當它收到reachability已更改的通知時才應發(fā)出新請求。

如果可以恢復下載任務兵拢,則NSError對象的userInfo字典包含NSURLSessionDownloadTaskResumeData鍵的值晕窑。您的應用應該傳遞此值調(diào)用downloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:創(chuàng)建一個新的下載任務,以繼續(xù)現(xiàn)有的下載卵佛。

如果任務無法恢復杨赤,您的應用程序應該創(chuàng)建一個新的下載任務并從頭開始重新啟動事務敞斋。

無論哪種情況,如果由于服務器錯誤以外的其他原因?qū)е聜鬏斒〖采堔D(zhuǎn)至步驟3(創(chuàng)建并恢復任務對象)植捎。

注意:NSURLSession不會通過錯誤參數(shù)報告服務器錯誤。代理通過error參數(shù)收到的唯一錯誤是客戶端錯誤阳柔,例如無法解析主機名或連接到主機焰枢。 URL Loading System Error Codes中描述了錯誤代碼。
通過NSHTTPURLResponse對象中的HTTP狀態(tài)代碼報告服務器端錯誤舌剂。有關(guān)更多信息济锄,請閱讀NSHTTPURLResponseNSURLResponse類的文檔。

    1. 如果響應是多部分編碼的霍转,那么會話可以再次調(diào)用代理的didReceiveResponse方法荐绝,然后再調(diào)用零個或多個額外的didReceiveData調(diào)用。如果發(fā)生這種情況避消,請轉(zhuǎn)到步驟7(處理didReceiveResponse調(diào)用)低滩。
    1. 當您不再需要會話時,通過調(diào)用invalidateAndCancel(取消未完成的任務)或finishTasksAndInvalidate(以允許未完成的任務在使對象失效之前完成)來使其無效岩喷。在使會話無效之后恕沫,當所有未完成的任務已被取消或完成時,會話向委托發(fā)送一個URLSession:didBecomeInvalidWithError:
      消息纱意。當該代理方法返回時婶溯,會話將處理其對代理的強烈引用。

重要提示:會話對象保持對代理的強引用偷霉,直到您的應用程序明確地使會話失效迄委。如果您不會使會話失效,您的應用程序會泄漏內(nèi)存腾它。

如果您的應用取消正在進行的下載跑筝,則NSURLSession對象會像發(fā)生錯誤一樣調(diào)用代理的URLSession:task:didCompleteWithError:方法。

后記

本篇介紹了關(guān)于URL Session的生命周期問題瞒滴,喜歡的就給個贊或者點個關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曲梗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子妓忍,更是在濱河造成了極大的恐慌虏两,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世剖,死亡現(xiàn)場離奇詭異定罢,居然都是意外死亡,警方通過查閱死者的電腦和手機旁瘫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門祖凫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼蚯,“玉大人,你說我怎么就攤上這事惠况≡馐” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵稠屠,是天一觀的道長峦睡。 經(jīng)常有香客問我,道長权埠,這世上最難降的妖魔是什么榨了? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮攘蔽,結(jié)果婚禮上龙屉,老公的妹妹穿的比我還像新娘。我一直安慰自己秩彤,他們只是感情好叔扼,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布事哭。 她就那樣靜靜地躺著漫雷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳍咱。 梳的紋絲不亂的頭發(fā)上降盹,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音谤辜,去河邊找鬼蓄坏。 笑死,一個胖子當著我的面吹牛丑念,可吹牛的內(nèi)容都是我干的涡戳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼脯倚,長吁一口氣:“原來是場噩夢啊……” “哼渔彰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起推正,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤恍涂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后植榕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再沧,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年尊残,在試婚紗的時候發(fā)現(xiàn)自己被綠了炒瘸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淤堵。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖顷扩,靈堂內(nèi)的尸體忽然破棺而出粘勒,到底是詐尸還是另有隱情,我是刑警寧澤屎即,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布庙睡,位于F島的核電站,受9級特大地震影響技俐,放射性物質(zhì)發(fā)生泄漏乘陪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一雕擂、第九天 我趴在偏房一處隱蔽的房頂上張望啡邑。 院中可真熱鬧,春花似錦井赌、人聲如沸谤逼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽流部。三九已至,卻和暖如春纹坐,著一層夾襖步出監(jiān)牢的瞬間枝冀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工耘子, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留果漾,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓谷誓,卻偏偏與公主長得像绒障,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子捍歪,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

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