NSURLSession实现断点续传

NSURLSession VS NSURLConnection  
NSURLSession可以看做是NSURLConnection的进化版,其对NSURLConnection的改进点有: 

  • * 根据每个Session做配置(http header,Cache,Cookie,protocal,Credential),不再在整个App层面共享配置.
  • * 支持网络操作的取消和断点续传
  • * 改进了授权机制的处理
  • * 丰富的Delegate模型
  • * 分离了真实数据和网络配置数据。
  • * 后台处理上传和下载,即使你点击了“Home”按钮,后台仍然可以继续下载,并且提供了根据网络状况,电力情况进行处理的配置。

用法  
使用NSURLSession的一般套路如下: 
  • 1. 定义一个NSURLRequest
  • 2. 定义一个NSURLSessionConfiguration,配置各种网络参数
  • 3. 使用NSURLSession的工厂方法获取一个所需类型的NSURLSession
  • 4. 使用定义好的NSURLRequest和NSURLSession构建一个NSURLSessionTask
  • 5. 使用Delegate或者CompletionHandler处理任务执行过程的所有事件。

实战  

这儿我简单的实现了一个下载任务的断点续传功能,具体实现代码如下:

-(NSURLSession *)session{

    if(_session == nil){

        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

        _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

    }

    return _session;

}


-(NSURLRequest *)request{

    if(_request == nil){

        NSURL *url = [NSURL URLWithString:@"http://p1.pichost.me/i/40/1639665.png"];

        _request = [NSURLRequest requestWithURL:url];

    }

    return _request;

}

-(void)startAction{

    if(self.isLoading){

        NSLog(@"loading...");

        return;

    }

    

    NSLog(@"start download task");

    

    self.task = [self.session downloadTaskWithRequest:self.request];

    [self.task resume];

}


-(void)pauseAction{

    if(_task){

        NSLog(@"pause download task");

        

        //取消下载任务,把已下载数据保存起来

       [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {

           self.imgData = resumeData;

           self.task = nil;

       }];

    }

}


-(void)resumeAction{

    if(!_task){

        NSLog(@"resume download task");

        

        //判断是否有已下载数据,有则直接断点续传,没有则重新下载

        if(self.imgData){

            self.task = [self.session downloadTaskWithResumeData:self.imgData];

        }else{

            self.task = [self.session downloadTaskWithRequest:self.request];

        }

        [self.task resume];

    }

}


#pragma mark delegate

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{

    //下载成功后,文件是保存在一个临时目录的,需要开发者自己考到放置该文件的目录

    NSLog(@"Download success for URL: %@",location.description);

    NSURL *destination = [self createDirectoryForDownloadItemFromURL:location];

    BOOL success = [self copyTempFileAtURL:location toDestination:destination];

    

    if(success){

        //        文件保存成功后,使用GCD调用主线程把图片文件显示在UIImageView

        dispatch_async(dispatch_get_main_queue(), ^{

            UIImage *image = [UIImage imageWithContentsOfFile:[destination path]];

            self.imgView.image = image;

            self.imgView.contentMode = UIViewContentModeScaleAspectFit;

        });

    }else{

        NSLog(@"Meet error when copy file");

    }

    self.task = nil;

}


/* Sent periodically to notify the delegate of download progress. */

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask

      didWriteData:(int64_t)bytesWritten

 totalBytesWritten:(int64_t)totalBytesWritten

totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

{

    //刷新进度条的delegate方法,同样的,获取数据,调用主线程刷新UI

    double currentProgress = totalBytesWritten/(double)totalBytesExpectedToWrite;

    dispatch_async(dispatch_get_main_queue(), ^{

        self.infoLabel.text = [NSString stringWithFormat:@"进度: %.2f%%", currentProgress];

    });

}


//创建文件本地保存目录

-(NSURL *)createDirectoryForDownloadItemFromURL:(NSURL *)location

{

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];

    NSURL *documentsDirectory = urls[0];

    return [documentsDirectory URLByAppendingPathComponent:[location lastPathComponent]];

}


//把文件拷贝到指定路径

-(BOOL) copyTempFileAtURL:(NSURL *)location toDestination:(NSURL *)destination

{

    NSError *error;

    NSFileManager *fileManager = [NSFileManager defaultManager];

    [fileManager removeItemAtURL:destination error:NULL];

    [fileManager copyItemAtURL:location toURL:destination error:&error];

    if (error == nil) {

        return true;

    }else{

        NSLog(@"%@",error);

        return false;

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值