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 = [NSURLSessionConfigurationdefaultSessionConfiguration];

       _session= [NSURLSessionsessionWithConfiguration:configdelegate:selfdelegateQueue:nil];

    }

   return_session;

}


-(NSURLRequest*)request{

   if(_request==nil){

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

       _request= [NSURLRequestrequestWithURL:url];

    }

   return_request;

}

-(void)startAction{

   if(self.isLoading){

       NSLog(@"loading...");

       return;

    }

    

   NSLog(@"start download task");

    

   self.task= [self.sessiondownloadTaskWithRequest:self.request];

    [self.taskresume];

}


-(void)pauseAction{

   if(_task){

       NSLog(@"pause download task");

        

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

       [self.taskcancelByProducingResumeData:^(NSData*_NullableresumeData) {

          self.imgData= resumeData;

          self.task=nil;

       }];

    }

}


-(void)resumeAction{

   if(!_task){

       NSLog(@"resume download task");

        

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

       if(self.imgData){

           self.task= [self.sessiondownloadTaskWithResumeData:self.imgData];

        }else{

           self.task= [self.sessiondownloadTaskWithRequest:self.request];

        }

        [self.taskresume];

    }

}


#pragma mark delegate

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

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

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

   NSURL*destination = [selfcreateDirectoryForDownloadItemFromURL:location];

   BOOLsuccess = [selfcopyTempFileAtURL:locationtoDestination:destination];

    

   if(success){

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

       dispatch_async(dispatch_get_main_queue(), ^{

           UIImage*image = [UIImageimageWithContentsOfFile:[destinationpath]];

           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

   doublecurrentProgress = totalBytesWritten/(double)totalBytesExpectedToWrite;

   dispatch_async(dispatch_get_main_queue(), ^{

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

    });

}


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

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

{

   NSFileManager*fileManager = [NSFileManagerdefaultManager];

   NSArray*urls = [fileManagerURLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask];

   NSURL*documentsDirectory = urls[0];

   return[documentsDirectoryURLByAppendingPathComponent:[locationlastPathComponent]];

}


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

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

{

   NSError*error;

   NSFileManager*fileManager = [NSFileManagerdefaultManager];

    [fileManagerremoveItemAtURL:destinationerror:NULL];

    [fileManagercopyItemAtURL:locationtoURL:destination error:&error];

   if(error ==nil) {

       returntrue;

    }else{

       NSLog(@"%@",error);

       returnfalse;

    }

}



版权声明:本文为u012243474原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。