
/*
NSURLConnectionDownloadDelegate 千万不要用!!! 专门针对杂志的下载提供的接口
如果在开发中使用DownloadDelegate 下载.能够监听下载进度,但是无法拿到下载文件!
Newsstand Kit’s 专门用来做杂志!!!
*/
@interface ViewController ()<NSURLConnectionDataDelegate>
/** 要下载文件的总大小 */
@property(assign,nonatomic)long long expectedContentLength;
/** 当前下载的长度 */
@property(assign,nonatomic)long long currentLength;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
/*
问题:
1.没有下载进度 ,会影响用户体验
2.内存偏高,有一个最大峰值:
解决办法:
- 通过代理方式来解决!!
1.进度跟进!
- 在响应方法中获得文件总大小!
- 每次接收到数据,计算数据的总比例!
2.保存文件的思路?
- 保存完成写入磁盘
测试结果:和异步方法执行的效果一样.仍然存在内存问题!
推测:苹果的异步方法的实现思路.就是刚才我们的实现思路!!
- 边下载,边写
1.NSFileHandle 测地解决了内存峰值的问题!
2.NSOutputStream 输出流
*/
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//1.url
NSString * urlStr = @"http://localhost/demo.mp4";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL * url = [NSURL URLWithString:urlStr];
//2.request
NSURLRequest * request = [NSURLRequest requestWithURL:url];
//3.connection
NSLog(@"开始");
NSURLConnection * conn = [NSURLConnection connectionWithRequest:request delegate:self];
//启动连接
[conn start];
}
#pragma mark - <NSURLConnectionDataDelegate>
//1.接受到服务器的响应 - 状态行&响应头 - 做一些准备工作
//expectedContentLength 需要下载文件的总大小 long long
//suggestedFilename 服务器建议保存的文件名称
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"%@",response);
//记录文件总大小
self.expectedContentLength = response.expectedContentLength;
self.currentLength = 0;
}
//2.接受到服务器的数据 - 此代理方法可能会执行很多次!! 因为拿到多个data
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
self.currentLength += data.length;
//计算百分比
// progress = long long / long long
float progress = (float)self.currentLength / self.expectedContentLength;
NSLog(@"%f",progress);
//拼接数据
[self writeToFileWithData:data];
}
// 边下载 边写入
-(void)writeToFileWithData:(NSData *)data{
/*
NSFileManager: 主要功能,创建目录,检查目录是否存在,遍历目录,删除文件.. 针对文件操作!! Finder
NSFileHandle: 文件"句柄"(文件指针),Handle
意味着是对前面的单词的"File"操作,
主要功能,就是对同一个文件进行二进制的读和写!
*/
//注意: 如果文件不存在,fp 在实例化的结果是空
NSFileHandle * fp = [NSFileHandle fileHandleForWritingAtPath:self.tartgetFilePath];
//判断文件是否存在 - 如果文件不存在,直接将数据写入磁盘!
if (fp == nil) {
[data writeToFile:self.tartgetFilePath atomically:YES];
}else{
//1.将文件指针移动到文件的末尾!!
[fp seekToEndOfFile];
//2.写入文件
[fp writeData:data];
//3.关闭文件,在c语言的开发中,凡是涉及到文件读.写 打开和关闭的操作!!
[fp closeFile];
}
}
//3.所有的数据加载完毕 - 所有数据都传输完毕,只是一个最后的通知
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"完毕");
}
//4.下载失败或者错误
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
@end
didReceiveResponse的内容,给客户端一个准备

NSURLConnectionDownloadDelegate
千万不要用!!! 专门针对杂志的下载提供的接口
如果在开发中使用DownloadDelegate 下载.能够监听下载进度,但是无法拿到下载文件!
Newsstand Kit’s 专门用来做杂志!!!
网友评论