一:NSURLSessionDownloadTask:实现文件下载:无法监听进度

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self download];
}//优点:不需要担心内存
//缺点:无法监听文件下载进度
-(void)download
{//1.urlNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.创建sessionNSURLSession *session = [NSURLSession sharedSession];//4.创建Task/*第一个参数:请求对象第二个参数:completionHandler 回调location:文件保存的tmp路径urlresponse:响应头信息error:错误信息因为存在tmp路径,所以随时可能会被删除,所以需要手动移动文件夹来存储下载的文件*///该方法内部已经实现了边接受数据边写沙盒(tmp)的操作NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {//6.处理数据NSLog(@"%@---%@",location,[NSThread currentThread]);//6.1 拼接文件全路径NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];//6.2 剪切文件
        [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];NSLog(@"%@",fullPath);}];//5.执行Task
    [downloadTask resume];
}@end

(1)使用NSURLSession和NSURLSessionDownload可以很方便的实现文件下载操作

```objc

/*

第一个参数:要下载文件的url路径

第二个参数:当接收完服务器返回的数据之后调用该block

location:下载的文件的保存地址(默认是存储在沙盒中tmp文件夹下面,随时会被删除)

response:服务器响应信息,响应头

error:该请求的错误信息

*/

//说明:downloadTaskWithURL方法已经实现了在下载文件数据的过程中边下载文件数据,边写入到沙盒文件的操作

NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * __nullable location, NSURLResponse * __nullable response, NSError * __nullable error)

```

(2)downloadTaskWithURL内部默认已经实现了变下载边写入操作,所以不用开发人员担心内存问题

(3)文件下载后默认保存在tmp文件目录,需要开发人员手动的剪切到合适的沙盒目录

(4)缺点:没有办法监控下载进度

二:NSURLSessionDownloadTask:实现文件下载:监听进度

