本文內容大綱:html
一、回顧NSURLSessionTask編程
二、NSURLSessionDownloadTask大文件之block下載緩存
三、NSURLSessionDownloadTask大文件之代理方法下載網絡
四、NSURLSessionDownloadTask大文件之代理方法實現斷點續傳下載session
前言:若是讀者是第一次閱讀或者是學習關於本篇要介紹的NSURLSession的知識,最好先閱讀本人前篇《iOS開發之網絡編程--一、NSURLSession的基本使用》而後再學習本篇比較好。ide
一、回顧NSURLSessionTask:post
使用NSURLSession就須要用到NSURLSessionTask,因此關於Task的類和其子類的關係仍是要了解的:學習
本篇講解的是大文件下載,既然是"下載",因此天然要用到的是NSURLSessionDownloadTask。測試
二、NSURLSessionDownloadTask大文件之block下載url
測試的API接口:http://120.25.226.186:32812/resources/images/minion_08.png (由於Block的缺點,因此這裏用並不打的圖片文件做爲測試)
2-一、類、方法、屬性介紹:
NSURLSession
+(NSURLSession*)sharedSession; 單例,直接建立會話session對象
- (NSURLsessionDownloadTask*)downloadTaskWithURL:completionHandler:; 根據URL來建立會話的下載任務downloadTask,完成的話回調block
NSURLsessionDownloadTas
- (void)resume; 啓動並執行任務
2-二、源碼展現:
2-三、缺點:
Block下載方式不適合大文件下載,由於該方法須要等到文件下載完畢了,纔會回調completionHandler後面的block參數,而後才能夠在這個block參數能夠
獲取location(文件下載緩存的路徑)、response(響應)、error(錯誤信息)。
這樣的話,對於大文件,咱們就沒法實時的在下載過程當中獲取文件的下載進度了。
三、NSURLSessionDownloadTask大文件之代理方法下載
測試的API接口:http://120.25.226.186:32812/resources/videos/minion_02.mp4 (這回用的是大文件哦,但也不會太大,本篇基礎練習用,不會讓你下載都要花個好幾十分鐘以上的時間😉)
3-一、類、方法、屬性:
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-二、源碼展現
3-三、相比block下載方式的優勢:
能夠實時獲取下載進度。
3-四、源碼下載:
百度雲分享連接: http://pan.baidu.com/s/1i4jmNIl 密碼: m5jk
3-五、能夠看到的效果:
而後這個路徑下你能夠找到下載的mp4文件。
四、NSURLSessionDownloadTask大文件之代理方法實現斷點續傳下載
接下來的示例是在三、NSURLSessionDownloadTask大文件之代理方法下載的基礎上進一步敘述的。
使用測試的API接口仍然是那個:http://120.25.226.186:32812/resources/videos/minion_02.mp4
4-一、爲了更好的實現斷點續傳,這裏須要添加三個按鈕實現:開始下載、暫停下載、恢復下載,並關聯到代碼中。
4-二、斷點續傳涉及到的類和方法
NSURLSessionDownloadTask:
- (void) suspend; 暫停 ,能夠恢復
- (void) cancel; 取消,不能夠恢復
- (void) cancelByProducingResumeData:^(NSData * _Nullable resumeData) : ; 取消的
- (void) resume; 在建立新的任務下resume,至關於從新啓動任務
4-三、使用上面的方法注意
4-3-一、若是使用suspend方法暫停下載,由於是可恢復的,那麼對應的下載任務對象是惟一的。
使用的時候suspend要和resume成對使用,都是同一個NSURLSessionDownloadTask調用的對象方法。
4-3-二、若是使用cancel,就至關於同時NSURLSessionDwonloadTask任務也被取消了。因此若是要從新下載就須要從新建立NSURLSessionDownloadTask對象
與此同時,就不能再重頭開始下載了,應該是要重以前已經下載的部分末尾開始下載。
下面先改改UIButton的顯示字符串爲"取消"
若是使用cancel是沒法恢復下載,可是爲了可以恢復下載就只能用 cancelByProducingResumeData:^(NSData * _Nullable resumeData)方法了。
其中這個方法中的resumeData存儲的是以前已經下載好的數據相關的信息:文件名,存儲位置,已經下載好的數據的長度等等信息,並非下載的數據自己哦。
恢復下載也是須要經過這個resumeData來恢復,而後繼續下載。同時也要從新建立下載任務對象NSURLSessionDownloadTask。
這中方法,會有一個bug,那就若是用戶再此點擊"繼續下載"按鈕,就建立新的任務,一個新的任務同時會新的線程。
4-四、源碼下載:
百度雲分享連接: http://pan.baidu.com/s/1qXnIsYK 密碼: ekx2
4-五、沒法處理的需求:
對於退出應用程序,而後重啓程序,想要斷點繼續下載沒法實現,只能從新下載。
首先,貌似可行的思路:能夠將resumData存儲在本地,可是存儲的前提是,用戶點擊了"取消下載"按鈕,實際狀況中每每是用戶直接退出應用程序而通常不會事先去點擊一下"取消按鈕",
若是是這樣的話,resumeData並無存儲在本地,就沒法實現重啓應用程序以後再繼續下載。
轉載註明出處:http://www.cnblogs.com/goodboy-heyang/p/5195806.html,尊重勞動成果。