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?
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");
}
I did encounter the same problem:
- Open my
UIWebView
for the first time with the phone on airplane mode or without a data connection, the following methods were called in turn:-webView:shouldStartLoadWithRequest:navigationType:
-webViewDidStartLoad:
-webView:didFailLoadWithError
- Then, I tapped refresh button, that's to say, I called
UIWebView
's-reload
method, no delegate method was called, so I even couldn't get a timeout notification.
My solution is:
- Check network reachability status before load or reload requests, many thanks to @darvids0n's great advice(But I found out the
request
is notnil
when reload after the request failed for the 1st time). - Use
loadRequest:
to reload the current URL instead ofreload
. - Implement my own timeout mechanism, such as, 20s after reload/load request, if no delegate methods were called, I take it as a timeout, and cancel requests and loadingHUD animation.
Some other similar issues:
- 404 (or similar codes) aren't considered errors by UIWebView, because a HTML response was received.
精彩评论