下载文件到NSURLConnectionNSURLSession两种,一种有恨悠久的历史了。

使用相对麻烦,后者是新出来的,添加了一些额外的功能。

一、NSURLConnection实现下载

TIPS:

1、当NSURLConnection下载时,得到的NSData写入文件时,data并没有占用多大内存. (即使文件非常大)
2、一点点在传. 做的是磁盘缓存.而不是内存缓存机制。

3、了解在NSURLConnection上加代理。

[consetDelegateQueue:[[NSOperationQueuealloc]init]]

4、NSURLResponse记录的了url, mineType, exceptedContentLength, suggestedFileName等属性.
下载时用得着.  

下面程序实现追踪下载百分比的下载(URLConnection自带的方法):

  1. #import "XNDownload.h"
  2.  
  3. typedef void(^ProgressBlock)(float percent);
  4.  
  5. @interface XNDownload() <NSURLConnectionDataDelegate>
  6.  
  7. @property (nonatomic, strong) NSMutableData *dataM;
  8.  
  9. // 保存在沙盒中的文件路径
  10. @property (nonatomic, strong) NSString *cachePath;
  11. // 文件总长度
  12. @property (nonatomic, assign) long long fileLength;
  13. // 当前下载的文件长度
  14. @property (nonatomic, assign) long long currentLength;
  15.  
  16. // 回调块代码
  17. @property (nonatomic, copy) ProgressBlock progress;
  18.  
  19. @end
  20.  
  21. @implementation XNDownload
  22.  
  23. - (NSMutableData *)dataM
  24. {
  25. if (!_dataM) {
  26. _dataM = [NSMutableData data];
  27. }
  28. return _dataM;
  29. }
  30.  
  31. - (void)downloadWithURL:(NSURL *)url progress:(void (^)(float))progress
  32. {
  33. // 0. 记录块代码
  34. self.progress = progress;
  35.  
  36. // 1. request GET
  37. NSURLRequest *request = [NSURLRequest requestWithURL:url];
  38.  
  39. // 2. connection
  40. NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
  41.  
  42. // 让connection支持多线程。指定代理的工作队列就可以
  43. // NSURLConnection在执行时,执行循环不负责监听代理的详细执行
  44. [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
  45.  
  46. // 3. 启动连接
  47. [connection start];
  48. }
  49.  
  50. #pragma mark - 代理方法
  51. // 1. 接收到server的响应。server执行完请求,向client回传数据
  52. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  53. {
  54. NSLog(@"%@ %lld", response.suggestedFilename, response.expectedContentLength);
  55. // 1. 保存的缓存路径
  56. NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
  57. self.cachePath = [cachePath stringByAppendingPathComponent:response.suggestedFilename];
  58. // 2. 文件总长度
  59. self.fileLength = response.expectedContentLength;
  60. // 3. 当前下载的文件长度
  61. self.currentLength = 0;
  62.  
  63. // 清空数据
  64. [self.dataM setData:nil];
  65. }
  66.  
  67. // 2. 接收数据。从server接收到数据
  68. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  69. {
  70. // 拼接数据
  71. [self.dataM appendData:data];
  72.  
  73. // 依据data的长度添加当前下载的文件长度
  74. self.currentLength += data.length;
  75.  
  76. float progress = (float)self.currentLength / self.fileLength;
  77.  
  78. // 推断是否定义了块代码
  79. if (self.progress) {
  80. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  81. // 强制执行循环执行一次更新
  82. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
  83.  
  84. self.progress(progress);
  85. }];
  86. }
  87. }
  88.  
  89. // 3. 完毕接收
  90. - (void)connectionDidFinishLoading:(NSURLConnection *)connection
  91. {
  92. NSLog(@"%s %@", __func__, [NSThread currentThread]);
  93. // 将dataM写入沙盒的缓存文件夹
  94. // 写入数据,NSURLConnection底层实现是用磁盘做的缓存
  95. [self.dataM writeToFile:self.cachePath atomically:YES];
  96. }
  97.  
  98. // 4. 出现错误
  99. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
  100. {
  101. NSLog(@"%@", error.localizedDescription);
  102. }
  103.  
  104. @end

