在我們?nèi)粘i_發(fā)的過程中帽哑,我們的項(xiàng)目中可能都會(huì)遇到一個(gè)需求就是去下載一個(gè)文件供置,然后將文件保存到本地柳爽,但是在下載的過程中一定是異步的进鸠,也就是說我們可能會(huì)有其它的操作稠曼,這個(gè)時(shí)候可能我們的程序會(huì)遇到一些意外造成閃退的問題亦或是用戶在下載中用戶就退出了程序,如果用戶下次進(jìn)入程序的時(shí)候就需要重新進(jìn)行下載那么一定會(huì)造成極差的用戶體驗(yàn)堤如,所以我們一定需要知道用戶下載的進(jìn)度蒲列。
最近我們的項(xiàng)目中就在做相關(guān)的問題窒朋,官方文檔上NSUrlSessionDownloadTask章節(jié)中沒有找到我想要的方案搀罢,于是我百度了一下相關(guān)的答案,找到的一個(gè)稍微有點(diǎn)用的方案竟然是創(chuàng)建一個(gè)輪詢的timer侥猩,間隔一段時(shí)間在異步線程中將程序暫停獲取到數(shù)據(jù)后存儲(chǔ)到本地榔至,這樣就能保證用戶最多只是小部分?jǐn)?shù)據(jù)的丟失,但是在我看來這樣的方案一定是極差的欺劳。因?yàn)槊看螘和N募霓D(zhuǎn)移都需要花費(fèi)大量的時(shí)間唧取,然后再去resume下載任務(wù)肯定不合理。我就去嘗試了一下愛奇藝的電影的下載划提,我發(fā)現(xiàn)愛奇藝可以做到后臺(tái)看到的下載進(jìn)度枫弟,在后臺(tái)殺死后,再開啟從上次進(jìn)度繼續(xù)下載鹏往,于是我就很好奇他們的實(shí)現(xiàn)方案淡诗。
當(dāng)時(shí)我想到一種方案是利用Application中- (void)applicationWillTerminate:(UIApplication*)application通知,在每次程序?qū)⒁粴⑺赖臅r(shí)候如果有正在下載的任務(wù)將之暫停然后進(jìn)行下載伊履,為此我專門去看了對(duì)應(yīng)的官方文檔韩容,在這個(gè)方法中我們可以做一些數(shù)據(jù)釋放和數(shù)據(jù)保存相關(guān)的操作而且有將近5秒的操作時(shí)間,其實(shí)這個(gè)時(shí)候還是一個(gè)問題就是文檔上說如果用戶是在后臺(tái)殺死程序的話這個(gè)方法一樣是不會(huì)被調(diào)用的唐瀑,雖然有這樣的問題群凶,但是我還是想嘗試一下單純從前臺(tái)是不是能夠?qū)崿F(xiàn)。我起初只是寫了一個(gè)簡單的異步線程哄辣,但是發(fā)現(xiàn)內(nèi)部的打印不會(huì)執(zhí)行请梢,所以我就用了下邊的方案進(jìn)行測試,發(fā)現(xiàn)我的打印被執(zhí)行了力穗。我想也許我找到了一種解決方案溢陪。代碼如下
但是當(dāng)我在項(xiàng)目中加入這個(gè)通知的時(shí)候我發(fā)現(xiàn)這個(gè)時(shí)候是無法執(zhí)行到的,代碼大致如下
也許是系統(tǒng)默認(rèn)就將我的這個(gè)線程殺死不在讓我繼續(xù)去執(zhí)行了睛廊,所以顯然這樣的方案就行不通了形真,我后來嘗試了一些其它的方案都沒有什么效果。也漸漸的理解了在百度上為什么能夠搜到那樣的解決方案,而且Google也沒有找到很好地方案咆霜。但是在我一次次失敗的過程中邓馒,我發(fā)現(xiàn)一件好玩的事情,就是如果我們每次系統(tǒng)手動(dòng)殺死程序蛾坯,下次進(jìn)入程序的時(shí)候我們都會(huì)執(zhí)行NSURLSessionTaskDelegate中的一個(gè)代理方法光酣,代碼如下。
后續(xù)的開發(fā)過程中我格外的關(guān)注這個(gè)方法脉课,我發(fā)現(xiàn)無論是我們下載過程中發(fā)生錯(cuò)誤還是我們?cè)谙螺d過程中出現(xiàn)網(wǎng)絡(luò)中斷等情況都會(huì)走這個(gè)代理方法救军。我想也許這就是說蘋果留個(gè)開發(fā)者解決這一類問題的入口,于是我打印其中的錯(cuò)誤信息大致如下
這個(gè)時(shí)候我打印一下每次暫停的時(shí)候倘零,系統(tǒng)給我們返回的相關(guān)的數(shù)據(jù)唱遭,系統(tǒng)返回?cái)?shù)據(jù)如下
通過上邊的數(shù)據(jù),我開始有一個(gè)大膽的猜測呈驶,我可以使用錯(cuò)誤中的error進(jìn)行繼續(xù)下載拷泽,然后我嘗試著用error的userinfo中的resumeData去繼續(xù)下載,發(fā)現(xiàn)這樣的方案完全能夠?qū)崿F(xiàn)我的想法袖瞻。
通過上邊的嘗試司致,我發(fā)現(xiàn)雖然在文檔上我沒有找到斷點(diǎn)續(xù)傳如何實(shí)現(xiàn),但是其實(shí)系統(tǒng)是幫我實(shí)現(xiàn)好了的聋迎。我們?nèi)绻螺d中斷脂矫,在下一次進(jìn)入的時(shí)候,系統(tǒng)會(huì)告訴我們中斷的位置霉晕,而不需要做復(fù)雜的存儲(chǔ)過程庭再。這樣我們就完成了一次斷點(diǎn)續(xù)傳。
為本文寫了一個(gè)簡單的demo:下載地址
如對(duì)本文有任何疑問娄昆,煩請(qǐng)留言區(qū)提出佩微,看到馬上都會(huì)回復(fù)。如果本文中有任何錯(cuò)誤萌焰,請(qǐng)您指正哺眯,我會(huì)馬上進(jìn)行更改。