I am using AFNetworking to download files that my app uses for a sync solution. At certain times, the app downloads a series of files as a batch unit. Following this example, I run the batch like this:
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
});
This works well for the batch downloads. However, I want to display to the user an MBProgressHUD which shows them how the downloads are coming along.
AFNetworking provides a callback method
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
}];
... which lets you update a progress meter pretty easily, simply by setting the progress to totalBytesRead / totalBytesExpectedToRead
. But when you have multiple downloads going simultaneously that is hard to keep track of on a total basis.
I have considered having an NSMutableDictionary
with a key for each HTTP operation, with this general format:
NSMutableArray *downloadProgress = [NSMutableArray arrayWithArray:@{
@"DownloadID1" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @100000},
@"DownloadID2" : @{ @"totalBytesRead" : @0, @"totalBytesExpected" : @200000}
}];
As each operation's download progresses, I can update the totalBytesRead
for that specific operation in the central NSMutableDictionary
-- and then total up all the totalBytesRead
and totalBytesExpected' to come up with the total for the whole batched operation. However, AFNetworking's progress callback method
downloadProgressBlock, 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
successand
failure` callbacks, which do contain the specific operation as a variable, making it accessible). Which makes it impossible, as far as I can tell, to determine which operation specifically is making the callback.
Any suggestions on how to track the progress of multipole simultaneous downloads using AFNetworking?