本篇文章介绍文件下载,包括以下内容:

  1. 原生态的分段下载的基本原理

  2. NSURLSession的下载任务

  3. 使用AFNetworking下载

  4. 下载任务常遇状况

  • 原生态的分段下载的基本原理

文件下载往往需要比较长的一段时间,实现分段下载是实现断点下载的前提

实现分段下载需要解决以下两个问题

问题1:下载前,需要知道文件的长度

问题2:每一次请求下载文件的一段

  • 针对问题1:HEAD请求获取文件长度

HEAD请求只获取响报文,而不获取资源的实际数据

通常用来获取文件长度、检测服务器端资源是否发生变化

响应对象NSURLResponse的属性exceptedContentLength即表示文件的长度

  • 针对问题2:请求头参数Range进行分段下载

HTTP协议规定,请求头中的Range参数用于请求一段数据

如:

bytes=0-499                     从0到499的头500个字节

bytes=500-999                 从500到999的第二个500字节

bytes=500-                       从500字节以后的所有字节

bytes=-500                       最后500个字节

bytes=500-599,800-899   同时指定几个范围

也就是说,分段下载,就是发送多次多次请求,每次请求设置Range字段

下面的代码,完成一个文件的分段下载:

下面的代码,完成文件的一段下载:

使用异步下载时,应使用代理、通知、block进行下载后的处理动作。

  • NSURLSession的下载任务

下载任务的创建:

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL*)url
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL*)url completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL*location, NSURLResponse *response, NSError*error))completionHandler

NSURLSession执行下载任务相关的代理方法:

// 周期性的调用,参数描述了下载的进度
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask*)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
// 下载完成时调用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask*)downloadTask didFinishDownloadingToURL:(NSURL *)location

示例说明:

1)创建NSURLSession对象并指定代理

2)创建下载任务并启动

3)实现下载完成的代理方法:应将下载完成后的文件移动到指定目录并重命名

4)实现下载进度监听的代理方法:

  • 下载暂停/继续的实现

NSURLSessionDownloadTask的暂停方法:

- (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler

参数resumeData:描述断点信息

NSURLSession通过断点信息创建下载任务:

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeDatacompletionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError*error))completionHandler

相关代理方法:

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

实例说明:

1)下载暂停

2)下载继续

3)断点继续下载的代理方法

  • 使用AFNetworking下载

使用AFNetworking进行下载,本质上还是创建NSURLSessionDownloadTask对象

只是将代理方法的封装到AFURLSession对象中,并用block指定行为

AFURLSessionManager创建下载任务

// 根据请求对象创建下载任务
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request progress:(NSProgress *__nullable __autoreleasing *__nullable)progress destination:(nullable NSURL *( ^ ) ( NSURL *targetPath , NSURLResponse *response ))destination completionHandler:(nullable void ( ^ ) ( NSURLResponse *response , NSURL *filePath , NSError *error ))completionHandler
// 根据断点信息创建爱下载任务
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData progress:(NSProgress *__nullable __autoreleasing *__nullable)progress destination:(nullable NSURL *( ^ ) ( NSURL *targetPath , NSURLResponse *response ))destination completionHandler:(nullable void ( ^ ) ( NSURLResponse *response , NSURL *filePath , NSError *error ))completionHandler

参数destination:该block用于指定获取文件下载后的路径

参数completionHandler:该block在下载任务完成时执行

包括任务被暂停时(cancelByProducingResumeData)

出参progress:非NULL时,会返回一个NSProgress对象,描述下载进度

示例说明:

1)创建NSURLSession对象并指定代理

2)下载完成的block封装1:应返回下载完成的文件的最终存储URL

3)任务完成block封装:包括错误情况下的处理、成功请求下的提示等

4)下载任务的创建启动/继续

5)下载任务的暂停

  • 使用NSProgress监听下载进度

在上面的代码中,有一个参数NSProgress类型,传的是NULL,这个参数是AFN框架用于监听下载进度

NSProgress在iOS7.0引入,使用观察者模式

其fractionCompleted属性值变化时,通知其所有的观察者

示例说明:

1)下载任务的创建启动/继续

2)KVO的响应方法

其中self.progressView是一个自定义的用于显示下载进度的视图对象

  • 下载任务常遇状况

状况一:程序退出时,如何保存下载状态

下载任务管理类,注册成为以下UIApplication对象通知的响应者

UIApplicationDidEnterBackgroundNotification

UIApplicationWillTerminateNotification

响应方法实现:将所有的下载任务暂停,并将断点信息保存到本地的操作

