你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> NSURLSessionDownloadTask的深度斷點續傳

NSURLSessionDownloadTask的深度斷點續傳

編輯:IOS開發基礎

未標題-1.jpg

本文為投稿文章,作者:WeiTChen

對於後台下載與斷點續傳相信大家肯定不會陌生,那麼如果要同時實現這兩種需求該怎麼辦呢?

使用NSURLSessionDataTask可以很輕松實現斷點續傳,可是有個致命的缺點就是無法進行後台下載,一點應用程序進入了後台,便會停止下載。所以無法滿足我們的需求。而NSURLSessionDownloadTask是唯一可以實現後台下載的類,所以我們只能從這個類進行下手了。

網上關於NSURLSessionDownloadTask的斷點續傳資料很多,但是很遺憾的是基本都是一模一樣的CV大法。而且只有一個暫停按鈕暫停後繼續下載,而關於應用程序被關閉後的斷點續傳卻是完全空白。
那麼本篇我們就來談談關於應用程序隨時可能被殺死的情況下,如何進行斷點續傳。

關於斷點續傳原理:

首先,如果想要進行斷點續傳,那麼需要簡單了解一下斷點續傳的工作機制,在HTTP請求頭中,有一個Range的關鍵字,通過這個關鍵字可以告訴服務器返回哪些數據給我。
比如:
bytes=500-999 表示第500-第999字節
bytes=500- 表示從第500字節往後的所有字節
然後我們再根據服務器返回的數據,將得到的data數據拼接到文件後面,就可以實現斷點續傳了。

關於NSURLSessionDownloadTask基礎

大家可以參考下這篇文章:iOS中利用NSURLSession進行文件斷點下載

關於文件下載與暫停的分析

當使用NSURLSessionDownloadTask進行下載的時候,系統會在cache文件夾下創建一個下載的路徑,路徑下會有一個以"CFNetworking"打頭的.tmp文件(以下簡稱"下載文件"防止混淆),這個就是我們正在下載中的文件。而當我們調用了cancelByProducingResumeData:方法後,會得到一個data文件,通過String格式化後,發現是一個XML文件,裡面包含了關於.tmp文件的一些關鍵點的描述,包括"Range","key","下載文件的路徑"等等.而原本存在於download文件下的下載文件,則被移動到了系統tmp文件夾目錄下.而當我們再次進行resume操作的時候,下載文件則又被移回到了download文件夾下。

關於程序被殺掉的斷點續傳resumeData

根據上面的分析,基本可以得到以下結論:
1.DownloadTask每次進行斷點續傳的時候,會根據data文件中的"路徑Key"去尋找下載文件,然後校驗後再根據"Range"屬性去進行斷點續傳。
2.download文件夾中存放的只會是下載中的文件,一旦暫停就會被移動到tmp文件夾下。
3.每個暫停得到的data文件,與下載文件一一對應。
3.斷點續傳只與tmp文件夾中的文件有關。

具體實現

為了節省性能,我嘗試查找關於程序被殺掉前的回調,但是很遺憾失敗了,因為我無法控制到知道是哪一秒去保存進度,所以我只能每隔一段時間保存一次。設置一個Bool變量用來判斷是否正在下載中,同時用一個周期事件每隔一段時間暫停一次(聽上去挺笨的,但是這似乎是唯一獲得data文件的辦法了)。然後保存data文件和拷貝tmp文件夾下的下載文件到安全目錄下(因為tmp文件夾據說隨時可能清空)。
當再次下載的時候,先是從安全目錄下取到下載文件,刪除tmp文件夾中原有的同名文件,然後copy到tmp目錄下,最後利用保存的data文件進行再次downloadTaskWithResumeData操作,就可以實現再次下載了。

利與弊

好處:
1.DownloadTask可以後台下載,不必保持app在前台,用戶體驗很好。
2.實現了任意時間點殺掉進程後,仍然可以斷點續傳。

缺陷:
1.因為蘋果沒有提供很好的API,所以會有一個循環檢查,每隔一段時間會暫停個一秒左右,效率略有降低。
2.如果設置保存間隔過長,中間殺掉進程可能會損失較多進度。

最後附上Demo的Github地址:https://github.com/WeiTChen/NSURLSessionDownload.git

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved