用NSUrlSession批量下载文件并保存文件的处理

    现在我来介绍之前说过的用NSUrlSession批量下载的方法,用NSUrlSession下载文件,有两种方法,一是直接调用Block方法做下载后的处理,二是利用NSUrlSessionDelegate的一系列方法,做下载文件后的处理,这种方法的好处就是可以随时监测下载进度。但是一旦选择调用代理方法,就不能用Block的初始化方法初始化,因为如果有Block方法,那么就会走Block,不会走代理方法了,这点需要注意。现在上两种方法的代码:

NSURL*url=[NSURL URLWithString:stringcontent];

    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];

    request.timeoutInterval=90.0;//设置请求超时为5秒
    request.HTTPMethod=@"POST";//设置请求方法

     // 下载文件
     NSURLSession *session = [NSURLSession sharedSession];
     
     NSURLSessionDownloadTask *downLoadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         
     if (!error)
     {
     // 下载成功
         downloadRight = @"success";
     // 注意 location是下载后的临时保存路径, 需要将它移动到需要保存的位置
     NSError *saveError;
     // 创建一个自定义存储路径
     NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
     NSString *dirPath = [cachePath stringByAppendingPathComponent:FileName];
         //创建文件夹,把下载文件存到文件夹里
         NSFileManager *fileManager = [NSFileManager defaultManager];
         NSLog(@"文件夹路径:%@",dirPath);
         if(![fileManager fileExistsAtPath:dirPath]){
             
             [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
         }else{
             //删除原文件夹,创建新文件夹
             [fileManager removeItemAtPath:dirPath error:nil];
             [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];

         }
     //保存下载的压缩包
     NSString *savePath = [dirPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip",ContentName]];
     NSURL *saveURL = [NSURL fileURLWithPath:savePath];

     // 文件移动到cache路径中
     [[NSFileManager defaultManager] moveItemAtURL:location toURL:saveURL error:&saveError];
     if (!saveError)
     {
     NSLog(@"保存成功");
         
     }
     else
     {
     NSLog(@"saveError is %@", saveError.localizedDescription);
     }
         
     }
     
     
     else
     {
         //下载失败
     NSLog(@"error is : %@", error.localizedDescription);
         
     }
     }];
     // 恢复线程, 启动任务
     [downLoadTask resume];

    block方法的有点就是存储文件取名字比较方便,可以直接写一个方法,把需要的参数传进来。但就是不能获取实时的下载进度。

    下面是利用代理方法下载:

NSURL*url=[NSURL URLWithString:stringcontent];
    
    NSURLSessionConfiguration*cfg = [NSURLSessionConfiguration defaultSessionConfiguration]; // 默认配置
    
    NSURLSession*session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    // 创建任务
    NSURLSessionDownloadTask*downloadTask = [session downloadTaskWithURL:url];

    // 开始任务
    [downloadTask resume];
    NSLog(@"下载开始时间:%@",[NSDate date]);
    代理方法有:

#pragma mark - NSUrlSessionDegelate
// 下载过程中 会多次调用, 记录下载进度
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    // 记录下载进度
    NSString * progress = [NSString stringWithFormat:@"%f",(double)totalBytesWritten/totalBytesExpectedToWrite];
    self.progressLB.text = progress;
}

// 下载完成
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    
    
    NSString *filesName;
    NSString *contentName;
    NSDictionary *dict = self.downloadArray[downCount];
    filesName = [NSString stringWithFormat:@"%@",dict[@"fileName"]];
    contentName = [NSString stringWithFormat:@"%@",dict[@"contentName"]];
    
    //通知 downCount++
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downCountJishu) name:@"notice" object:nil];

    NSLog(@"%@",downloadTask.currentRequest.URL);
    NSLog(@"下载完成时间:%@",[NSDate date]);
    // 注意 location是下载后的临时保存路径, 需要将它移动到需要保存的位置
    NSError *saveError;
    // 创建一个自定义存储路径
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dirPath = [cachePath stringByAppendingPathComponent:filesName];//downFileName
    
    //创建文件夹,把下载文件存到文件夹里
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSLog(@"文件夹路径:%@",dirPath);
    if(![fileManager fileExistsAtPath:dirPath]){
        
        [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
    }else{
        //删除原文件夹,创建新文件夹
        [fileManager removeItemAtPath:dirPath error:nil];
        [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
        
    }
    //保存下载的压缩包
    NSString *savePath = [dirPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip",contentName]];//downContentName
    NSURL *saveURL = [NSURL fileURLWithPath:savePath];
    
    // 文件移动到cache路径中
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:saveURL error:&saveError];
    if (!saveError)
    {
        NSLog(@"保存成功");
        //解压
        [self jieyasuo:contentName :filesName];//downContentName,downFileName
        
    }
    else
    {
        NSLog(@"saveError is %@", saveError.localizedDescription);
    }
    
    [self performSelector:@selector(downCountJishu) withObject:nil];

}
- (void)downCountJishu
{
    downCount ++;
}
// 当调用恢复下载的时候 触发的代理方法 [_downLoadTask resume]
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    
    
}


#pragma mark --- 任务完成, 不管是否下载成功
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    if (error) {
        //下载文件失败
    }else{
        //下载文件成功
    }
}
#pragma mark --- session 后台下载完成 之后的操作 (本地通知 或者 更新UI)
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
{
    
}

    注意,要记得遵守协议: NSURLSessionDownloadDelegate

    在用代理方法下载文件时,我遇到的一个很多天都没有想到解决办法的问题,那就是在下载完成的代理方法里,由于系统方法无法把自己想要的参数传进去,所以保存文件的时候,我无法获取到所下载的文件究竟叫什么名字,从而给批量下载保存文件造成了困难。我查了很多网上的方法,都只说了在

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
的方法里,有一个属性是 response . suggestedFilename

这个是服务器保存的文件的名字,也是我们请求URL的最后一部分的字段,可以用它来当做下载文件的名字。如以下情况:

大部分人都可以用这个方法来解决保存文件的问题,但我的情况是:服务器把所有文件的请求路径都做成了一个,只不过每个文件下载时,传的一个filePath的参数都不一样,所以这给我保存时造成了很大的困难,我如果用上述方法,那么所有文件都会保存成同一个名字。

    最后,我找到了一个解决办法,声明一个常量int downCount;先把downCount初始化为0,然后在下载完成的代理方法里,根据保存好的数组self.downloadArray和downCount获取对应的字典,然后获取下载的文件的相关信息,如fileName。再拼接保存文件的路径和名字就好了。每当保存好一个文件后,在代理方法的最后,将downCount++;这样downCount就像自动计数一样,将文件和下载内容对应起来了。

    当然,这只是我想到的解决办法,希望大家如果有其他更好的办法,一起交流。

;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值