响应下面通知,从本地读出断点信息的操作

UIApplicationWillEnterForegroundNotification

或在下载任务管理对象被创建时,从本地读出断点信息的操作

状况二:从断点继续下载时,如果服务器上的文件发生变化或被删除,应如何处理?

可以在从断点继续下载前,先发送一次HEAD请求,判断文件是否存在,以及该文件的长度是否发生变化等操作。

转载于:https://blog.51cto.com/annmeng/1746811

iOS网络开发(8)文件下载的实现相关推荐

  1. iOS网络开发中的同步、异步和请求队列

    在iOS网络编程中,我们经常会遇到线程的同步和异步问题,同时为了对异步请求更加精准丰富的控制,我们还常常在iOS中使用请求队列,下面就来谈谈iOS开发中同步.异步以及请求队列的使用方法. 1. 同步意 ...

  2. ios网络开发 网络状态检查

    http://www.cnblogs.com/hanjun/archive/2012/12/01/2797622.html 网络连接中用到的类: 一.Reachability 1.添加 Reachab ...

  3. iOS网络开发(5)请求的缓存

    有网络请求的App有可能出现两个问题: 1)遇到网络不畅或数据量较大的情况下,会出现由于数据到达不及时使用不流畅的问题 2)频繁发送网络请求,可能造成没必要的流量产生以及拖累手机速度的问题 针对问题一 ...

  4. IOS网络开发(一)

    1.1 问题 Socket的英文原义是孔或者插座的意思,通常也称作套接字,用于描述IP地址和端口,是一个通信链的句柄,本案例使用第三方Socket编程框架AsyncSocket框架实现一个简易的聊天工 ...

  5. iOS开发系列--网络开发(转)

    iOS开发系列--网络开发 2014-10-22 08:34 by KenshinCui, 66365 阅读, 56 评论, 收藏, 编辑 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微 ...

  6. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  7. iOS网络编程开发—HTTP协议

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

  8. iOS网络编程开发-数据加密

    iOS网络编程开发-数据加密 一.简单说明 1.说明 在开发应用的时候,数据的安全性至关重要,而仅仅用POST请求提交用户的隐私数据,还是不能完全解决安全问题. 如:可以利用软件(比如Charles) ...

  9. iOS网络高级编程:iPhone和iPad的企业应用开发之错误处理

    本章内容 ●    iOS应用中的网络错误源 ●    检测网络的可达性 ●    错误处理的经验法则 ●    处理网络错误的设计模式 到目前为止,我们所介绍的iPhone与其他系统的网络交互都是基 ...

最新文章

  1. 处理除第一个之外的所有参数(在bash脚本中)
  2. Caddy-基于go的微型serve用来做反向代理和Gateway
  3. ZOJ 3609 Modular Inverse(扩展欧几里得)题解
  4. PHP语言特性和各版本的差异
  5. 字符串处理分割字符串
  6. springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
  7. 深度学习总结:tensorflow和pytorch关于RNN的对比,tf.nn.dynamic_rnn,nn.LSTM
  8. (11) Hibernate 缓存机制
  9. mysql function函数_详解MySQL如何按表创建千万级的压测数据
  10. 【转】详细解析Java中抽象类和接口的区别
  11. Spring+jpaNo transactional EntityManager available
  12. 没学会python怎么学_恕我直言!这么久还没学会python,那是因为你还没有看过这本书...
  13. jQuery的几个例子流程讲解
  14. matlab实现贝叶斯,最简单的贝叶斯分类器MATLAB实现
  15. Unity 导航网格的使用
  16. 阿里云服务器安装MySql8.0.26
  17. android其实很简单 -- roaster 以代码构建代码
  18. VideoPose3D:基于视频的3D人体关键点检测
  19. 感知复合型人才的重要性!
  20. RedisTemplate hash操作如何使用string类型

热门文章

  1. TWaver Flex开发示例及license下载
  2. os-cocos2d游戏开发基础-进度条-开发笔记
  3. Silverlight 2.0 RTW 正式版发布(附下载地址)!
  4. 优雅的缓存解决方案--设置过期时间
  5. 在SpringBoot的Web项目中使用于Thymeleaf(二)
  6. 一文读懂MySQL事务锁、事务级别
  7. 数据库将某个字段由可为空改为非空
  8. 为什么windows系统能运行项目linux和Mac不行
  9. SpringMvc 3.x跨域+ajax请求
  10. HDU 4352 XHXJ#39;s LIS(数位dpamp;状态压缩)