NSURLConnection sendSynchronousRequest - background to foreground

Deadly 提交于 2019-12-03 14:23:54

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.

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).

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.

Chigs79

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);
}

use ASIHttpRequest class instead of NSURLConnection , its nothing but wrapper around NSURLConnection and has very simple callbacks , you can also set time to complete a request. Please go through this link for more info http://allseeing-i.com/ASIHTTPRequest/

I think you first have to test user data whether it is correct or not and than only if it is correct, sends the request otherwise prompt user that "please enter correct data"...

or

when your parsing of data in response failed. You can also make protocol delegate method i.e FinishWithError so that you come up with your last UI.

Rohit Wankhede

Try this one:

#import "ASIHTTPRequest.h"

//In a method
[self performSelectorInBackground:@selector(DownLoadImageInBackground:) withObject:imgUrlArr];  


-(void) DownLoadImageInBackground:(NSArray *)imgUrlArr1  
{
    NSURL * url = [Image URL];

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setDelegate:self];
    [request startAsynchronous];
}

-(void)requestFailed:(ASIHTTPRequest *)request

{

    NSLog(@"URL Fail : %@",request.url);

    NSError *error = [request error];

       // you can give here alert too..
}

-(void)requestFinished:(ASIHTTPRequest *)request

{

    NSData *responseData = [request responseData];
    UIImage *imgInBackground = [[UIImage alloc]
                         initWithData:responseData];
    [imageView setImage: imgInBackground];

}

This might help you: I am also loading a number of images at one time, so images that have no proper data show a black screen. To avoid this, try to resize your imageview.

You could check the reachability of the URL before starting the request. Apple has Reachability Methods to do so. But its easier to use a wrapper. E.g. ASIReachability.

rakeshNS

I think the application crashing because you does not get any data when user enters wrong URL and you are using this 'returned' nil NSData to do stuffs.

I think this will fix your problem

NSData *data=[NSURLConnection sendSynchronousRequest:request 
                                   returningResponse:&response 
                                               error:&error];
if(data!=nil){
    /// 
} else {
   NSLog(@"NO DATA");
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!