首页 > 代码库 > iOS核心笔记——网络编程-NSURLSessionDownloadTask

iOS核心笔记——网络编程-NSURLSessionDownloadTask

1、大文件下载:

1-1、创建下载任务:
方式一:创建时同时设置代理监听下载进度:
1.-(void)downloadDelegate
2.{
3. //01 确定资源路径
4. NSURL *url = [NSURL URLWithString:@"http://img4q.duitang.com/uploads/item/201406/09/20140609150919_ZztLd.jpeg"];
5.
6. //02 创建请求对象
7. NSURLRequest *request = [NSURLRequest requestWithURL:url];
8.
9. //03 创建会话对象 设置代理
10. NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
11.
12. //04 创建downloadTask
13. NSURLSessionDownloadTask *downloadTask =[session downloadTaskWithRequest:request];
14.
15. //05 发送请求
16. [downloadTask resume];
17.
18.}

方式二:直接创建NSURLSessionDownloadTask对象:
1.//缺点:无法监听文件的进度
2.-(void)download
3.{
4. //01 确定资源路径
5. NSURL *url = [NSURL URLWithString:@"http://img4q.duitang.com/uploads/item/201406/09/20140609150919_ZztLd.jpeg"];
6.
7. //02 创建请求对象
8. NSURLRequest *request = [NSURLRequest requestWithURL:url];
9.
10. //03 创建会话对象
11. NSURLSession *session = [NSURLSession sharedSession];
12.
13. //04 创建downloadTask
14. /* 参数说明
15. *
16. * 第一个参数:请求对象
17. * 第二个参数:completionHandler 请求完成(成功|失败)的时候调用
18. * location:位置 文件的位置 内部已经实现了边接收数据边写沙盒的操作
19. * response:响应头信息
20. */
21. NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
22. //默认已经把数据写到磁盘中:tmp/...随时可能被删除
23.
24. //转移文件(转移到安全的地方去)
25. NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
26. NSString *fullPath = [cachePath stringByAppendingPathComponent:response.suggestedFilename];
27.
28. //路径 ->NSURL
29. //URLWithString 不做其他额外的处理
30. //fileURLWithPath
31. NSLog(@"%@",[NSURL URLWithString:fullPath]);
32. NSLog(@"%@",[NSURL fileURLWithPath:fullPath]);
33.
34. [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
35. }];
36.
37. //05 发送请求
38. [downloadTask resume];
39.}

1-2、NSURLSessionDownloadTask常用代理方法:
1.#pragma mark NSURLSessionDownloadDelegate
2.
3.//01 写数据的时候调用
4.// bytesWritten 本次写入的数据大小
5.// totalBytesWritten 写入数据的总大小
6.// totalBytesExpectedToWrite 文件的总大小
7.-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
8.{
9. NSLog(@"%f",1.0 * totalBytesWritten / totalBytesExpectedToWrite);
10.}

?重要:开始向应用沙盒中默认路径下的文件开始写入数据时调用。


1.//02 下载完成的时候调用
2.-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
3.{
4. //转移文件(转移到安全的地方去)
5. NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
6. NSString *fullPath = [cachePath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
7.
8. //剪切文件
9. [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
10.}

?重要:下载完成时调用该方法,默认下载完成便会删除该路径下的文件;所以,需要在下载完成时将文件转移至其它安全的路径下。


1.//03 整个请求结束或者是失败的时候调用
2.-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
3.{
4. NSLog(@"didCompleteWithError");
5.}

?重要:当下载任务完成时或失败时调用。


2、断点续传:

?重要:1、NSURLSessionDownloadTask能使用suspend(挂起下载任务)resume(启动下载任务)cancel(不可恢复取消下载任务)cancelByProducingResumeData:(可恢复下载任务)操作下载任务。

?重要:2、NSURLSessionDownloadTask使用cancel方法取消下载操作之后便不能够再恢复下载任务(即:使用cancel方法取消之后便不能再进行断点续传,因为,downloadTask如果不做特殊处理,下载操作执行完毕或者使用cancel方法取消将会立即删除保存在沙盒路径中的文件;所以,不能使用NSURLSessionDownloadTask实现离线下载功能,也不能使用cancel方法实现断点续传功能)。

?重要:3、使用cancelByProducingResumeData:方法取消下载任务,使用属性保存resumeData数据;便可以实现断点续传功能。

?重要:4、resumeData:可以用来恢复下载的数据,并不是沙盒中保存的已经下载好的文件数据。


2-1、使用属性保存恢复下载操作所需的resumeData数据:
1.@property (nonatomic, strong) NSData *resumeData;

2-2、使用cancelByProducingResumeData:暂停下载操作:
1.- (IBAction)cacnelBtnClick:(id)sender
2.{
3. //取消 普通的取消操作是不可以恢复的
4. //[self.downloadTask cancel];
5.
6. //取消,可以恢复的取消操作
7. //resumeData 可以用来恢复下载的数据 并不是沙盒中保存的已经下载好的文件数据
8. [self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
9. self.resumeData = http://www.mamicode.com/resumeData;
10. }];
11.
12. self.downloadTask = nil;
13. NSLog(@"取消下载任务+++");
14.}

2-3、恢复下载任务:
1.- (IBAction)resumeBtnClick:(id)sender
2.{
3. //暂停->恢复
4. if(self.resumeData)
5. {
6. //取消->恢复
7. //在恢复下载的时候,判断是否有可以用来进行恢复下载的数据,如果有那么就根据该数据创建一个新的网络请求
8. self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
9. self.resumeData = http://www.mamicode.com/nil;
10. }
11.
12. [self.downloadTask resume];
13.}

iOS核心笔记——网络编程-NSURLSessionDownloadTask