Posts Tagged ‘asynchronous’

Multiple async NSURLConnections example

Sunday, March 15th, 2009

After posting the custom NSURLConnection subclass blog post, I thought I might post an example of how it would be used, since quite a lot of visitors came to the blog searching for the keywords: “multiple asynchronous NSURLConnection”. The code itself is pretty straightforward, but might prove handy for those developers setting their first steps in Cocoa Touch.

The basic idea is to use a dictionary which stores the received data per tag, remember that the actual connection cannot be used as the key of a dictionary. Each NSURLConnection methods retrieve the NSMutableData object from the dictionary based on the tag and does it magic with it.

If you don’t know how to use the NSURLConnection class, take a look at the documentation. That should get you going in no time.

First of all add a mutable dictionary to the header file:

NSMutableDictionary *receivedData;

Here’s the actual code. The load method starts the actual asynchronous calls. The startAsyncLoad:tag and dataForConnection methods are convenience methods to keep the code tidy & readable.

- (void)startAsyncLoad:(NSURL*)url tag:(NSString*)tag {
   NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
   CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:tag];
 
   if (connection) {
      [receivedData setObject:[[NSMutableData data] retain] forKey:connection.tag];
   }
}
 
- (NSMutableData*)dataForConnection:(CustomURLConnection*)connection {
   NSMutableData *data = [receivedData objectForKey:connection.tag];
   return data;
}
 
- (void)load {
   receivedData = [[NSMutableDictionary alloc] init];
 
   NSURL *url1 = [NSURL URLWithString:@"http://blog.emmerinc.be"];
   NSURL *url2 = [NSURL URLWithString:@"http://www.emmerinc.be"];
   NSURL *url3 = [NSURL URLWithString:@"http://twitter.com/emmerinc"]; 
 
   [self startAsyncLoad:url1 tag:@"tag1"];
   [self startAsyncLoad:url2 tag:@"tag2"];
   [self startAsyncLoad:url3 tag:@"tag3"];
}
 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [dataForConnection setLength:0];
}
 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [dataForConnection appendData:data];
}
 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [connection release];
 
   // Do something with the dataForConnection.
}

In the connectionDidFinishLoading: method the tag of the connection should be used to determine what to do with the actual received data. And that is about it!

Don’t forget to release the dictionary in the deconstructor or after all the asynchronous calls have been completed though.