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实在是方便太多.