NSURLSession使文件下載變得非常方便,只需要提供簡單的配置,下面講述使用NSURLSession實現文件下載的使用方法,這里只是實現前臺下載(應用在沒有退出的時候的下載)
配置NSURLSession
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
self.sessionConfiguration = sessionConfiguration;
NSURLSession *downloadSession = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
self.session = downloadSession;
NSURL *url = [NSURL URLWithString:@"http://sw.bos.baidu.com/sw-search-sp/software/797b4439e2551/QQ_mac_5.0.2.dmg"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *downloadTask = [downloadSession downloadTaskWithRequest:request];
self.downloadTask = downloadTask;
上述代碼將NSURLSession配置為默認配置,設置下載的URL地址,最后通過URL生成的request生成一個下載任務,生成任務之后可以調用 [downloadTask resume]也可以后面出發再調用,比如點擊了下載按鈕之后再調用。
處理下載委托
進度回調
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
NSLog(@"bytesWritten=%@,totalBytesWritten=%@,totalBytesExpectedToWrite=%@",@(bytesWritten),@(totalBytesWritten),@(totalBytesExpectedToWrite));
float progress = (float)totalBytesWritten/totalBytesExpectedToWrite;
self.downloadView.progress = progress;
}
當任務開始下載,系統會將文件先下載到臨時文件中,上述回調,表示下載到臨時文件中的字節數、文件的總字節數。這個比較簡單,進度顯示一一般放在這里.
下載完成回調
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"任務下載完成");
self.downloadView.progress = 1.0;
//將臨時文件拷貝到永久文件中
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:@"1.dmg"];
NSError *error = nil;
if ( [[NSFileManager defaultManager] fileExistsAtPath:filePath] ) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
[[NSFileManager defaultManager] copyItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:&error];
if ( error ) {
NSLog(@"錯誤信息為:%@",[error localizedDescription]);
}else{
NSLog(@"拷貝文件成功,文件的路徑為:%@",filePath);
}
}
當任務下載完成之后,系統會將文件儲存的臨時文件的路徑給出來,讓我們自己處理,需要將臨時文件拷貝到永久文件中。
整個任務完成處理
//無論是數據任務還是上傳任務執行完之后都會執行該回調
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"整個任務完成");
if (error) {
// check if resume data are available
if ([error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]) {
NSData *resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData];
//通過之前保存的resumeData,獲取斷點的NSURLSessionTask,調用resume恢復下載
self.resumeData = resumeData;
//彈出提示框,如果需要重新下載,則調用[download taskwithResumeData]
}
} else {
//下載完成處理
}
}
無論是數據任務還是上傳任務,還是下載任務,任務完成了,都會執行該回調,error為空,表示沒有錯誤,正常完成,error表示在下載過程中出現了錯誤,我們可以從error中取出,resumeData,如果需要繼續下載,只要調用downloadTask中的downloadTaskWithResumeData方法即可實現斷點下載,非常方便。
如果需要手動暫停,可以調用taskDownload中的suspend方法(也可以調用cancelByProducingResumeData),如果需要繼續下載則調用taskDownload中的resume即可.
總結
NSURLSession為下載文件提供提供了便利的接口,只需要簡單的配置和實現幾個簡單的協議即可,文件的數據處理也不需要我們關心,下載完成之需要將臨時文件拷貝到永久文件中即可.NSURLSession實現斷點續傳也非常方便,下載出現了錯誤或者是用戶手動暫停了,也不需要重新下載,只要將error中的resumeData取出來,然后調用taskDownload中的downloadTaskWithResumeData即可。比NSURLConnection實在是方便太多.