I have multiple operations (they're AFNetworking requests) with completion blocks that takes some time to execute, and a Core Data object that needs to be saved at the end of all the requests.
MyCoreDataObject *coreDataObject;
AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
coreDataObject.attribute1 = responseObject;
sleep(5);
}];
[operation1 start];
AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
coreDataObject.attribute2 = responseObject;
sleep(10);
}];
[operation1 operation2];
[context save:nil];
Of course, this does not work as I want because the requests are asynchronous. I tried adding an NSOperationQueue like so:
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:2];
AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
coreDataObject.attribute1 = responseObject;
sleep(5);
}];
[operationQueue addOperation:operation1];
AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
coreDataObject.attribute2 = responseObject;
sleep(10);
}];
[operationQueue addOperation:operation2];
[imageQueue waitUntilAllOperationsAreFinished];
[context save:nil];
This looks a bit better. Using waitUntilAllOperationsAreFinished
, my queue blocks the current thread until my requests are finished, but not until my success Blocks are finished, which is really what I need.
Any ideas on how to achieve this in a good way?
Use dispatch groups.
AFNetworking has designed method for this kind of operations, which abstracts from GCD:
-enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:
-enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:
Take a look at FAQ
I belive something like this:
refering to docs: http://cocoadocs.org/docsets/AFNetworking/2.5.0/
My requirements were those of do many request from an array of String (URL)
Obviously, in this way calls are made in cascade, not N asynchronous calls.