美文网首页
iOS网络—NSURLSession文件下载

iOS网络—NSURLSession文件下载

作者: lionsom_lin | 来源:发表于2017-12-27 15:59 被阅读12次

    导语

    • 现在NSURLConnection在开发中会使用的越来越少,iOS9已经将NSURLConnection废弃,现在最低版本一般适配iOS7,所以也可以使用。
    • NSURLConnection相对于NSURLSession,安全性低。NSURLConnection下载有峰值,比较麻烦处理。
    • 尽管适配最低版本iOS7,也可以使用NSURLSessionAFN已经不支持NSURLConnection
    • NSURLSession:默认是挂起状态,如果要请求网络,需要开启。
    [NSURLSession sharedSession]获取全局的NSURLSession对象。在iPhone的所有app共用一个全局session.
    NSURLSessionUploadTask -> NSURLSessionDataTask -> NSURLSessionTask
    NSURLSessionDownloadTask -> NSURLSessionTask
    NSURLSessionDownloadTask下载,默认下载到tmp文件夹。下载完成后删除临时文件。所以我们要在删除文件之前,将它移动到Cache里。
    

    一、开启Mac本地Apache服务器

    开启Mac自带Apache服务器

    二、downloadTaskWithURL进行网络下载

        //1、url
        NSString *urlStr = @"http://127.0.0.1/下载视频.wmv";
        //1.1、url有中文,需要转码
        urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url  = [NSURL URLWithString: urlStr];
    
        /*
         如果在回调方法中,不做任何处理,下载的文件会被删除
         下载文件是默认下载到tmp文件夹,系统会自动回收这个区域
         
         设计目的:
         1.通常从网络下载文件,什么样的格式文件最多?zip
         2.如果是zip包,下载之后要解压
         3.解压之后,原始的zip就不需要了。系统会自动帮你删除
         */
        
        [[[NSURLSession sharedSession]downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"目录地址 == %@",location);
            
        }]resume];
    
    下载目录 进入tmp目录观察整个下载过程

    问题:
    1、无法知道下载进度;

    三、如何下载Zip文件并解压

    3.1、导入minizip库

    3.2、下载zip文件并解压

    流程 :
    1、如果在回调方法中,不做任何处理,下载的文件会被删除,由于下载文件默认下载到tmp文件夹,系统会自动回收这个区域;
    2、创建解压路径 ----- 不能指定目标文件。因为我们解压文件会产生多个文件;
    3、利用SSZipArchive进行解压;

        //1、url
        NSString *urlStr = @"http://127.0.0.1/AAA.zip";
        //1.1、url有中文,需要转码
        urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url  = [NSURL URLWithString: urlStr];
    
        /*
         如果在回调方法中,不做任何处理,下载的文件会被删除
         下载文件是默认下载到tmp文件夹,系统会自动回收这个区域
         
         设计目的:
         1.通常从网络下载文件,什么样的格式文件最多?zip
         2.如果是zip包,下载之后要解压
         3.解压之后,原始的zip就不需要了。系统会自动帮你删除
         */
        [[[NSURLSession sharedSession]downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
            NSLog(@"%@",location);
            
            //文件解压目标路径,不能指定目标文件。因为我们解压文件会产生多个文件
            NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
    
            [SSZipArchive unzipFileAtPath:location.path toDestination:cachePath];
    
        }]resume];
    

    结果:

    根据下载路径进入查看 Cache文件夹中解压的文件

    四、添加进度条 -- Delegate

    如果你要监听下载进度,必须使用代理。就不能block 。
    [NSURLSession sharedSession] 是全局的单例。在iPhone的所有app共用一个全局session。所以需要自定义;

    // 懒加载
    -(NSURLSession *)session
    {
        if (_session == nil) {
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
        }
        return _session;
    }
    
    Delegate
    #pragma mark --NSURLSessionDelegate
    
    //下载完成
    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
    {
        NSLog(@"下载完成!");
    }
    
    //2下载进度
    /*
     session :
     downloadTask :调用代理方式的下载任何
     bytesWritten:本次下载的字节数
     totalBytesWritten:已经下载的字节数
     totalBytesExpectedToWrite:期望下载的字节数————文件总大小
     */
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten  totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    
        float progress = (float)totalBytesWritten /totalBytesExpectedToWrite;
        NSLog(@"%f",progress);
        
        NSLog(@"%@",[NSThread currentThread]);
        //默认开启在子线程,需要回到主线程刷新页面
        dispatch_async(dispatch_get_main_queue(), ^{
            self.progressView.progress = progress;
        });
    }
    

    五、断点续传

    
    -(void)startBtnCallBack {
        NSLog(@"start!");
        NSString *urlStr = @"http://127.0.0.1/下载视频.wmv";
        //1.1、url有中文,需要转码
        urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url  = [NSURL URLWithString: urlStr];
        
        //如果你要监听下载进度,必须使用代理。
        //[NSURLSession sharedSession] 是全局的单例。整个系统å
        //如果你要更进下载进度,就不能block
        self.downloadTask =  [self.session downloadTaskWithURL:url];
        [self.downloadTask resume];
    }
    
    -(void)pauseBtnCallBack {
        NSLog(@"暂停!");
        [self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            
            NSLog(@"数据的长度是:%tu",resumeData.length);
            self.resumeData = resumeData;
            
            //释放任务
            self.downloadTask = nil;
        }];
    }
    
    -(void)resumeBtnCallBack {
        NSLog(@"resume");
        if (_resumeData == nil) {
            return;
        }
        self.downloadTask =  [self.session downloadTaskWithResumeData:self.resumeData];
        self.resumeData = nil;
        [self.downloadTask resume];
    }
    

    六、NSURLSession强引用问题

    NSURLSession是强引用,即使下载完成,session依旧存在,会造成内存泄露;

    解决方案

    //未完成下载,直接取消
      [self.session invalidateAndCancel];
      self.session = nil;
    
    // 完成下载,取消
      [self.session finishTasksAndInvalidate];
      self.session = nil;
    

    如何查看是否内存泄露

    -(void)dealloc
    {
        NSLog(@"走了!");
    }
    

    基本完成!!

    相关文章

      网友评论

          本文标题:iOS网络—NSURLSession文件下载

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