【待整理】IOS开发之下载
一、传统的下载文件的方式
- (void)downloaderWithUrl:(NSURL *)url { NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (!connectionError) { NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *)response; if (urlResponse.statusCode == 200 || urlResponse.statusCode == 304) { [data writeToFile:@"/Users/gxiangzi/Desktop/a.mp4" atomically:YES]; NSLog(@"OK"); } }else { NSLog(@"错误"); } }]; }
但是这种方式存在着弊端:
1> 用不无法跟踪下载的进度,无法直观的显示下载进度
2> 文件下载的时候,都会先下载到内存之中,导致内存 > 所需文件的大小长度,会造成程序崩溃等现象(可以查看内存的耗费)
二、代理的方式下载程序(NSURLConnectionDownloadDelegate)
#import "GXDownloader.h" @interface GXDownloader () <NSURLConnectionDownloadDelegate> @end @implementation GXDownloader - (void)downloaderWithUrl:(NSURL*)url { NSURLRequest* request = [NSURLRequest requestWithURL:url]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; } #pragma mark - NSURLConnectionDownloadDelegate /** bytesWritten: 表示下载的数据字节数 totalBytesWritten:总的已经下载的字节数 expectedTotalBytes:期望的总的字节数 */ - (void)connection:(NSURLConnection*)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes { float progress = (float)totalBytesWritten / expectedTotalBytes; NSLog(@"%f", progress); } /** * @param connection * @param totalBytesWritten : 总的已经下载的字节数 * @param expectedTotalBytes : 期望总的字节数 */ - (void)connectionDidResumeDownloading:(NSURLConnection*)connection totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes { } /** * @param connection * @param destinationURL:下载完的目标路径 */ - (void)connectionDidFinishDownloading:(NSURLConnection*)connection destinationURL:(NSURL*)destinationURL { NSLog(@"%@", destinationURL); }
优点:
1> 该种方式可以跟踪文件下载的进度;
2> 也可以解决内存消耗过大的问题
弊端: 这丫的 下载的文件没有 ,就是虽然你显示下载完成,但是你本地找不到该文件------没有任何卵用
三、第三种方式--代理(NSURLConnectionDataDelegate)
// // GXDownloader.m // 02-下载 // // Created by gxiangzi on 15/8/21. // Copyright (c) 2015年 hqu. All rights reserved. // #import "GXDownloader.h" @interface GXDownloader () <NSURLConnectionDataDelegate> // 文件的总长度 @property (nonatomic, assign) long long expectedContentLength; // 已经接受到文件的长度 @property (nonatomic, assign) long long receivedContentLength; // 已经接收到的文件的总长度 @property (nonatomic, strong) NSMutableData* receivedData; @end @implementation GXDownloader - (void)downloaderWithUrl:(NSURL*)url { NSURLRequest* request = [NSURLRequest requestWithURL:url]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; } #pragma mark - NSURLConnectionDataDelegate /** * 已经接受到响应头 */ - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response { self.expectedContentLength = response.expectedContentLength; } /** * 文件接受到一点的时候就是用 */ - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { // 把二进制数据进行拼接 [self.receivedData appendData:data]; // 拼接长度 self.receivedContentLength += data.length; float progress = (float)self.receivedContentLength / self.expectedContentLength; NSLog(@"下载进度: %.2f",progress); } /** * 下载出错的时候调用 */ - (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error { } /** * 当下载完成的时候调用 */ - (void)connectionDidFinishLoading:(NSURLConnection*)connection { NSLog(@"下载完成"); // IOS 的文件路径,只能讲软件操作的数据放在沙盒内 NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *fileName = [path stringByAppendingPathComponent:@"love.mp4"]; NSLog(@"%@",fileName); [self.receivedData writeToFile:fileName atomically:YES]; } #pragma mark -懒加载 - (NSMutableData*)receivedData { if (!_receivedData) { _receivedData = [NSMutableData data]; } return _receivedData; } @end
优点:
1> 可以检测到进度的问题
2> 文件的写入的路径之中,文件可以存在
弊端:
占用的内存太大
为了解决上面的问题: 引入了NSHandle 和 NSOutputStream ------下一点 写入文件一点
四、NSHandle的使用
// // GXDownloader.m // 02-下载 // // Created by gxiangzi on 15/8/21. // Copyright (c) 2015年 hqu. All rights reserved. // #import "GXDownloader.h" @interface GXDownloader () <NSURLConnectionDataDelegate> // 文件的总长度 @property (nonatomic, assign) long long expectedContentLength; // 已经接受到文件的长度 @property (nonatomic, assign) long long receivedContentLength; @end @implementation GXDownloader - (void)downloaderWithUrl:(NSURL*)url { NSURLRequest* request = [NSURLRequest requestWithURL:url]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; } #pragma mark - NSURLConnectionDataDelegate /** * 已经接受到响应头 */ - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response { self.expectedContentLength = response.expectedContentLength; } /** * 文件接受到一点的时候就是用 */ - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { // 拼接长度 self.receivedContentLength += data.length; float progress = (float)self.receivedContentLength / self.expectedContentLength; NSLog(@"%f",progress); NSString* path = @"/Users/gxiangzi/Desktop/a.mp4"; NSFileHandle* handle = [NSFileHandle fileHandleForWritingAtPath:path]; // 如果handle 不会帮我们创建文件 if (handle == nil) { [data writeToFile:path atomically:YES]; } else { //让offset指向文件的末尾,在末尾处追加数据 [handle seekToEndOfFile]; //写输入 [handle writeData:data]; //关闭 (等文件下载完成关闭更好) [handle closeFile]; } } /** * 当下载完成的时候调用 */ - (void)connectionDidFinishLoading:(NSURLConnection*)connection { NSLog(@"下载完成"); } @end
原理:下载一点数据 写一点数据
效果:能够达到占用很少内存
五、NSOutputStream的使用
// // GXDownloader.m // 02-下载 // // Created by gxiangzi on 15/8/21. // Copyright (c) 2015年 hqu. All rights reserved. // #import "GXDownloader.h" @interface GXDownloader () <NSURLConnectionDataDelegate> // 文件的总长度 @property (nonatomic, assign) long long expectedContentLength; // 已经接受到文件的长度 @property (nonatomic, assign) long long receivedContentLength; @property (nonatomic, strong) NSOutputStream* stream; @end @implementation GXDownloader - (void)downloaderWithUrl:(NSURL*)url { NSURLRequest* request = [NSURLRequest requestWithURL:url]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; } #pragma mark - NSURLConnectionDataDelegate /** * 已经接受到响应头 */ - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response { self.expectedContentLength = response.expectedContentLength; NSString* path = @"/Users/gxiangzi/Desktop/a.mp4"; // 注意 此处的url 为本地的路径 // 前面加 file:// 无效 // 只能使用 [NSURL fileURLWithPath:path] self.stream = [NSOutputStream outputStreamWithURL:[NSURL fileURLWithPath:path] append:YES]; [self.stream open]; } /** * 文件接受到一点的时候就是用 */ - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { // 拼接长度 self.receivedContentLength += data.length; float progress = (float)self.receivedContentLength / self.expectedContentLength; NSLog(@"%f", progress); [self.stream write:data.bytes maxLength:data.length]; } /** * 当下载完成的时候调用 */ - (void)connectionDidFinishLoading:(NSURLConnection*)connection { NSLog(@"下载完成"); [self.stream close]; } - (NSOutputStream *)stream { if (_stream == nil) { _stream = [[NSOutputStream alloc] init]; } return _stream; } @end
【待整理】IOS开发之下载的更多相关文章
- 整理iOS开发常用的第三方资源
一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:hud提示框 地址:https://github. ...
- [整理]iOS开发学习
最近想趁着休假,花点时间了解下最新的iOS8下的新特性以及Swift语言(想大致了解下和Objective-C有了哪些改进和不同) 可以通过Chris Lattner:Swift 编程语言首席架构师初 ...
- 李洪强iOS开发之下载
// // // LHQDownLoader.m // A21 - 李洪强 - 下载 // // Created by vic fan on 16/7/3. // Copyright © 20 ...
- iOS开发--网络下载
这里使用的是NSURLConnection的代理请求下载,并且是具有进度,UI能实时刷新,至于NSURLConnection如何请求.并且有几种请求方法请看NSURLConnection请求简介,在这 ...
- IOS开发-phonegap及免证书及真机调试
回头补记(Last edited at 2015.5.24). 第一步:建立项目 参见:Xcode5 + phoneGap2.9搭建ios开发环境 下载phonegap2.9.1,解压. 命令行,进入 ...
- 文顶顶iOS开发博客链接整理及部分项目源代码下载
文顶顶iOS开发博客链接整理及部分项目源代码下载 网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程 ...
- 【热门收藏】iOS开发人员必看的精品资料(100个)——下载目录
iPhone.iPad产品风靡全球,巨大的用户群刺激着iOS软件开发需求,然而国内人才缺口很大,正处于供不应求的状态,ios开发前景大好.我们整理了51CTO下载中心100份热门的ios开发资料,做了 ...
- iOS 开发设计常用软件及工具整理
1, xCode 2, AppCode 3, Skech 原型设计软件 4, Hype 动画设计工具 5, fontawsome 免费图表 6, Prepo icon, images.catlog 生 ...
- iOS开发使用半透明模糊效果方法整理
虽然iOS很早就支持使用模糊效果对图片等进行处理,但尤其在iOS7以后,半透明模糊效果得到大范围广泛使用.包括今年最新发布的iOS8也沿袭了这一设计,甚至在OS X 10.10版Yosemite中也开 ...
随机推荐
- 云风:我所偏爱的C语言面向对象编程范式
面向对象编程不是银弹.大部分场合,我对面向对象的使用非常谨慎,能不用则不用.相关的讨论就不展开了. 但是,某些场合下,采用面向对象的确是比较好的方案.比如 UI 框架,又比如 3d 渲染引擎中的场景管 ...
- 使用AlarmManager进行定时任务处理
1:UploadingService.java package com.example.service; import com.example.broadcast.AlarmReceiver; imp ...
- BZOJ 1068 (区间DP)
题意:字符串的压缩,f[l][r][0]代表还没M,f[l][r][1]代表有M. #include<cstdio> #include<cmath> #include<c ...
- 转:关于rename命令ubuntu下的用法
下面是我的遭遇:上午想批量改几个文件的名字,觉得mv在批量方面不够方便,百度到了rename这个命令,原谅我吧,我总是在百度不到结果时才去看google,以后还是少去百度的好国内很多贴子都在说linu ...
- java设计模式--结构型模式--享元模式
享元模式 概述 运用共享技术有效地支持大量细粒度的对象. 适用性 当都具备下列情况时,使用Flyweight模式: 1.一个应用程序使用了大量的对象. 2.完全由于使用大量的对象,造成很大的存储开销. ...
- 漏洞:WebRTC 泄漏用户IP
WebRTC又称为“网页即时通信”,是一组API函数,它经过W3C组织的认证,支持浏览器之间的语音通话.视频聊天和P2P模式分享文件. 这个协议主要包括:getUserMedia,RTCPe ...
- Java宝典(一)
-switch语句能作用在byte上,能否作用在long上,能否作用在String上? -在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量,整数表达式可以是int基本类型或I ...
- Thinkphp多表联查mysql写法
$model=M("user","","mysql://root:222222@localhost:3306/jiaoyou"); //换数 ...
- (转)25个增强iOS应用程序性能的提示和技巧--中级篇
在性能优化时,当你碰到一些复杂的问题,应该注意和使用如下技巧: 9.重用和延迟加载View10.缓存.缓存.缓存11.考虑绘制12.处理内存警告13.重用花销很大的对象14.使用Sprite Shee ...
- POJ 3114 Countries in War(强连通+最短路)
POJ 3114 Countries in War 题目链接 题意:给定一个有向图.强连通分支内传送不须要花费,其它有一定花费.每次询问两点的最小花费 思路:强连通缩点后求最短路就可以 代码: #in ...