NSURLConnection sendAsynchronousRequest:queue:completionHandler: making multiple requests in a row?

Nic Hubbard picture Nic Hubbard · Feb 23, 2012 · Viewed 53.7k times · Source

I have been using NSURLConnection's sendAsynchronousRequest:queue:completionHandler: method which is great. But, I now need to make multiple requests in a row.

How can I do this while still using this great asychronous method?

Answer

yuji picture yuji · Feb 23, 2012

There's lots of ways you can do this depending on the behavior you want.

You can send a bunch of asynchronous requests at once, track the number of requests that have been completed, and do something once they're all done:

NSInteger outstandingRequests = [requestsArray count];
for (NSURLRequest *request in requestsArray) {
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        [self doSomethingWithData:data];
        outstandingRequests--;
        if (outstandingRequests == 0) {
            [self doSomethingElse];
        }
    }];
}

You could chain the blocks together:

NSMutableArray *dataArray = [NSMutableArray array];    
__block (^handler)(NSURLResponse *response, NSData *data, NSError *error);

NSInteger currentRequestIndex = 0;
handler = ^{
    [dataArray addObject:data];
    currentRequestIndex++;
    if (currentRequestIndex < [requestsArray count]) {
        [NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:currentRequestIndex] 
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];
    } else {
        [self doSomethingElse];
    }
};
[NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:0] 
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];

Or you could do all the requests synchronously in an ansynchronous block:

dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Lots of requests", NULL);
    dispatch_async(downloadQueue, ^{
        for (NSRURLRequest *request in requestsArray) {
            [dataArray addObject:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]];
        }
        dispatch_async(callerQueue, ^{
            [self doSomethingWithDataArray:dataArray];
        });
    });
});

P.S. If you use any of these you should add some error checking.