为多个文件下载添加子进度

Posted

技术标签:

【中文标题】为多个文件下载添加子进度【英文标题】:Adding child progress for multiple file download 【发布时间】:2016-02-07 04:47:51 【问题描述】:

我正在我的项目中使用 AFNetworking 3.0 下载多个文件。我想显示所有文件的单个下载进度。我将每个文件下载的每个子进度添加到父进度中。但它不起作用,应用程序崩溃了。我收到了错误 -

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<DownloadManager: 0x7f92e2f6e130>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: fractionCompleted

这是我的下载类-

@interface DownloadManager ()

@property (nonatomic, strong) NSProgress *progress;
@property (nonatomic, strong) Settings *settings;
@property (nonatomic, strong) DocumentDirectory *documentDirectory;

@end


@implementation DownloadManager

- (instancetype)init

    self = [super init];
    if (self) 
        self.progress = [NSProgress new];
        [self.progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
        self.settings = [Settings new];
        self.documentDirectory = [DocumentDirectory new];
    

    return self;


- (void) dealloc 
    [self.progress removeObserver:self forKeyPath:@"fractionCompleted"];



//Download the file from remote server in the document directory as Zip format
- (void) downloadCarContents:(NSArray *)urlArray forContent:(NSArray *)contentArray 

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    self.progress.totalUnitCount =  urlArray.count;
    self.progress.completedUnitCount = 0;

    for (NSInteger i = 0; i < urlArray.count; i++) 

        NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentArray[i]];
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[i]]];

        NSURLSessionTask *task = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) 

            return [NSURL fileURLWithPath:destinationPath];

         completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) 


        ];

        NSProgress *childProgress = [manager downloadProgressForTask:task];
        [self.progress addChild:childProgress withPendingUnitCount:1];

        NSLog(@"Total downloaded : %f", self.progress.fractionCompleted * 100.0);

        [task resume];
    


@end

【问题讨论】:

【参考方案1】:

您忘记实现observeValueForKeyPath:ofObject:change:context: 方法。

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSString *, id> *)change
                       context:(void *)context 
    if ([keyPath isEqualToString:@"fractionCompleted"]) 
        // process value
    

【讨论】:

哦,是我的错。谢谢。 还有一个问题。如何确保在 completionHandler 块中成功下载所有内容?我需要在 completionHandler 块中进行验证,但不需要在带有 1.0 分数值完成检查的 observeValueForKeyPath 方法中进行验证?

以上是关于为多个文件下载添加子进度的主要内容,如果未能解决你的问题,请参考以下文章

使用 SparkSQL 读取多个 parquet 文件时将子文件夹作为列获取

jquery 多个 上传文件教程

编写异步控制器并更新进度

php文件上传进度条例子

优雅设计封装基于Okhttp3的网络框架:多线程下载添加数据库支持(greenDao)及 进度更新

在 iPad 上以编程方式添加子视图,硬编码