现在的位置: 首页 > 综合 > 正文

NSURLSession普通多任务下载和断点续传并保存显示进度条

2018年08月04日 ⁄ 综合 ⁄ 共 3625字 ⁄ 字号 评论关闭

关于NSURLSessionde概念的介绍可以参见http://blog.csdn.net/majiakun1/article/details/38133433

在模拟器上测试发现这些下载方式在锁屏或者挂起时也可以下载

普通下载:

都是在viewController里面测试的,定义currentSession的和下载任务downTask这两个属性,使用<NSURLSessionDownloadDelegate>代理方法

为了方便测试 URL是自己搭的服务器上的内容

如果要实现多任务下载 就定义多个task,多个task会同时下载 不同的task用taskIdentifiler进行区分,taskIdentifiler为只读属性,不能赋值,由系统分配其ID值

    NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://192.168.23.1/test/Backkom.mp4"]];
    NSURLSessionConfiguration *epheSession=[NSURLSessionConfiguration ephemeralSessionConfiguration];
    epheSession.discretionary=YES;
    self.currentSession=[NSURLSession sessionWithConfiguration:epheSession delegate:self delegateQueue:nil];
    self.downTask=[self.currentSession downloadTaskWithRequest:request];
    [self.downTask resume];

如果用这种的方式创建task则不会执行NSURLSessionDownloadDelegate中的一些重要的代理方法代理方法,不管成功与否是直接里面的block

self.downTask=[self.currentSession downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
        NSLog(@"________");
    }];

以下就是NSURLSessionDownloadDelegate中得代理方法,需要注意的时把下载的temp文件转存下来需要自己需要指定文件名和类型;另外注意为指定路径时URL初始化用此方法fileURLWithPath,用URLWithString会造成路径错误

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    //下载成功调用此方法,
    NSFileManager *fileManager = [NSFileManager defaultManager];//文件管理
    NSURL *documentsDirectory=[NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingString:@"/Documents/"]];
    NSURL *destinationPath = [documentsDirectory URLByAppendingPathComponent:@"Backkom.mp4"];
    NSError *error;
    [fileManager removeItemAtURL:destinationPath error:NULL];//确保文件不在
    BOOL success = [fileManager copyItemAtURL:location toURL:destinationPath error:&error];
    if(success){
        NSLog(@"success path:%@",destinationPath);
    }else{
        NSLog(@"error:%@",error);
    }
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    //失败和成功都会调用
    if(error){
        NSLog(@"error:%@",error);
    }
}

执行下载有数据写入执行,bytesWritten--每次写入的data字节数;totalBytesWritten--当前一共写入的data字节数,totalBytesExpectedToWrite--期望收到的所有data字节数

prograss就是下载进度

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    double prograss=totalBytesWritten/(double)totalBytesExpectedToWrite;
}

如要取消下载可以设置downTask cancel就可以了。

断点续传:

此方式需要定义一个NSData *partialData来存储暂停时需要保存的下载数据,resumableTask为NSURLSessionDownloadTask,当取消下载时,需在cancelByProducingResumeData的block中对已经下载的数据进行保存

if(self.resumableTask){
        [self.resumableTask cancelByProducingResumeData:^(NSData *resumeData){
            self.partialData=resumeData;
        }];
    }

创建下载时同样使用的时代理方法,注意判断partiaData,不是nil表示已经取消过下载。代理方法里面的代码和上面普通下载一样

if(!self.resumableTask){
        NSURLSessionConfiguration *defaultSession=[NSURLSessionConfiguration defaultSessionConfiguration];
        defaultSession.discretionary=YES;
        self.resumeSession=[NSURLSession sessionWithConfiguration:defaultSession delegate:self delegateQueue:nil];
    }
    if(self.partialData){
        self.resumableTask=[self.resumeSession downloadTaskWithResumeData:self.partialData];
    }else{
        NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://192.168.23.1/test/Backkom.mp4"]];
        self.resumableTask=[self.resumeSession downloadTaskWithRequest:request];
    }
    [self.resumableTask resume];

后台下载:

后台下载是在说在程序锁屏,挂起也可以下载,甚至在程序退出时都可以继续下载,是由系统来处理的。在找的demo程序我退出程序都不能下载,看backgroundSessionConfigurationWithIdentifier的文档If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers说用户终止应用就会取消session的后台就传输,找了个demo(http://www.cocoachina.com/bbs/read.php?tid=171978)也没有实现程序退出后下载成功,希望有成功的同学能分享下或者指教下。

抱歉!评论已关闭.