Reputation: 35384
I use this AFNetworking method to start multiple requests at once:
- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
completionBlock:(void (^)(NSArray *operations))completionBlock
One of them is a AFJSONRequestOperation
. The problem is that the success-block of this JSON operation is executed after the completion-block of the batch. The reason is: AFJSONRequestOperation
has an internal dispatch queue for JSON processing. So the JSON data is still in processing while the completion block is called.
Question: How can execute code in the completion block after the success block of the JSON operation has been called?
I tried to dispatch a code block on the main queue but that didn't help.
Upvotes: 12
Views: 3020
Reputation: 19005
It appears there is no easy way to do exactly what the OP requests, so here are some easy workarounds.
A rather blunt strategy would be to use AFHTTPRequestOperation
instead of AFJSONRequestOperation
and then convert the response using NSJSONSerialization
.
So the success block of the operation would look like
success:^(AFHTTPRequestOperation *operation, id responseObject){
NSError *error ;
id json = [NSJSONSerialization JSONObjectWithData:responseObject
options:kNilOptions error:&error] ;
...
}
Caveats would apply - for large JSON responses this is potentially blocking code, and some of the AFNetworking workarounds to NSJSONSerialization
issues would not apply. But this would get you going.
Update: The first commenter below suggests using AFJSONRequestOperation
and calling responseJSON
on it in the batch completion block. I'm good with that if your situation allows it. In my current use case it complicates my code somewhat (I'm using a mixed set of JSON calls, so the code is cleaner if I can keep it in a success
block directly associated with the operation).
Upvotes: 0
Reputation: 982
You can move your Json operation to the beginning of the queue, and then add a dependency so that another operation can only start after the json operation finishes:
[lastOperation addDependency:jsonOperation]
Upvotes: 0
Reputation: 2955
If it's possible, the simplest solution might be just to move your processing code from the success block of each operation to the completion block of the whole batch.
You have the NSArray *operations
available in the completion block, you can iterate through the operations and look for:
for(AFHTTPRequestOperation *operation in operations){
if(operation.response.statusCode == 200){
//Do something with the response
}else{
//Handle the failure
}
}
You also have the url address for each operation available through the operation.request.URL
property if you need to preform different actions
Upvotes: 1