- 1、本文档共7页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
iOS开发网络编程之断点续传精要
iOS开发网络编程之断点续传
在下载较大的文件的时候,一次不能下载完毕,这就需要用到断点续传,那么在IOS开发中该如何实现呢,下面跟着小编一起通过本文来学习下。
前言
网络下载是我们在项目中经常要用到的功能,如果是小文件的下载,比如图片和文字之类的,我们可以直接请求源地址,然后一次下载完毕。但是如果是下载较大的音频和视频文件,不可能一次下载完毕,用户可能下载一段时间,关闭程序,回家接着下载。这个时候,就需要实现断点续传的功能。让用户可以随时暂停下载,下次开始下载,还能接着上次的下载的进度。
今天我们来看看如何自己简单的封装一个断点续传的类,实现如下功能。
1.使用者只需要调用一个接口即可以下载,同时可以获取下载的进度。
2.下载成功,可以获取文件存储的位置
3.下载失败,给出失败的原因
4.可以暂停下载,下次开始下载,接着上次的进度继续下载
原理讲解
要实现断点续传的功能,通常都需要客户端记录下当前的下载进度,并在需要续传的时候通知服务端本次需要下载的内容片段。
在HTTP1.1协议(RFC2616)中定义了断点续传相关的HTTP头的Range和Content-Range字段,一个最简单的断点续传实现大概如下:
1.客户端下载一个1024K的文件,已经下载了其中512K
2.网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段:Range:bytes=512000-这个头通知服务端从文件的512K位置开始传输文件
3.服务端收到断点续传请求,从文件的512K位置开始传输,并且在HTTP头中增加:Content-Range:bytes 512000-/1024000并且此时服务端返回的HTTP状态码应该是206,而不是200。
难点说明
1. 客户端如何获取已经下载的文件字节数
客户端这边,我们需要记录下每次用户每次下载的文件大小,然后实现原理讲解中步骤1的功能。
那么如何记载呢?
其实我们可以直接获取指定路径下文件的大小,iOS已经提供了相关的功能,实现代码如下,
?
1 [[[NSFileManager defaultManager] attributesOfItemAtPath: FileStorePath error:nil][NSFileSize] integerValue]
2.如何获取被下载文件的总字节数
上一步,我们获取了已经下载文件的字节数,这里我们需要获取被下载文件的总字节数,有了这两个值,我们就可以算出下载进度了。
那么如何获取呢?这里我们需要用到http 头部的conten-length字段,先来看看该字段的含义
Content-Length用于描述HTTP消息实体的传输长度the transfer-length of the message-body。在HTTP协议中,消息实体长度和消息实体的传输长度是有区别,比如说gzip压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是gzip压缩后的长度。
简单点说,content-length表示被下载文件的字节数。
对比原理讲解的第三步,我们可以看到如果要计算出文件的总字节数,那么必须把已经下载的字节数 加上 content-length。
我们需要把每个被下载文件的总字节数存储起来,这里我们选择使用plist文件来记载,plist文件包含一个字典。设置文件名为键值,已经下载的文件字节数为值。
文件名为了防止重复,这里我们设置文件名为下载url的hash值,可以保证不重重。
实现代码如下:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
self.totalLength = [response.allHeaderFields[@Content-Length] integerValue] + DownloadLength;
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile: TotalLengthPlist];
if (dict == nil) dict = [NSMutableDictionary dictionary];
dict[ Filename] = @(self.totalLength);
[dict writeToFile: TotalLengt
文档评论(0)