NSURLSession是iOS7提供的API,用來替代NSURLConnection
- 1.根據(jù)URL創(chuàng)建Session,并設置代理:
要跟進下載進度,不能使用全局 session
這里使用的是NSURLSessionDownloadDelegate代理方法
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
- 2.接下來根據(jù)URL、創(chuàng)建的session創(chuàng)建下載任務:
self.downloadTask = [session downloadTaskWithURL:url];
ps:通過下面這種方法創(chuàng)建下載任務時,NSURLSessionDownloadDelegate的代理方法將不會不執(zhí)行:
self.downloadTask =[session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
- 3.切記,所有任務默認都是掛起的,需要手動resume:
[self.downloadTask resume];
- 4.實現(xiàn)代理方法:
4.1.下載完成,必須實現(xiàn)
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
//下載完成后回調. location 就是文件下載之后保存的路徑
}
4.1.1 關于location的幾個常見屬性可以對比Log信息來看
NSLog(@"location:---->%@",location);
NSLog(@"location.path:---->%@",location.path);
NSLog(@"location.absoluteString:---->%@",location.absoluteString);
NSLog(@"location.absoluteURL:---->%@",location.absoluteURL);
4.1.2 Log信息:
location:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.path:---->/Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.absoluteString:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.absoluteURL:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
4.1.3 Log圖片:
2209298-effdf9ab361cf76e.png
4.2.進度方法,iOS 7.0 必須實現(xiàn)
/**
bytesWritten 本次下載數(shù)據(jù)的長度
totalBytesWritten 總共下載的數(shù)據(jù)的長度 (已經(jīng)下載了多少)
totalBytesExpectedToWrite 文件的總長度
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
}
4.3.續(xù)傳方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
}
4.4.下載錯誤監(jiān)聽
NSURLSessionDownloadDelegate 繼承自 NSURLSessionTaskDelegate 因此可以直接實現(xiàn) NSURLSessionTaskDelegate 的代理方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
}
- 5.控制下載任務
分別是:暫停、取消、繼續(xù)/開始
[self.downloadTask suspend];
[self.downloadTask cancel];
[self.downloadTask resume];
- 6.防止內(nèi)存泄露
- (void)viewDidDisappear:(BOOL)animated{
// The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session by calling the invalidateAndCancel or finishTasksAndInvalidate method, your app leaks memory until it exits.
//通過代理創(chuàng)建的session 會保持一個代理的強引用, 如果不調用下面的方法就會內(nèi)存溢出
[self.session invalidateAndCancel];
}
小結:
1.文件下載后,默認存放沙盒tmp路徑下,名稱隨機生成,并在下載完成后自動刪除,因此需要在下載完成的代理方法中進行轉存
2.與NSURLConnection對比:
2.1 NSURLConnection 通過connectionWithRequest: delegate:設置代理實現(xiàn)方法,添加異步處理后,還需手動開啟子線程的消息循環(huán),方法執(zhí)行完后會自動關閉;而NSURLSession自動異步處理,不需要干預,只是創(chuàng)建任務后默認掛起,需要resume;
2.2 NSURLConnection 的下載進度監(jiān)測實現(xiàn)過程比較復雜,而NSURLSession使用更簡便,只需要通過代理方法提供的參數(shù)直接使用即可
2.3 NSURLConnection和NSURLSession都可以實現(xiàn)對下載過程可控,包括:開始、暫停、和繼續(xù),而NSURLConnection能對程序意外退出再次進入重新下載做出更好的處理