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
NSURLSessionDownloadTask的深度断点续传的更多相关文章
- 总结iOS开发中的断点续传那些事儿
前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...
- AFNetworking 3.0 断点续传 使用记录
最近项目中用到了压缩包下载,使用AFNetworking 3.0 下载压缩包 支持断点续传 代码如下: #import "HDInternet_handler.h" #import ...
- iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) <进度值显示优化>
前言:根据前篇<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>或者<iOS开发之网络编程--3.NSURLSessionDataTask实现文 ...
- iOS开发之网络编程--3、NSURLSessionDataTask实现文件下载(离线断点续传下载)
前言:使用NSURLSessionDownloadTask满足不这个需要离线断点续传的下载需求,所以这里就需要使用NSURLSessionDataTask的代理方法来处理下载大文件,并且实现离线断点续 ...
- iOS开发之网络编程--2、NSURLSessionDownloadTask文件下载
本文内容大纲: 1.回顾NSURLSessionTask 2.NSURLSessionDownloadTask大文件之block下载 3.NSURLSessionDownloadTask大文件之代理方 ...
- iOS 应用开发中的断点续传实践总结
断点续传概述 断点续传就是从文件上次中断的地方开始重新下载或上传数据,而不是从文件开头.(本文的断点续传仅涉及下载,上传不在讨论之内)当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者 ...
- 利用NSURLSession下载视频,图片,能实现断点续传
首先分析下载资源到本地,就得有URL ,点击btn ,就会解析网络地址,获取数据,就得有进度条控件 NSURLSession类的实现,通过委托代理模式去实现一些方法,需遵守<NSURLSessi ...
- ios 后台下载,断点续传总结
2018年12月05日 16:09:00 weixin_34101784 阅读数:5 https://blog.csdn.net/weixin_34101784/article/details/875 ...
- NSURLSession下载和断点续传
NSURLSession是iOS7之后新的网络接口,和经常用到NSURLConnection是类似的.在程序在前台时,NSURLSession与NSURLConnection可以相互的替代.但是当用户 ...
随机推荐
- python中如何去除列表中重复元素?
方法一: 用内置函数set: list1 = [1, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 9] list2 = list(set(list1)) print(list2) ...
- innodb状态
Innodb_buffer_pool_pages_data Innodb buffer pool缓存池中包含数据的页的数目,包括脏页.单位是page. Innodb_buffer_pool_pages ...
- JZOJ5857 【NOIP提高组模拟A组2018.9.8】没有上司的舞会
题目 Description "那么真的有果尔德施坦因这样一个人?"他问道. "是啊,有这样一个人,他还活着.至于在哪里,我就不知道了." "那么那个 ...
- 模板:ST表
ST表:解决RMQ类问题,预处理$O(nlog_{2}n)$,查询$O(1)$ 较线段树来说每次查询为1,线段树为log,但ST表不方便更改 ST表还用了倍增思想. 模板: struct ST_MAP ...
- 88 Lowest Common Ancestor of a Binary Tree
原题网址:https://www.lintcode.com/problem/lowest-common-ancestor-of-a-binary-tree/description 描述 给定一棵二叉树 ...
- 013- unittest单元测试框架
unittest单元测试框架 重要的概念 1. TestCase TestCase 是最小的测试单元,用于检查特定输入集合的特定返回值.unittest提供了TestCase基类,我们创建的测试类需要 ...
- 数据库访问技术 odbc dao rdo uda jet oledb
一.UDA(UniversalDataAccess) 这是微软提供的通用数据访问策略.包括ADO.OLEDB和ODBC.它不光提供了数据库的访 问能力,对于其它的数据存储技术也同样支持,如目录服务.E ...
- 洛谷P5319 奥术神杖
题意:给你若干个串和一个填了一部分的串.补完这个串使得 (每个串的匹配次数 * 权值) ^ (1 / 所有串匹配次数) 最大. 解:把这个东西随便取一个对数,就变成了分数规划. 二分.然后在AC自动机 ...
- linux和window双系统下修改系统启动项
参考:http://jingyan.baidu.com/article/63acb44ae4062c61fcc17e27.html: 我们在安装双系统之后经常会遇到想打开windows但默认启动项是u ...
- 对BOM的总结
参考:JavaScript半知半解 TG著 BOM对象 Window对象是客户端JavaScript程序的全局对象. Window对象使得JavaScript与浏览器进行交互. 所有的JavaScri ...