Search code examples
objective-cios7afnetworking-2

Is it possible to use [AFURLConnectionOperation batchOfRequestOperations...] and setUploadProgressBlock simultaneously?


I'm using AFURLConnectionOperation batchOfRequestOperations as described here. My code is a modified version of the sample code below, and it works.

NSMutableArray *mutableOperations = [NSMutableArray array];
for (NSURL *fileURL in filesToUpload) {
    NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];
    }];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [mutableOperations addObject:operation];
}

NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
    NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
    NSLog(@"All operations in batch complete");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];

The issue I'm having is that I can't figure out how to use the AFURLConnectionOperation class on its own, and specifically the setUploadProgressBlock, which is defined like so:

- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block;

The problem is that batchOfRequestOperations is a static method and the progress block needs to be defined on an instance. I can't find any examples of setting up AFURLConnectionOperation and using it as an instance (except with a single request, which I don't want). And even if I could, I'd want to recreate the functionality of the batch method I'm using anyway.

Is there any way to use this very handy block and very handy batch method at the same time? If not, I'm open to other suggestions...

tl;dr: I want to batch some upload operations and use a simple progress block to track their progress.


Solution

  • You can get each operation in batchOfRequestOperations and use them like this:

    [AFURLConnectionOperation batchOfRequestOperations:operations 
     progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) 
     {
         for(AFHTTPRequestOperation *operation in operations)
         {
             [operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
                                            long long totalBytesWritten,
                                            long long totalBytesExpectedToWrite) {
             NSLog(@"PROGRESS: %lld TOTAL: %lld", totalBytesWritten, totalBytesExpectedToWrite);
             //Do whatever you want with the progress
             }];
         }
      }
    
    completionBlock:^(NSArray *operations) {}
    ];
    

    Now that you have progress of each request, you can easily store and increment values for a global progress.