AFNetworking batch requests - canceling when first one fails

afnetworking, ios, objective-c

Solution

Rather than adding the operations to the `[NSOperationQueue mainQueue]`, create your own operation queue. So, in your `@interface` define a queue:

@property (nonatomic, strong) NSOperationQueue *networkQueue;

Then, instantiate a queue:

self.networkQueue = [[NSOperationQueue alloc] init];
self.networkQueue.name = @"com.domain.app.networkqueue";

// if you want it to be a serial queue, set maxConcurrentOperationCount to 1
//
// self.networkQueue.maxConcurrentOperationCount = 1;
// 
// if you want it to be a concurrent queue, set it to some reasonable value
//
// self.networkQueue.maxConcurrentOperationCount = 4;

Then, add your network operations to this queue (bypassing `batchOfRequestOperations`):

NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"All operations done");
}];

// NSOperation *previousOperation = nil;   // if you uncomment dependency code below, uncomment this, too

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];

    // if you want the operations to run serially, you can also
    // make each dependent upon the prior one, as well
    //    
    // if (previousOperation)
    //     [operation addDependency:previousOperation];
    //
    // previousOperation = operation;

    [completionOperation addDependency:operation];

    [self.networkQueue addOperation:operation];
}

[self.networkQueue addOperation:completionOperation];

And, finally, if you want to cancel the operations, you can do:

[self.networkQueue cancelAllOperations];

Problem

I'm using AFNetworking code for batching requests. I have really copy & paste from example code - it looks like that: ``` 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:mutableOperation 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]; ``` Now what I want to achieve is to cancel all other operation in that queue if the first one fails. I found a solution for 1.0.3 with AFHttpClient but nothing for 2.0. Any tips ?

Original source