#import "ViewController.h"@interface ViewController ()<NSURLSessionDownloadDelegate>@end@implementation ViewController-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self delegate];
}//优点:不需要担心内存
//缺点:无法监听文件下载进度
-(void)download
{//1.urlNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.创建sessionNSURLSession *session = [NSURLSession sharedSession];//4.创建Task/*第一个参数:请求对象第二个参数:completionHandler 回调location:response:响应头信息error:错误信息*///该方法内部已经实现了边接受数据边写沙盒(tmp)的操作NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {//6.处理数据NSLog(@"%@---%@",location,[NSThread currentThread]);//6.1 拼接文件全路径NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];//6.2 剪切文件
        [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];NSLog(@"%@",fullPath);}];//5.执行Task
    [downloadTask resume];
}-(void)delegate
{//1.urlNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.创建sessionNSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];//4.创建TaskNSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];//5.执行Task
    [downloadTask resume];
}#pragma mark ----------------------
#pragma mark NSURLSessionDownloadDelegate
/***  写数据**  @param session                   会话对象*  @param downloadTask              下载任务*  @param bytesWritten              本次写入的数据大小*  @param totalBytesWritten         下载的数据总大小*  @param totalBytesExpectedToWrite  文件的总大小*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{//1. 获得文件的下载进度NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);
}/***  当恢复下载的时候调用该方法**  @param fileOffset         从什么地方下载*  @param expectedTotalBytes 文件的总大小*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{NSLog(@"%s",__func__);
}/***  当下载完成的时候调用**  @param location     文件的临时存储路径*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{NSLog(@"%@",location);//1 拼接文件全路径NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];//2 剪切文件
    [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];NSLog(@"%@",fullPath);
}/***  请求结束*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{NSLog(@"didCompleteWithError");
}@end

#import "ViewController.h"@interface ViewController ()<NSURLSessionDownloadDelegate>
@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic, strong) NSData *resumData;
@property (nonatomic, strong) NSURLSession *session;
@end@implementation ViewController- (IBAction)startBtnClick:(id)sender
{//1.urlNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.创建sessionNSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];//4.创建TaskNSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];//5.执行Task
    [downloadTask resume];self.downloadTask = downloadTask;}//暂停是可以恢复
- (IBAction)suspendBtnClick:(id)sender
{NSLog(@"+++++++++++++++++++暂停");[self.downloadTask suspend];
}//cancel:取消是不能恢复
//cancelByProducingResumeData:是可以恢复
- (IBAction)cancelBtnClick:(id)sender
{NSLog(@"+++++++++++++++++++取消");//[self.downloadTask cancel];//恢复下载的数据!=文件数据[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {self.resumData = resumeData;}];
}- (IBAction)goOnBtnClick:(id)sender
{NSLog(@"+++++++++++++++++++恢复下载");if(self.resumData){self.downloadTask = [self.session downloadTaskWithResumeData:self.resumData];}[self.downloadTask resume];
}//优点:不需要担心内存
//缺点:无法监听文件下载进度
-(void)download
{//1.urlNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.创建sessionNSURLSession *session = [NSURLSession sharedSession];//4.创建Task/*第一个参数:请求对象第二个参数:completionHandler 回调location:response:响应头信息error:错误信息*///该方法内部已经实现了边接受数据边写沙盒(tmp)的操作NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {//6.处理数据NSLog(@"%@---%@",location,[NSThread currentThread]);//6.1 拼接文件全路径NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];//6.2 剪切文件
        [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];NSLog(@"%@",fullPath);}];//5.执行Task
    [downloadTask resume];
}#pragma mark ----------------------
#pragma mark NSURLSessionDownloadDelegate
/***  写数据**  @param session                   会话对象*  @param downloadTask              下载任务*  @param bytesWritten              本次写入的数据大小*  @param totalBytesWritten         下载的数据总大小*  @param totalBytesExpectedToWrite  文件的总大小*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{//1. 获得文件的下载进度NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);
}/***  当恢复下载的时候调用该方法**  @param fileOffset         从什么地方下载*  @param expectedTotalBytes 文件的总大小*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{NSLog(@"%s",__func__);
}/***  当下载完成的时候调用**  @param location     文件的临时存储路径*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{NSLog(@"%@",location);//1 拼接文件全路径NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];//2 剪切文件
    [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];NSLog(@"%@",fullPath);
}/***  请求结束*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{NSLog(@"didCompleteWithError");
}@end

(1)创建NSURLSession并设置代理,通过NSURLSessionDownloadTask并以代理的方式来完成大文件的下载

```objc

//1.创建NSULRSession,设置代理

self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

//2.创建task

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

self.downloadTask = [self.session downloadTaskWithURL:url];

//3.执行task

[self.downloadTask resume];

```

(2)常用代理方法的说明

```objc

/*

1.当接收到下载数据的时候调用,可以在该方法中监听文件下载的进度

该方法会被调用多次

totalBytesWritten:已经写入到文件中的数据大小

totalBytesExpectedToWrite:目前文件的总大小

bytesWritten:本次下载的文件数据大小

*/

-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

/*

2.恢复下载的时候调用该方法

fileOffset:恢复之后,要从文件的什么地方开发下载

expectedTotalBytes:该文件数据的总大小

*/

-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

/*

3.下载完成之后调用该方法

*/

-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location

/*

4.请求完成之后调用

如果请求失败,那么error有值

*/

-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error

```

(3)实现断点下载相关代码

```objc

//如果任务,取消了那么以后就不能恢复了

//    [self.downloadTask cancel];

//如果采取这种方式来取消任务,那么该方法会通过resumeData保存当前文件的下载信息

//只要有了这份信息,以后就可以通过这些信息来恢复下载

[self.downloadTask cancelByProducingResumeData:^(NSData * __nullable resumeData) {

self.resumeData = resumeData;

}];

-----------

//继续下载

//首先通过之前保存的resumeData信息,创建一个下载任务

self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];

[self.downloadTask resume];

```

(4)计算当前下载进度

```objc

//获取文件下载进度

self.progress.progress = 1.0 * totalBytesWritten/totalBytesExpectedToWrite;

