0

I have send asynchronous request to a website using the following code:

NSMutableURLRequest *requestSiteToSendData = [NSMutableURLRequest requestWithURL:[[NSURL alloc]initWithString:@"www.example.com"] cachePolicy:NSURLRequestReloadIgnoringCacheData  timeoutInterval:30];
NSURLConnection *connectionToSiteToSendData = [[NSURLConnection alloc]initWithRequest:requestSiteToSendData delegate:self];

Then I used the following method defined inside NSURLConnectionDelegate to get and parse the data after the data fetching is completed.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //parse 'data'
    NSString *parsedData = [self parseDataWithData:data];
}

And then in the method in which I send the asynchronous request, I return parsedData. But the returning should only happen after the data fetching is completed and hence parsing is done. I know the question arises if that is what I need then why I am not using synchronous request. It is because I don't want my other methods to hang up when the loading is going on in background.

Harikrishnan
  • 7,765
  • 13
  • 62
  • 113

4 Answers4

1

Quick answer : if it's asynchronous, you don't want to wait the asynchronous method. One of the bests option would be :

  • The object calling wanting the data should set itself as the object that runs the asynchronous method, and in didReceiveData, you call a method such as updateData:(NSString *)parsedData, which handles the newly received data

  • The object calling the method should use KVO to observe any change on a property of the object that runs the asynchronous method.

Tell me if you need more informations.

DCMaxxx
  • 2,534
  • 2
  • 25
  • 46
  • The actual problem is the value should be returned only after loading is completed and all other methods should work as it is without hanging. But in my case return is being called before the loading is completed. Hope I am clear. Please ask if there is anything you didn't get about the question. – Harikrishnan Aug 12 '13 at 12:11
  • 1
    Yes, I see what do mean, and that is normal : as the request is made asynchronously, the rest of the function is continued as the asynchronous call was finished. I understand that you want your method to wait until it actually finishes, but is is NOT a good idea or practice. Server might never answer and make your app unresponsive, and many other reasons. You should deal with this using your own made delegate, or KVO. If you'd need help with that, I'd be happy to help. You can wait using Armaan Stranger's answer, BUT I WOULD NOT DO THAT. (unresponsive app, etc.). – DCMaxxx Aug 12 '13 at 14:17
  • Ok.. the problem was solved using a self made delegate. Thank you. – Harikrishnan Aug 13 '13 at 04:35
0

Asynchronous requests run on separate thread, So we don't need to worry about handling view lockup. If you want send a synchronous request then you have to use GCD to achieve the same. And various other details like, how much data is send/received etc. will not be available in synchronous request.

Synchronous request are helpful if your code next state is dependent on data received in response of the request.

Ashwani
  • 3,463
  • 1
  • 24
  • 31
  • The actual problem is the value should be returned only after loading is completed and all other methods should work as it is without hanging. But in my case return is being called before the loading is completed. Hope I am clear. Please ask if there is anything you didn't get about the question. – Harikrishnan Aug 12 '13 at 12:12
  • Then create synchronous instead of async request using `[NSThread]`. And call this when load completes. This won't hang your app. – Ashwani Aug 12 '13 at 12:20
0

You have this delegate method which will execute when all the downloading is completed from tha server successfully.Use this method to do the remaining process

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
}

Ok this method gets executed when the all data is recieved.What you should do is to collect all data from -didReceiveData delegate method and then use it to parse in this method.

A must read document for you

Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
  • I tried this even, but the data is returned before the loading is completed. I tried recursive calling until the data is fetched, but that caused the app to crash and nothing happened. The actual problem is the value should be returned only after loading is completed and all other methods should work as it is without hanging. Hope I am clear. Please ask if there is anything you didn't get about the question. – Harikrishnan Aug 12 '13 at 12:10
  • See the edits and look into the link for more clarity on which you are trying – Lithu T.V Aug 12 '13 at 12:53
0

As far as i understand you want that to return data after web call is complete. so i would suggest that create any method for webcall that returns NSData and do something like this:

NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[NSError alloc] init];  
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];  

if ([urlResponse statusCode] >= 200 && [urlResponse statusCode] < 300) {
       // return responseData from here.
}
else {
        NSLog(@"%d",[urlResponse statusCode]);
        NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
        NSLog(@"%@",result);

}

and you don't want to hung up your View. so call this method in background thread. like this:

[self performSelectorInBackground:@selector(WebCallMethod) withObject:nil];

Hope it Helps!!

Armaan Stranger
  • 3,140
  • 1
  • 14
  • 24
  • So the basic principle here is that synchronous request running in background will do the same effect as that of asynchronous request? Even if it is so, even if the requests loads it background it will still return data right? – Harikrishnan Aug 12 '13 at 12:18
  • @HarikrishnanT you are right. but i have given just another option. both works the same. so it's just the choice for him. – Armaan Stranger Aug 12 '13 at 12:22