本文內容大綱:
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,尊重勞動成果。