Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLConnection sendSynchronousRequest - background to foreground

I m using sendSynchronousRequest to get the data from the server. I know that synchronous will wait until the data received for that request.

But the problem comes when user by mistake enters some non-existing url and than tries to get response. In this case, if user goes in to background and than comes into foreground it shows only black screen. It only shows status bar. Also its not showing any background application. I have to press Home button to come out of my application.

On simulator, After 1+ minute it shows me the message that "Request time out" (No crash).

On Device, within 1 min application get crashes.

Any suggestion. Any Help. This is really a serious issue in my app.

Thanks.

like image 346
JiteshW Avatar asked Nov 02 '11 04:11

JiteshW


4 Answers

Just like Julien said, the watchdog is killing your app. To answer some questions:

  • why does this happen only on the simulator? Because when you're debugging the watchdog leaves your app alone, it can take time.
  • why does this happen only when the user enters a wrong url? Because of the system timeout, the system will keep trying for 60 secs if it can't find a server.
  • so the problem is synchronous vs asynchronous? No, the problem is the thread, you can do the same operation in a background thread, just don't do it on the main thread and the watchdog will leave you alone.
  • why is the screen black when the app comes up? Remember, you are making blocking stuff on the main thread, the thread that draws...

Hope that was all. Let me know if I missed something.

like image 142
fbernardo Avatar answered Oct 20 '22 08:10

fbernardo


Why not setting a timeout for your connection?

NSString *urlString = TEST_CONNECTION;
NSError *error = nil;
NSHTTPURLResponse *response = nil;
NSURLRequest *request = [NSURLRequest
                         requestWithURL:[NSURL URLWithString:urlString]
                         cachePolicy:NSURLRequestReloadIgnoringCacheData
                         timeoutInterval:5.0];


NSData *conn = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

This should release the synchronous waiting after a number of seconds, which should solve your problem without going with an asynchronous call (which sometimes isn't the proper solution)

I know this works properly because this is how I check if I am connected to a certain VPN (where reachability flags totally fail).

like image 23
superandrew Avatar answered Oct 20 '22 09:10

superandrew


you should take a look to this article: https://developer.apple.com/library/ios/#qa/qa1693/_index.html

iOs contains a watchdog, if your application is blocked to much time on an operation on the main thread, this one will be killed. (for more details about Watchdog: http://en.wikipedia.org/wiki/Watchdog_timer)

So if you want to download something, don't download it on the main thread.

like image 37
Julien Avatar answered Oct 20 '22 08:10

Julien


RELATE

UIImage *image = [self.imgCache objectForKey:urlString];
if(!image){
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURLResponse *response = nil;
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
        NSLog(@"%@",response);
        UIImage *img = [UIImage imageWithData:data];
        //

        if(img)
        {
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self.imgCache setObject:img forKey:urlString];
                completionBlock(img);
            });
        }
    });

}
else{
    completionBlock(image);
}
like image 39
Chigs79 Avatar answered Oct 20 '22 08:10

Chigs79