iOS网络—NSURLSession文件下载

导语

  • 现在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];
下载目录
iOS网络—NSURLSession文件下载_第1张图片
进入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];

结果:

根据下载路径进入查看
iOS网络—NSURLSession文件下载_第2张图片
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文件下载)