NSURLSessionDownloadTask的深度断点续传

http://www.cocoachina.com/ios/20160503/16053.html

本文为投稿文章,作者:WeiTChen

对于后台下载与断点续传相信大家肯定不会陌生,那么如果要同时实现这两种需求该怎么办呢?

使用NSURLSessionDataTask可以很轻松实现断点续传,可是有个致命的缺点就是无法进行后台下载,一点应用程序进入了后台,便会停止下载。所以无法满足我们的需求。而NSURLSessionDownloadTask是唯一可以实现后台下载的类,所以我们只能从这个类进行下手了。

网上关于NSURLSessionDownloadTask的断点续传资料很多,但是很遗憾的是基本都是一模一样的CV大法。而且只有一个暂停按钮暂停后继续下载,而关于应用程序被关闭后的断点续传却是完全空白。
那么本篇我们就来谈谈关于应用程序随时可能被杀死的情况下,如何进行断点续传。

关于断点续传原理:

首先,如果想要进行断点续传,那么需要简单了解一下断点续传的工作机制,在HTTP请求头中,有一个Range的关键字,通过这个关键字可以告诉服务器返回哪些数据给我。
比如:
bytes=500-999 表示第500-第999字节
bytes=500- 表示从第500字节往后的所有字节
然后我们再根据服务器返回的数据,将得到的data数据拼接到文件后面,就可以实现断点续传了。

关于NSURLSessionDownloadTask基础

大家可以参考下这篇文章:iOS中利用NSURLSession进行文件断点下载

关于文件下载与暂停的分析

当使用NSURLSessionDownloadTask进行下载的时候,系统会在cache文件夹下创建一个下载的路径,路径下会有一个以"CFNetworking"打头的.tmp文件(以下简称"下载文件"防止混淆),这个就是我们正在下载中的文件。而当我们调用了cancelByProducingResumeData:方法后,会得到一个data文件,通过String格式化后,发现是一个XML文件,里面包含了关于.tmp文件的一些关键点的描述,包括"Range","key","下载文件的路径"等等.而原本存在于download文件下的下载文件,则被移动到了系统tmp文件夹目录下.而当我们再次进行resume操作的时候,下载文件则又被移回到了download文件夹下。

关于程序被杀掉的断点续传resumeData

根据上面的分析,基本可以得到以下结论:
1.DownloadTask每次进行断点续传的时候,会根据data文件中的"路径Key"去寻找下载文件,然后校验后再根据"Range"属性去进行断点续传。
2.download文件夹中存放的只会是下载中的文件,一旦暂停就会被移动到tmp文件夹下。
3.每个暂停得到的data文件,与下载文件一一对应。
3.断点续传只与tmp文件夹中的文件有关。

具体实现

为了节省性能,我尝试查找关于程序被杀掉前的回调,但是很遗憾失败了,因为我无法控制到知道是哪一秒去保存进度,所以我只能每隔一段时间保存一次。设置一个Bool变量用来判断是否正在下载中,同时用一个周期事件每隔一段时间暂停一次(听上去挺笨的,但是这似乎是唯一获得data文件的办法了)。然后保存data文件和拷贝tmp文件夹下的下载文件到安全目录下(因为tmp文件夹据说随时可能清空)。
当再次下载的时候,先是从安全目录下取到下载文件,删除tmp文件夹中原有的同名文件,然后copy到tmp目录下,最后利用保存的data文件进行再次downloadTaskWithResumeData操作,就可以实现再次下载了。

利与弊

好处:
1.DownloadTask可以后台下载,不必保持app在前台,用户体验很好。
2.实现了任意时间点杀掉进程后,仍然可以断点续传。

缺陷:
1.因为苹果没有提供很好的API,所以会有一个循环检查,每隔一段时间会暂停个一秒左右,效率略有降低。
2.如果设置保存间隔过长,中间杀掉进程可能会损失较多进度。

最后附上Demo的Github地址:https://github.com/WeiTChen/NSURLSessionDownload.git

时间: 2024-10-07 03:42:21

NSURLSessionDownloadTask的深度断点续传的相关文章

利用NSURLSession下载视频,图片,能实现断点续传