二、NSURLSession实现下载

NSURLSession能实现断点续传,暂停下载等功能。

1、session提供的是开了多个线程的异步下载.
2、下载的暂停与续传: (session的代理中的方法)
*弄一个NSData变量来保存下载东西.暂停时将下载任务task清空.
*续传:将暂停时的data交给session继续下载,并将先前的data清空.
3、task一定要resume才開始运行.
  1. #import "XNViewController.h"
  2.  
  3. @interface XNViewController () <NSURLSessionDownloadDelegate>
  4.  
  5. // 下载网络回话
  6. @property (nonatomic, strong) NSURLSession *session;
  7. // 下载任务
  8. @property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
  9. // 续传的二进制数据
  10. @property (nonatomic, strong) NSData *resumeData;
  11. @end
  12.  
  13. @implementation XNViewController
  14.  
  15. - (NSURLSession *)session
  16. {
  17. if (!_session) {
  18. NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
  19. _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
  20. }
  21. return _session;
  22. }
  23.  
  24. - (void)viewDidLoad
  25. {
  26. [super viewDidLoad];
  27.  
  28. [self downloadFile];
  29. }
  30.  
  31. // 暂停下载任务
  32. - (IBAction)pause
  33. {
  34. // 假设下载任务不存在,直接返回
  35. if (self.downloadTask == nil) return;
  36.  
  37. // 暂停任务(块代码中的resumeData就是当前正在下载的二进制数据)
  38. // 停止下载任务时,须要保存数据
  39. [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {
  40. self.resumeData = resumeData;
  41.  
  42. // 清空而且释放当前的下载任务
  43. self.downloadTask = nil;
  44. }];
  45. }
  46.  
  47. - (IBAction)resume
  48. {
  49. // 要续传的数据是否存在?
  50. if (self.resumeData == nil) return;
  51.  
  52. // 建立续传的下载任务
  53. self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
  54. [self.downloadTask resume];
  55.  
  56. // 将此前记录的续传数据清空
  57. self.resumeData = nil;
  58. }
  59.  
  60. // 假设在开发中使用到缓存文件夹,一定要提供一个功能,“清除缓存”。
  61. /** 下载文件 */
  62. - (void)downloadFile
  63. {
  64. NSString *urlStr = @"http://localhost/苍老师全集.rmvb";
  65. urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  66.  
  67. NSURL *url = [NSURL URLWithString:urlStr];
  68.  
  69. // (1) 代理 & 直接启动任
  70. // 2. 启动下载任务
  71. self.downloadTask = [self.session downloadTaskWithURL:url];
  72.  
  73. [self.downloadTask resume];
  74. }
  75.  
  76. #pragma mark - 下载代理方法
  77. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
  78. {
  79. NSLog(@"完毕 %@ %@", location, [NSThread currentThread]);
  80. }
  81.  
  82. /**
  83. bytesWritten : 本次下载的字节数
  84. totalBytesWritten : 已经下载的字节数
  85. totalBytesExpectedToWrite : 下载总大小
  86. */
  87. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
  88. {
  89. float progress = (float)totalBytesWritten / totalBytesExpectedToWrite;
  90.  
  91. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  92. //主线程中更新进度UI操作。。。。
  93. }];
  94. }
  95.  
  96. /** 续传的代理方法 */
  97. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
  98. {
  99. NSLog(@"offset : %lld", fileOffset);
  100. }
  101.  
  102. @end

出处:http://blog.csdn.net/xn4545945

版权声明:本文博主原创文章。博客,未经同意不得转载。

