Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group or batch requests with AFNetworking 2.0

I'm trying to figure out what is the best practice to group or batch a number of GET requests using AFNetworking 2.0. All the GET requests need to be completed before the code can continue, but they don't have to run one after the other. Right now for single requests, I'm using AFHTTPRequestOperationManager (see also here: Subclass AFHTTPRequestOperationManager?).

One possibility is described here, using a dispatch_group: How to batch request with AFNetworking 2?, but that is for AFHTTPSessionManager, which is iOS7 only. My app still targets iOS6 as well, so I need to use AFHTTPRequestOperationManager.

Is using a dispatch_group the way to go? Or is there something built in in AFNetworking that I have overlooked and can use for this?

EDIT: Still don't know what the correct way is... For instance, how do I use a group with AFHTTPRequestOperation ?

I've tried the following, but the final NSLog ("done searching") is always shown first, before all the responses come in:

dispatch_queue_t dispatch_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t dispatch_group = dispatch_group_create();

for (Entry *e in self.entries)
{
    dispatch_group_async(dispatch_group, dispatch_queue, ^{
        NSString *queryString = [e getQueryString];         
        NSURL *URL = [NSURL URLWithString: queryString];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];

        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        operation.responseSerializer = [AFHTTPResponseSerializer serializer];
        operation.completionGroup = dispatch_group;
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"%@", responseObject);
        } failure:nil];

        [operation start];
    });
}

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"done searching");
});
like image 275
koen Avatar asked Dec 30 '13 19:12

koen


1 Answers

After lots of trying, I came up with the following, which does exactly what I need. All the AFHTTPRequestOperation calls are taken care of by a singleton client:

dispatch_group_t dispatchGroup = dispatch_group_create();

for (Entry *e in self.entries)
{
    dispatch_group_enter(dispatchGroup);

    MyDBClient *dbClient = [MyDBClient sharedClient];

    [dbClient searchForQuery: queryString
                   withParameters: nil
                       completion: ^(NSData *data, NSError *error) {
                           if (data) {
                               // process data
                           }                               
                           else {
                               // deal with error, if any
                           }                              
                           dispatch_group_leave(dispatchGroup);
                       }];
}

dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
  // update UI here
});

The code in the client is based on the sample code I found here: http://nsscreencast.com/episodes/91-afnetworking-2-0

I hope this helps others who are trying to accomplish the same.

like image 102
koen Avatar answered Oct 05 '22 14:10

koen