美文网首页网络
NSURLConnectionDataDelegate 简介

NSURLConnectionDataDelegate 简介

作者: 派大星的博客 | 来源:发表于2018-09-22 18:54 被阅读35次
网络下载示意图.png
/*
 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的内容,给客户端一个准备

状态行&响应头.png

NSURLConnectionDownloadDelegate

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

相关文章

网友评论

    本文标题:NSURLConnectionDataDelegate 简介

    本文链接:https://www.haomeiwen.com/subject/bquxoftx.html