iPhone - UIWebView 在没有数据连接的情况下不调用 didFailLoadWithError

Posted

技术标签:

【中文标题】iPhone - UIWebView 在没有数据连接的情况下不调用 didFailLoadWithError【英文标题】:iPhone - UIWebView not calling didFailLoadWithError without data connection 【发布时间】:2011-09-02 02:34:41 【问题描述】:

我已经搜索并没有找到解决方案,所以希望有人可以提供帮助。

我有一个 UIWebView,当用户按下按钮时会调用它。一切都很好,除非您考虑到手机没有数据连接时的行为。

在手机处于飞行模式或没有数据连接的情况下第一次尝试打开 UIWebView:

UIWebView 开始加载 加载失败

一旦分配了 UIWebView 并且第一次加载失败,点击链接到 IBAction(调用 [webView reload])的刷新按钮会导致:

无论手机在初始加载失败后是否有数据连接,都会调用刷新IBAction,但我的NSLogs告诉我既没有调用webViewDidStartLoad、webViewDidFinishLoad,也没有调用webView...didFailLoadWithError。

如果我让应用程序运行并打开与设备的数据连接(例如关闭飞行模式),然后返回我的应用程序并点击刷新按钮,[webView reload] 被调用,但 webViewDidStartLoad(因此webViewDidFinishLoad) 未被调用。

下面是相关代码:

要调出 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];


重新加载:

  -(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");

想法?

【问题讨论】:

【参考方案1】:

使用Reachability 是检查您是否应该尝试加载网页的好方法。

NetworkStatus currentStatus = [[Reachability reachabilityForInternetConnection] 
                               currentReachabilityStatus];

if(currentStatus == kReachableViaWWAN) // 3G

else if(currentStatus == kReachableViaWifi) // ...wifi

else if(currentStatus == kNotReachable) // no connection currently possible

如果您在无法连接时甚至不启动 webView 加载,您可能完全可以避免这种情况。

一个奇怪行为的修复,但是:在你的刷新方法中尝试检查它是否已经加载了任何东西,如果没有,那么在那里调用loadRequest:requestObj。例如:

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

    NSLog(@"RELOAD");

【讨论】:

darvids0n,关于最初依赖可达性而不是我自己做的好点。我知道这门课,但想看看我自己是否可以轻松完成。无论哪种方式,使用 Reachability 绝对是要走的路,如果只是因为 UIWebView 不是我认为我们很多人可能想要的那样。非常感谢!【参考方案2】:

我确实遇到了同样的问题

    第一次打开我的UIWebView手机在飞行模式或者没有数据连接的情况下,依次调用以下方法: -webView:shouldStartLoadWithRequest:navigationType: -webViewDidStartLoad: -webView:didFailLoadWithError 然后,我点了刷新按钮,也就是说,我调用了UIWebView-reload方法,没有调用委托方法,所以我什至无法收到超时通知。

我的解决方案是:

在加载或重新加载请求之前检查网络可达性状态,非常感谢@darvids0n的好建议(但我发现request不是nil,当请求第一次失败后重新加载时)。 使用 loadRequest: 而不是 reload 重新加载当前 URL。 实现我自己的超时机制,比如reload/load请求后20s,如果没有调用委托方法,我就当作超时,取消请求和loadingHUD动画。

其他一些类似问题

404 (or similar codes) aren't considered errors by UIWebView, because a html response was received.

【讨论】:

以上是关于iPhone - UIWebView 在没有数据连接的情况下不调用 didFailLoadWithError的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 的 uiwebview 中没有播放音频

在 iPad 和 iPhone 上显示 UIwebview

UIWebview 在 iPhone 设备上很慢,在模拟器上很快

iPhone - UIPickerView 和 UIWebView 上的手势

是否可以使用 UIWebView 方法在 iphone 本机应用程序中播放 vimeo 视频?

iPhone 上禁用了条形图标,但 iPad 上没有