首先分析下载资源到本地,就得有URL ,点击btn ,就会解析网络地址,获取数据,就得有进度条控件 NSURLSession类的实现,通过委托代理模式去实现一些方法,需遵守<NSURLSessionDownloadDelegate>,委托代理设计模式在iOS开发中得到大量使用 /* 利用NSURLConnection实现断点续传 1.NSURLSession,iOS7中推出的一个类,有取代NSURLConnection 2.实现文件的下载与上传,而NSURLSessionData有两个子类:N

网络编程之断点续传

>断点续传 1 在start方法中创建NSURLSession,并且绑定代理,注意不能使用block代码,否则不执行代理方法 2 开始下载,利用nsurlsession对象创建下载任务task 暂停下载,获取resumeData,resumeData中包含继续下载的开始位置信息 恢复下载,从resumeData中获取断点信息,继续下载 3 实现三个必要的代理方法,在代理方法中获取下载信息 在监控任务下载的代理方法downloadTask中写文件到沙盒 在 代理方法中更新UI视图(进度条) 在结束

总结iOS开发中的断点续传那些事儿

前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很浪费时间有木有.所以呢,项目中实现大文件下载的时候,断点续传功能是必不可少了.当然咯,断点续传有一种特殊的情况,就是我们的应用呗用户kill掉或者应用crash,要实现应用重启之后的断点续传,这种情况就是我们将要解决的问题. 断点续传的原理 要实现断点续传,服务器必须是要支持的.目前最常见的两种方式

网络编程(三) 下载任务,支持断点续传

实现效果图: 注意点:1.下载的文件会保存在沙盒目录下的tmp文件夹内,这个文件夹专门存储一些临时文件,我们需要在下载完成后把文件移动到自己需要的文件夹内,并修改文件的扩展名 2.有部分链接使用下载时resume data = nil;这样断点续传功能就没有用了: 在storyboard里面添加button,progressView和显示进度的label,并进行连线 ViewController.m代码 #import "ViewController.h" @interface Vie

Kill应用之后断点续传的实现

之前使用NSURLSession做了一个断点续传的demo,主要实现了在下载的过程中中断下载,然后可以再次启动延续上次的下载链接继续下载的功能.原理是将task的方法cancelByProducingResumeData的Block块中的resumeData获取下来,当再次下载的时候,通过session的downloadTaskWithResumeData方法使用该resumeData创建一个新的task,然后启动下载,就实现了断点续传的功能.但是如果说当前任务正在下载,程序切到后台之后被kil

NSURLSession用法示例及断点续传视频的实现

NSURLSession是苹果在WWDC2013中提出来的,旨在替代NSURLConnection,与我们之前经常使用的NSURLConnection不同,NSURLSession为我们提供了更灵活的使用方法,包括后台下载以及断点续传的实现等功能.之前使用下载一直用的都是第三方框架比如OC的AFNetworking或者Swift的Alamofire.虽然第三方库用起来很方便也很稳定,但是还是想自己研究下苹果原生的下载框架.这几天研究了下NSURLSession,做了一个加载视频的demo,包括了

AFNetworking 3.0 断点续传 使用记录

最近项目中用到了压缩包下载,使用AFNetworking 3.0 下载压缩包 支持断点续传 代码如下: #import "HDInternet_handler.h" #import "AFNetworking.h" #import "ASIHTTPRequest.h" @interface HDInternet_handler ()<NSURLSessionDelegate> @end @implementation HDIntern

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

1.大文件下载: 1-1.创建下载任务: 方式一:创建时同时设置代理监听下载进度: 1.-(void)downloadDelegate2.{3. //01 确定资源路径4. NSURL *url = [NSURL URLWithString:@"http://img4q.duitang.com/uploads/item/201406/09/20140609150919_ZztLd.jpeg"];5.6. //02 创建请求对象7. NSURLRequest *request = [NS

iOS开发之网络编程--2、NSURLSessionDownloadTask文件下载

本文内容大纲: 1.回顾NSURLSessionTask 2.NSURLSessionDownloadTask大文件之block下载 3.NSURLSessionDownloadTask大文件之代理方法下载 4.NSURLSessionDownloadTask大文件之代理方法实现断点续传下载 前言:如果读者是第一次阅读或者是学习关于本篇要介绍的NSURLSession的知识,最好先阅读本人前篇<iOS开发之网络编程--1.NSURLSession的基本使用>然后再学习本篇比较好. 1.回顾NS