多个文件串行下载
2021-11-22 本文已影响0人
白色天空729
复习GCD信号量知识
https://www.jianshu.com/p/2d90fdf5de9e
依赖AFNetworking
.h文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^downloadpercent)(double percent);
typedef void(^filesavedPath)(NSURL *path);
typedef void(^errorReason)(NSString *error);
@interface xxx : NSObject {
/// 统计遍历到了第几个元素
__block NSInteger downloadIndex_;
}
- (void)downloadStuffWithArray:(NSArray *)urlArray
complitionHandler:(downloadpercent)complitionBlock
filesavedPath:(filesavedPath)pathBlock
downloadError:(errorReason)errorBlock;
@end
NS_ASSUME_NONNULL_END
.m
#import "xxx.h"
#import "AFURLSessionManager.h"
@implementation xxx
- (instancetype)init
{
self = [super init];
if (self) {
downloadIndex_ = 0;
}
return self;
}
- (void)dealDownload:(filesavedPath _Nonnull)pathBlock
urlArray:(NSArray * _Nonnull)urlArray
complitionHandler:(downloadpercent _Nonnull)complitionBlock
downloadError:(errorReason)errorBlock {
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
NSURL* URL = [NSURL URLWithString:urlArray[downloadIndex_]];
dispatch_group_async(group, queue, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
// NSLog(@"%d %@ %f",__LINE__,NSStringFromClass(self.class),downloadProgress.fractionCompleted);
complitionBlock([NSString stringWithFormat:@"%.2f",downloadProgress.fractionCompleted].doubleValue);
if (downloadProgress.fractionCompleted == 1.0) {
dispatch_semaphore_signal(semaphore);
}
}
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:NO
error:nil];
pathBlock([documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]);
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
# if DEBUG
#else
NSLog(@"%d %@ %ld",__LINE__,NSStringFromClass(self.class),self->downloadIndex_);
#endif
/// 下载完一个,取下一个元素,继续下载。相当于遍历了一遍下载数组。
self->downloadIndex_ += 1;
errorBlock(error.debugDescription);
if (self->downloadIndex_ == urlArray.count) {
return;
}
[self dealDownload:pathBlock urlArray:urlArray complitionHandler:complitionBlock downloadError:errorBlock];
}];
[downloadTask resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_notify(group, queue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
#if DEBUG
NSLog(@"%d %@ %@",__LINE__,NSStringFromClass(self.class),@"下载完毕");
#else
#endif
});
});
}
- (void)downloadStuffWithArray:(NSArray *)urlArray
complitionHandler:(downloadpercent)complitionBlock
filesavedPath:(filesavedPath)pathBlock
downloadError:(errorReason)errorBlock {
/// 有下载元素
if (downloadIndex_ < urlArray.count) {
[self dealDownload:pathBlock urlArray:urlArray complitionHandler:complitionBlock downloadError:errorBlock];
}
}
@end
使用:
[xxx.new downloadStuffWithArray:list complitionHandler:^(double percent) {
NSLog(@"%d %@ %f",__LINE__,NSStringFromClass(self.class),percent);
} filesavedPath:^(NSURL * _Nonnull path) {
NSLog(@"%d %@ savedPATH%@",__LINE__,NSStringFromClass(self.class),path);
} downloadError:^(NSError * _Nonnull error) {
NSLog(@"%d %@ %@",__LINE__,NSStringFromClass(self.class),error.debugDescription);
}];