1

I've looked around a lot and cant seem to find a proper answer for my problem. As of now I have a network engine and I delegate into that from each of the view controllers to perform my network activity.

For example, to get user details I have a method like this:

- (void) getUserDetailsWithUserId:(NSString*) userId
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@Details", kServerAddress]]];
    request.HTTPMethod = @"POST";

    NSString *stringData = [NSString stringWithFormat:@"%@%@", kUserId, userId];
    NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = requestBodyData;

    NSURLConnection *conn = [[NSURLConnection alloc] init];
    [conn setTag:kGetUserInfoConnection];
    (void)[conn initWithRequest:request delegate:self];
}

And when I get the data in connectionDidFinishLoading, I receive the data in a NSDictionary and based on the tag I've set for the connection, I transfer the data to the required NSDictionary.

This is working fine. But now I require two requests going from the same view controller. So when I do this, the data is getting mixed up. Say I have a connection for search being implemented, the data from the user details may come in when I do a search. The data is not being assigned to the right NSDictionary based on the switch I'm doing inside connectionDidFinishLoading. I'm using a single delegate for the entire network engine.

I'm new to NSURLConnection, should I setup a queue or something? Please help.

EDIT

Here's the part where I receive data in the connectionDidFinishLoading:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if ([connection.tag integerValue] == kGetUserDetails)
        networkDataSource.userData = self.jsonDetails;
    if ([connection.tag integerValue] == kSearchConnection)
        networkDataSource.searchData = self.jsonDetails;
}

and after this I have a switch case that calls the required delegate for the required view controller.

Anil
  • 2,430
  • 3
  • 37
  • 55

3 Answers3

3

Anil here you need to identify for which request you got the data, simplest way to check it is as below,

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
 {
  // Check URL value for request, url for search and user details will be different, put if condition as per your need. 
   conn.currentRequest.URL
 } 

Try using conn.originalRequest.URL it will give original request.

Vishwa Patel
  • 484
  • 2
  • 10
  • 1
    That sounds like a nice idea. I'll give that a shot. – Anil Oct 25 '13 at 06:30
  • I tried the same. But when I send a request in between, say I do a search as the user details are being downloaded (say slow internet speeds), the user details call doesnt continue. Only the search happens. – Anil Oct 25 '13 at 08:29
  • Here for each request in delegate methods you need to handle response data, so suppose you are making 5 requests at a time than you should create 5 response data objects and need to handle all those by checking conditions which I mentioned. Please post some code which you did for multiple request and also post connection delegate method code. – Vishwa Patel Oct 25 '13 at 08:33
  • I've edited the question. Also, the problem I'm facing is that the URL is of the user data fetch but the tag is of the search URL :/ – Anil Oct 25 '13 at 12:17
  • The problem was with the category I'm using to set the tag for the connection. Even though the URL is the same, the tag is different. I was searching based on the tag. So thanks for your suggestion. – Anil Oct 25 '13 at 13:02
1

You can do in many ways to accomplish your task as mentioned by others and it will solve your problem . But if you have many more connections , you need to change your approach.

You can cretae a subclass of NSOperation class. Provide all the required data, like url or any other any informmation you want to get back when task get accomplish , by passing a dictionary or data model to that class.

In Nsoperation class ovewrite 'main' method and start connection in that method ie put your all NSURRequest statements in that method. send a call back when download finish along with that info dict.

Points to be keep in mind: Create separte instance of thet operation class for evey download, and call its 'start method'.

It will look something like :

 [self setDownloadOperationObj:[[DownloadFileOperation alloc] initWithData:metadataDict]];

    [_downloadOperationObj setDelegate:self];

    [_downloadOperationObj setSelectorForUpdateComplete:@selector(callBackForDownloadComplete)];

    [_downloadOperationObj setQueuePriority:NSOperationQueuePriorityVeryHigh];

    [_downloadOperationObj start];

metaDict will contain your user info. In DownloadFileOperation class you will overwrite 'main' method like :

- (void)main {
    // a lengthy operation
    @autoreleasepool
    {
        if(self.isCancelled)
            return;

//      //You url connection code
    }
}

You can add that operation to a NSOperationQueue if you want. You just need to add the operation to NSOperationQueue and it will call its start method.

Kumar Aditya
  • 1,097
  • 1
  • 8
  • 19
-2

Declare two NSURLConnection variables in the .h file.

NSURLConnection *conn1;
NSURLConnection *conn2;

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

    if(connection == conn1){

    }
    else if(connection == conn2){

    }

}
Ramaraj T
  • 5,184
  • 4
  • 35
  • 68
  • 1
    Am I not doing the same thing? I'm allocation different NSURLConnection for each connection NSURLConnection *conn = [[NSURLConnection alloc] init]; – Anil Oct 25 '13 at 06:16