Search code examples
iphonewebviewreloaddidfailwitherror

iPhone - UIWebView not calling didFailLoadWithError without data connection


I've searched and haven't found a solution to this, so hopefully someone can help.

I have a UIWebView that is called when a user presses a button. Everything works great, unless you account for behavior when the phone is without a data connection.

When attempting to open the UIWebView for the first time with the phone on airplane mode or without a data connection:

  • UIWebView starts to load
  • Fails to load

Once the UIWebView is allocated and fails to load for the first time, hitting a refresh button linked to an IBAction (that calls [webView reload]) causes:

  • Regardless of whether or not the phone has a data connection after the initial load fails, the refresh IBAction is called, but my NSLogs tell me neither webViewDidStartLoad, webViewDidFinishLoad, nor webView…didFailLoadWithError are called.

If I leave the app running and turn on a data connection to the device (e.g. turn off airplane mode,) then go back to my app and hit the refresh button, [webView reload] is called, but webViewDidStartLoad (and thus webViewDidFinishLoad) is not called.

Here's the relevant code:

To bring up the webView:

-(IBAction)loadWebView {

    webView = [[UIWebView alloc] init];
    webView.scalesPageToFit = YES;
    [webView setDelegate:self];

    NSString *urlAddress = @"http://google.com";
    NSURL *url = [NSURL URLWithString:urlAddress];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];

    [webView loadRequest:requestObj];

}

Reload:

  -(IBAction)reloadWebView{
    [webView reload];
    NSLog(@"RELOAD");
}

webViewDidStart, DidFinish, didFailLoadWithError:

 - (void)webViewDidStartLoad:(UIWebView *)webView
{  
    NSLog(@"START LOAD");   
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
     NSLog(@"FINISH LOAD");    
}

- (void)webView:(UIWebView *) webView didFailLoadWithError:(NSError *)error 
{ 
       NSLog(@"DID FAIL");
}

Thoughts?


Solution

  • A good way to check if you should even bother trying to load a webpage is with Reachability.

    NetworkStatus currentStatus = [[Reachability reachabilityForInternetConnection] 
                                   currentReachabilityStatus];
    
    if(currentStatus == kReachableViaWWAN) // 3G
    
    else if(currentStatus == kReachableViaWifi) // ...wifi
    
    else if(currentStatus == kNotReachable) // no connection currently possible
    

    If you don't even start the webView loading when no connection is possible, you can probably avoid this scenario altogether.

    A fix for the odd behaviour, though: In your refresh method try checking if it's loaded anything at all yet, and if not then call loadRequest:requestObj there. For example:

    - (IBAction)reloadWebView {
        if(webView.request != nil)
            [webView reload];
        else {
            // reconstruct requestObj here, or use a class member
            [webView loadRequest:requestObj];
        }
    
        NSLog(@"RELOAD");
    }