【iOS】文件下载小记的更多相关文章

  1. iOS 文件下载

    iOS 视频音乐类等应用会用到“文件下载”.文件下载在iOS中的实现如下: 1.小文件下载 @interface ViewController () <NSURLConnectionDataDe ...

  2. IOS知识小记

    iOS开发 小知识点 http://www.cnblogs.com/tangbinblog/archive/2012/07/20/2601324.html Objective-C中的instancet ...

  3. iOS 文件下载及断点续传

    ios的下载我们可以使用的方法有:NSData.NSURLConnection.NSURLSession还有第三方框架AFNetworking和ASI 利用NSData方法和NSURLConnecti ...

  4. 【转】iOS 文件下载及断点续传

    ios的下载我们可以使用的方法有:NSData.NSURLConnection.NSURLSession还有第三方框架AFNetworking和ASI 利用NSData方法和NSURLConnecti ...

  5. IOS开发小记-内存管理

    关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...

  6. iOS 文件下载和打开

    最近的项目要用到一个在线报告的下载,于是完成后自己在理一下思路,大体的实现了我要得需求. 话不多说,直接上代码 首先,取到网络文件的链接,进行判段是否需求再次下载还是直接打开 #pragma mark ...

  7. ios碎片小记

    一.UIImageView 1.图片形状设为圆形时可能会由于图片的宽高比例导致显示出来的效果不是圆形 解决:设置UIImageView的contentMode为UIViewContentModeSca ...

  8. IOS文件下载

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask, ...

  9. iOS - NetRequest 网络数据请求

    1.网络请求 1.1 网络通讯三要素 1.IP 地址(主机名): 网络中设备的唯一标示.不易记忆,可以用主机名(域名). 1) IP V4: 0~255.0~255.0~255.0~255 ,共有 2 ...

随机推荐

  1. 基于visual Studio2013解决面试题之0709求方

     题目

  2. 9、Cocos2dx 3.0游戏开发三查找值小工厂方法模式和对象

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 工厂方法模式 工厂方法是程序设计中一个 ...

  3. Net Core-Razor

    几行代码解决Razor中的嵌套if语句 MVC开发中,经常会遇到在razor中插入简单的逻辑判断. @if (clientManager.IsAdmin) { if (!Model.Topic.Top ...

  4. TensorFlow实现与优化深度神经网络

    TensorFlow实现与优化深度神经网络 转载请注明作者:梦里风林Github工程地址:https://github.com/ahangchen/GDLnotes欢迎star,有问题可以到Issue ...

  5. 通过程序预览Office文档

    我承认,标题是夸大了,就是为了吸引注意力.这里只有Word文档和Excel文档的预览代码. Word://此部分来源:http://princed.mblogger.cn/posts/11885.as ...

  6. jvm常用参数设置 good

    1.堆的大小可以通过 -Xms 和 -Xmx 来设置,一般将他们设置为相同的大小,目的是避免在每次垃圾回收后重新调整堆的大小,比如 -Xms=2g -Xmx=2g 或者 -Xms=512m -Xmx= ...

  7. 编译Boost 详细步骤 适用 VC6 VS2003 VS2005 VS2008 VS2010

    vs2008编译boost [一.Boost库的介绍] Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库 ...

  8. CListCtrl插入数据避免闪烁

    1.锁定窗口,不进行刷新 m_list.LockWindowUpdate(); 2.设定列表不进行重画 m_list.SetRedraw(FALSE); 3.清空列表,删除历史数据 m_list.De ...

  9. Datatable.Compute小技巧

    在个人版机房重构的过程中,大家最发愁的一件事无非就是上下机,结账和报表.那么在结账的过程中,最发愁的是否就数计算日结账单的数据和周结账的数据.还记得在第一遍机房收费系统的过程中用的是for 循环,但是 ...

  10. MFC 直线 虚线 折线 圆 椭圆 矩形 弧形

    ****Dlg.h头文件加入: //为project加入画笔.点变量数组 public: CPen m_pen[5]; CPoint m_point[5]; public: void DrawLine ...