NSURLSession实现断点续传

来源:互联网 发布:淘宝货源 方法步骤 编辑:程序博客网 时间:2024/05/22 12:46
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 *_Nullable resumeData) {

           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];

    BOOL success = [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

    double currentProgress = 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];

    [fileManager removeItemAtURL:destinationerror:NULL];

    [fileManager copyItemAtURL:locationtoURL:destination error:&error];

    if (error ==nil) {

        returntrue;

    }else{

        NSLog(@"%@",error);

        returnfalse;

    }

}


0 0
原创粉丝点击