標籤:
本文內容大綱:
1、回顧NSURLSessionTask
2、NSURLSessionDownloadTask大檔案之block下載
3、NSURLSessionDownloadTask大檔案之代理方法下載
4、NSURLSessionDownloadTask大檔案之代理方法實現斷點續傳下載
前言:如果讀者是第一次閱讀或者是學習關於本篇要介紹的NSURLSession的知識,最好先閱讀本人前篇《iOS開發之網路編程--1、NSURLSession的基本使用》然後再學習本篇比較好。
1、回顧NSURLSessionTask:
使用NSURLSession就需要用到NSURLSessionTask,所以關於Task的類和其子類的關係還是要瞭解的:
本篇講解的是大檔案下載,既然是"下載",所以自然要用到的是NSURLSessionDownloadTask。
2、NSURLSessionDownloadTask大檔案之block下載
測試的API介面:http://120.25.226.186:32812/resources/images/minion_08.png (因為Block的缺點,所以這裡用並不打的圖片檔案作為測試)
2-1、類、方法、屬性介紹:
NSURLSession
+(NSURLSession*)sharedSession; 單例,直接建立會話session對象
- (NSURLsessionDownloadTask*)downloadTaskWithURL:completionHandler:; 根據URL來建立會話的下載任務downloadTask,完成的話回調block
NSURLsessionDownloadTas
- (void)resume; 啟動並執行任務
2-2、源碼展示:
2-3、缺點:
Block下載方式不適合大檔案下載,因為該方法需要等到檔案下載完畢了,才會回調completionHandler後面的block參數,然後才可以在這個block參數可以
擷取location(檔案下載快取的路徑)、response(響應)、error(錯誤資訊)。
這樣的話,對於大檔案,我們就無法即時的在下載過程中擷取檔案的下載進度了。
3、NSURLSessionDownloadTask大檔案之代理方法下載
測試的API介面:http://120.25.226.186:32812/resources/videos/minion_02.mp4 (這回用的是大檔案哦,但也不會太大,本篇基礎練慣用,不會讓你下載都要花個好幾十分鐘以上的時間??)
3-1、類、方法、屬性:
NSURLSession
+(NSURLSession*)sessionWithConfiguration:delegate:delegateQueue:; 根據會話設定物件並設定代理和代理的執行隊列來建立會話NSURLSession對象
- (NSURLSessionDownloadTask*)downloadTaskWithURL; 根據URL直接建立會話的任務
NSURLSessionConfiguration
+(NSURLSessionConfiguration*)defaultSessionConfiguration; 建立預設的會話設定物件
NSURLSessionDownloadTask
- (void)resume 執行會話任務
協議和代理方法:
<NSURLSessionDownloadDelegate>
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
session當前會話 downloadTask當前會話任務 bytesWritten本次寫入資料大小 totalBytesWritten已經寫入資料大小 totalBytesExpectedToWrite要下載的檔案總大小
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
didResumeAtOffset恢複下載時調用的代理方法
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
didFinishDownloadingToURL:(NSURL *)location 內部已經實現了邊下載邊寫入資料到沙箱的操作
downloadTask 內部時可以拿到回應標頭資訊
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
請求失敗返回錯誤資訊調用的代理方法
3-2、源碼展示
3-3、相比block下載方式的優點:
可以即時擷取下載進度。
3-4、源碼下載:
百度雲分享連結: http://pan.baidu.com/s/1i4jmNIl 密碼: m5jk
3-5、可以看到的效果:
然後這個路徑下你可以找到下載的mp4檔案。
4、NSURLSessionDownloadTask大檔案之代理方法實現斷點續傳下載
接下來的樣本是在3、NSURLSessionDownloadTask大檔案之代理方法下載的基礎上進一步敘述的。
使用測試的API介面仍然是那個:http://120.25.226.186:32812/resources/videos/minion_02.mp4
4-1、為了更好的實現斷點續傳,這裡需要添加三個按鈕實現:開始下載、暫停下載、恢複下載,並關聯到代碼中。
4-2、斷點續傳涉及到的類和方法
NSURLSessionDownloadTask:
- (void) suspend; 暫停 ,可以恢複
- (void) cancel; 取消,不可以恢複
- (void) cancelByProducingResumeData:^(NSData * _Nullable resumeData) : ; 取消的
- (void) resume; 在建立新的任務下resume,相當於重新啟動任務
4-3、使用上面的方法注意
4-3-1、如果使用suspend方法暫停下載,因為是可恢複的,那麼對應的下載任務對象是唯一的。
使用的時候suspend要和resume成對使用,都是同一個NSURLSessionDownloadTask調用的對象方法。
4-3-2、如果使用cancel,就相當於同時NSURLSessionDwonloadTask任務也被取消了。所以如果要重新下載就需要重新建立NSURLSessionDownloadTask對象
與此同時,就不能再重頭開始下載了,應該是要重之前已經下載的部分末尾開始下載。
下面先改改UIButton的顯示字串為"取消"
如果使用cancel是無法恢複下載,但是為了能夠恢複下載就只能用 cancelByProducingResumeData:^(NSData * _Nullable resumeData)方法了。
其中這個方法中的resumeData儲存的是之前已經下載好的資料相關的資訊:檔案名稱,儲存位置,已經下載好的資料的長度等等資訊,並不是下載的資料本身哦。
恢複下載也是需要通過這個resumeData來恢複,然後繼續下載。同時也要重新建立下載任務對象NSURLSessionDownloadTask。
這中方法,會有一個bug,那就如果使用者再此點擊"繼續下載"按鈕,就建立新的任務,一個新的任務同時會新的線程。
4-4、源碼下載:
百度雲分享連結: http://pan.baidu.com/s/1qXnIsYK 密碼: ekx2
4-5、無法處理的需求:
對於退出應用程式,然後重啟程式,想要斷點繼續下載無法實現,只能重新下載。
首先,貌似可行的思路:可以將resumData儲存在本地,但是儲存的前提是,使用者點擊了"取消下載"按鈕,實際情況中往往是使用者直接退出應用程式而一般不會事先去點擊一下"取消按鈕",
如果是這樣的話,resumeData並沒有儲存在本地,就無法實現重啟應用程式之後再繼續下載。
轉載註明出處:http://www.cnblogs.com/goodboy-heyang/p/5195806.html,尊重勞動成果。
iOS開發之網路編程--2、NSURLSessionDownloadTask檔案下載