iOS开发之网络编程--2、NSURLSessionDownloadTask文件下载
本文内容大纲:
1、回顾NSURLSessionTask
2、NSURLSessionDownloadTask大文件之block下载
3、NSURLSessionDownloadTask大文件之代理方法下载
4、NSURLSessionDownloadTask大文件之代理方法实现断点续传下载
前言:如果读者是第一次阅读或者是学习关于本篇要介绍的NSURLSession的知识,最好先阅读本人前篇《iOS开发之网络编程--1、NSURLSession的基本使用》然后再学习本篇比较好。
1、回顾NSURLSessionTask:
使用NSURLSession就需要用到NSURLSessionTask,所以关于Task的类和其子类的关系还是要了解的:
本篇讲解的是大文件下载,既然是"下载",所以自然要用到的是NSURLSessionDownloadTask。
2、NSURLSessionDownloadTask大文件之block下载
测试的API接口:http://120.25.226.186:32812/resources/images/minion_08.png (因为Block的缺点,所以这里用并不打的图片文件作为测试)
2-1、类、方法、属性介绍:
NSURLSession
+(NSURLSession*)sharedSession; 单例,直接创建会话session对象
- (NSURLsessionDownloadTask*)downloadTaskWithURL:completionHandler:; 根据URL来创建会话的下载任务downloadTask,完成的话回调block
NSURLsessionDownloadTas
- (void)resume; 启动并执行任务
2-2、源码展示:
2-3、缺点:
Block下载方式不适合大文件下载,因为该方法需要等到文件下载完毕了,才会回调completionHandler后面的block参数,然后才可以在这个block参数可以
获取location(文件下载缓存的路径)、response(响应)、error(错误信息)。
这样的话,对于大文件,我们就无法实时的在下载过程中获取文件的下载进度了。
3、NSURLSessionDownloadTask大文件之代理方法下载
测试的API接口:http://120.25.226.186:32812/resources/videos/minion_02.mp4 (这回用的是大文件哦,但也不会太大,本篇基础练习用,不会让你下载都要花个好几十分钟以上的时间😉)
3-1、类、方法、属性:
NSURLSession
+(NSURLSession*)sessionWithConfiguration:delegate:delegateQueue:; 根据会话配置对象并设置代理和代理的执行队列来创建会话NSURLSession对象
- (NSURLSessionDownloadTask*)downloadTaskWithURL; 根据URL直接创建会话的任务
NSURLSessionConfiguration
+(NSURLSessionConfiguration*)defaultSessionConfiguration; 创建默认的会话配置对象
NSURLSessionDownloadTask
- (void)resume 执行会话任务
协议和代理方法:
<NSURLSessionDownloadDelegate>
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
session当前会话 downloadTask当前会话任务 bytesWritten本次写入数据大小 totalBytesWritten已经写入数据大小 totalBytesExpectedToWrite要下载的文件总大小
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
didResumeAtOffset恢复下载时调用的代理方法
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
didFinishDownloadingToURL:(NSURL *)location 内部已经实现了边下载边写入数据到沙盒的操作
downloadTask 内部时可以拿到响应头信息
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
请求失败返回错误信息调用的代理方法
3-2、源码展示
3-3、相比block下载方式的优点:
可以实时获取下载进度。
3-4、源码下载:
百度云分享链接: http://pan.baidu.com/s/1i4jmNIl 密码: m5jk
3-5、可以看到的效果:
然后这个路径下你可以找到下载的mp4文件。
4、NSURLSessionDownloadTask大文件之代理方法实现断点续传下载
接下来的示例是在3、NSURLSessionDownloadTask大文件之代理方法下载的基础上进一步叙述的。
使用测试的API接口仍然是那个:http://120.25.226.186:32812/resources/videos/minion_02.mp4
4-1、为了更好的实现断点续传,这里需要添加三个按钮实现:开始下载、暂停下载、恢复下载,并关联到代码中。
4-2、断点续传涉及到的类和方法
NSURLSessionDownloadTask:
- (void) suspend; 暂停 ,可以恢复
- (void) cancel; 取消,不可以恢复
- (void) cancelByProducingResumeData:^(NSData * _Nullable resumeData) : ; 取消的
- (void) resume; 在创建新的任务下resume,相当于重新启动任务
4-3、使用上面的方法注意
4-3-1、如果使用suspend方法暂停下载,因为是可恢复的,那么对应的下载任务对象是唯一的。
使用的时候suspend要和resume成对使用,都是同一个NSURLSessionDownloadTask调用的对象方法。
4-3-2、如果使用cancel,就相当于同时NSURLSessionDwonloadTask任务也被取消了。所以如果要重新下载就需要重新创建NSURLSessionDownloadTask对象
与此同时,就不能再重头开始下载了,应该是要重之前已经下载的部分末尾开始下载。
下面先改改UIButton的显示字符串为"取消"
如果使用cancel是无法恢复下载,但是为了能够恢复下载就只能用 cancelByProducingResumeData:^(NSData * _Nullable resumeData)方法了。
其中这个方法中的resumeData存储的是之前已经下载好的数据相关的信息:文件名,存储位置,已经下载好的数据的长度等等信息,并不是下载的数据本身哦。
恢复下载也是需要通过这个resumeData来恢复,然后继续下载。同时也要重新创建下载任务对象NSURLSessionDownloadTask。
这中方法,会有一个bug,那就如果用户再此点击"继续下载"按钮,就创建新的任务,一个新的任务同时会新的线程。
4-4、源码下载:
百度云分享链接: http://pan.baidu.com/s/1qXnIsYK 密码: ekx2
4-5、无法处理的需求:
对于退出应用程序,然后重启程序,想要断点继续下载无法实现,只能重新下载。
首先,貌似可行的思路:可以将resumData存储在本地,但是存储的前提是,用户点击了"取消下载"按钮,实际情况中往往是用户直接退出应用程序而一般不会事先去点击一下"取消按钮",
如果是这样的话,resumeData并没有存储在本地,就无法实现重启应用程序之后再继续下载。
转载注明出处:http://www.cnblogs.com/goodboy-heyang/p/5195806.html,尊重劳动成果。