最近在项目中遇到了多文件下载问题,具体需求是这样的:
我们是做的旅游类的项目,一个景区有多个景点,每一个景点有一个音频文件,现在要求用户点击一次能够下载所有的景点的音频文件,并且进度只显示总的进度。第一想法是使用afn下载功能实现,创建多个下载任务然后将进度做累加得出总的进度。但是在做的过程中发现并不能这样做,因为每一个下载的任务每一次返回的进度本身就是一个累加的过程,如果在把所有的进度累加的话得出的结果会远远大于实际值。想了各种方法,gcd串型队列,不行,operationqueue,也不行,最后灵光一闪,既然单个任务每次都是一个累加过程那个自己回调进度值的话只需要把本次的回调的值和上次的值做一次减法不就好了吗,然后马上尝试,果然成了。哈哈哈哈
实现的代码如下:
封装的下载方法:
/**
下载工具
@param fileUrl 下载的文件地址
@param dic 请求参数
@param result 下载的结果
*/
+(NSURLSessionDownloadTask *)downLoadTool:(NSString *)fileUrl dataDic:(NSDictionary *)dic progressBlock:(void(^)(CGFloat progressValue))progress resultBlcok:(void(^)(BOOL download))result{
__block CGFloat oldProgress = 0;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:fileUrl]];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@"=======%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
CGFloat pro = 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;
progress(pro-oldProgress);
oldProgress = pro;
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSString *cachesPath = [CommonTool getMusicPath:@"sight"];
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"%@",path);
return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
NSLog(@"%@",filePath);
if (error)
{
result(NO);
}else
{
result(YES);
}
}];
[downloadTask resume];
return downloadTask;
}
调用方法如下:
/**
下载功能
*/
-(void)downloadMehtod{
NSArray *sights = [CommonTool pickegSight:self.downloadScenicModel.sight];
dispatch_queue_t downQueue = dispatch_queue_create("downLoad", DISPATCH_QUEUE_CONCURRENT);
self.scenicTotalSize = sights.count;
for (DSDownloadModel *sight in sights) {
dispatch_async(downQueue, ^{
NSURLSessionDownloadTask *downloadTask = [RequestTool downLoadTool:sight.downfiles dataDic:nil progressBlock:^(CGFloat progressValue) {
_scenicDownloadSize = _scenicDownloadSize + progressValue;
NSLog(@"_+_+_+%f",_scenicDownloadSize);
} resultBlcok:^(BOOL download) {
}];
[self.downloadTaskArr addObject:downloadTask];
});
}
}