如何使用AFNetworking跟踪多个同时下载的进度?

Jas*_*son 13 block batch-processing ios mbprogresshud afnetworking-2

我正在使用AFNetworking下载我的应用程序用于同步解决方案的文件.在某些时候,应用程序会将一系列文件作为批处理单元下载.按照这个例子,我像这样运行批处理:

NSURL *baseURL = <NSURL with the base of my server>;
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];

// as per: https://stackoverflow.com/a/19883392/353137
dispatch_group_t group = dispatch_group_create();

for (NSDictionary *changeSet in changeSets) {
    dispatch_group_enter(group);

    AFHTTPRequestOperation *operation =
    [manager
     POST:@"download"
     parameters: <my download parameters>
     success:^(AFHTTPRequestOperation *operation, id responseObject) {
         // handle download success...
         // ...
         dispatch_group_leave(group);

     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         // handle failure...
         // ...
         dispatch_group_leave(group);
     }];
    [operation start];
}
// Here we wait for all the requests to finish
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // run code when all files are downloaded
});
Run Code Online (Sandbox Code Playgroud)

这适用于批量下载.但是,我想向用户显示一个MBProgressHUD,向他们展示下载的进展情况.

AFNetworking提供了一种回调方法

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
}];
Run Code Online (Sandbox Code Playgroud)

...只需将进度设置为,即可轻松更新进度表totalBytesRead / totalBytesExpectedToRead.但是,当您同时进行多次下载时,很难总体跟踪.

我考虑NSMutableDictionary过为每个HTTP操作设置一个密钥,使用这种通用格式:

NSMutableArray *downloadProgress = [NSMutableArray arrayWithArray:@{
   @"DownloadID1" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @100000},
   @"DownloadID2" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @200000}
}];
Run Code Online (Sandbox Code Playgroud)

随着每个操作的下载进行,我可以更新totalBytesRead中心的特定操作NSMutableDictionary- 然后总计所有totalBytesReadtotalBytesExpected' to come up with the total for the whole batched operation. However, AFNetworking's progress callback methoddownloadProgressBlock , defined as^(NSUInteger bytesRead,long long totalBytesRead,long long totalBytesExpectedToRead){} does not include the specific operation as a callback block variable (as opposed to the成功and失败`回调,它确实包含特定操作作为变量,使其可访问).据我所知,这使得无法确定哪个操作专门进行回调.

有关如何使用AFNetworking跟踪多极同时下载进度的任何建议?

tia*_*tia 5

如果块是内联的,则可以operation直接访问,但编译器可能会警告您循环引用.您可以通过声明弱引用并在块内使用它来解决:

__weak AFHTTPRequestOperation weakOp = operation;
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    NSURL* url = weakOp.request.URL; // sender operation's URL
}];
Run Code Online (Sandbox Code Playgroud)

实际上,您可以访问块内的任何内容,但是您需要了解块才能实现.通常,块中引用的任何变量在创建块时复制,即行执行的时间.这意味着我weakOp在块中将引用行执行weakOp时的变量值setDownloadProgressBlock.您可以认为,如果您的块立即执行,那么您在块中引用的每个变量将是什么.


tho*_*b65 0

开始操作时,您可以将每个操作、downloadID 以及totalbytesRead 和totalBytesExpected 的值一起保存在NSDictionary 中,并将所有字典保存到downloadProgressArray 中。

然后,当调用回调方法时,循环遍历数组并将调用操作与每个字典中的操作进行比较。这样您应该能够识别该操作。