```

(5)局限性

01 如果用户点击暂停之后退出程序,那么需要把恢复下载的数据写一份到沙盒,代码复杂度更

02 如果用户在下载中途未保存恢复下载数据即退出程序,则不具备可操作性

---

转载于:https://www.cnblogs.com/cqb-learner/p/5862507.html

ios开发网络学习九:NSURLSessionDownloadTask实现大文件下载相关推荐

  1. iOS开发网络篇—使用ASI框架进行文件下载

    iOS开发网络篇-使用ASI框架进行文件下载 说明:本文介绍iOS网络编程中经常用到的框架ASI,如何使用该框架进行文件的下载. 一.简单介绍 代码示例: 1 #import "YYView ...

  2. ios开发网络学习:一:NSURLConnection发送GET,POST请求

    #import "ViewController.h"@interface ViewController ()<NSURLConnectionDataDelegate> ...

  3. iOS开发网络篇—多线程断点下载

    iOS开发网络篇-多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  4. iOS开发网络篇—数据缓存

    iOS开发网络篇-数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以 ...

  5. 02.iOS开发网络篇—HTTP协议

    iOS开发网络篇-HTTP协议 说明:apache tomcat服务器必须占用8080端口 一.URL 1.基本介绍 URL的全称是Uniform Resource Locator(统一资源定位符) ...

  6. iOS开发人员不容错过的10大工具

    内容简介 1.iOS简介 2.iOS开发十大实用工具之开发环境 3.iOS开发十大实用工具之图标设计 4.iOS开发十大实用工具之原型设计 5.iOS开发十大实用工具之演示工具 6.iOS开发十大实用 ...

  7. iOS开发网络篇—搭建本地服务器

    iOS开发网络篇-搭建本地服务器 一.简单说明 说明:提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提示:提前准备好的软件 apache- ...

  8. 0811 iOS开发完整学习路线

    1.iOS开发需要学习哪些内容? 2.开发步骤 3.框架 为了方便开发者开发出强大的功能,苹果提供了各种各样的框架 [1]UIKit:创建和管理应用程序的用户界面 [2]QuartzCore:提供动画 ...

  9. iOS开发——网络请求案例汇总(AFNetworking)

    我在之前一篇博客中实现了使用NSURLConnection或者NSURLSession来请求网络数据,用的都是苹果自带的方法.请参考<iOS开发--网络请求案例汇总>.现在我们使用最流行的 ...

最新文章

  1. 2020春季学期信号与系统课堂参与信息处理
  2. Node.js 11.12.0 发布,服务器端的 JavaScript 运行环境
  3. css3动画-animation
  4. [云炬创业基础笔记]第七章创业资源测试1
  5. TypeError: object of type 'zip' has no len()、'zip' object is not subscriptable
  6. JavaScript学习(十二)—removeAttribute方法、hasAttribute方法、createAttribute方法以及setAttributeNode方法
  7. DNS分别在什么情况下使用UDP和TCP?
  8. 现在工作和技术一般,想下班后充充电多学点东西。然而事实却相反,怎么让自己的学习更加有毅力?...
  9. python dictionay(字典 )基本用法
  10. 7-3 小L的难题 (15 分)
  11. day18正则表达式 的介绍和模块运用
  12. python迭代法求极值_4计算函数零点和极值点的迭代法
  13. 【Java实例】随机数比较大小
  14. 计算机二级证一定要优秀吗,计算机二级需要优秀吗 如何拿拿到优秀成绩
  15. win7 无法访问服务器共享文件夹,win7系统共享文件夹无法访问的解决方法
  16. Android软件安全与逆向分析笔记
  17. ExecuteNonQuery方法和ExecuteScalar方法的区别
  18. 惠普笔记本无法调节亮度解决办法【成功解决记录贴】
  19. java freemarker 导出富文本到Word文档
  20. Monty Hall Problem

热门文章

  1. Windows系统cmd常用命令详解
  2. Win2003安装SP1方法
  3. CCF NOI1072 爬楼梯
  4. Windows系统下查看已共享的文件夹的方法
  5. 使用entityframework操作sqlite数据库
  6. 上传文件到服务器端后进一步推送到sftp服务器
  7. 15款免费的 HTML5/CSS3 响应式网页模板
  8. 使用 ssmtp 於 shell 透過 Gmail 寄信
  9. Python3数据结构总结(列表list,元组tuple,集合set,字典dict,堆栈stack,队列queue和遍历技巧)
  10. https 慢_dba+开源工具:可视化分析MongoDB慢查询日志