【问题标题】:iOS App - Set Timeout for UIWebView loadingiOS App - 为 UIWebView 加载设置超时
【发布时间】:2012-07-21 21:01:13
【问题描述】:

我有一个加载单个 UIWebView 的简单 iOS 本机应用程序。如果应用程序未在 20 秒内完全加载 webView 中的初始页面,我希望 webView 显示错误消息。

我在viewDidLoad 中加载 webView 的 URL,如下所示(简化):

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com"] cachePolicy:NSURLCacheStorageAllowed timeoutInterval:20.0]];

上面代码中的 timeoutInterval 实际上并没有“做”任何事情,因为 Apple 在操作系统中将其设置为实际上不会超时 240 秒。

我设置了webView didFailLoadWithError 操作,但如果用户有网络连接,则永远不会调用它。 webView 只是继续尝试加载我的 networkActivityIndi​​cator 旋转。

有没有办法为 webView 设置超时?

【问题讨论】:

  • 这里有人说超时间隔是为了连接。一旦它连接到服务器,它就不会再抛出错误了。您需要在 webViewDidStartLoad 连接后实现自己的 NSTimer 并自行取消 stackoverflow.com/questions/1883888/…
  • 这看起来正是我正在寻找的......你能给我一些关于如何实现它的指导吗? (我是 Objective-C 的新手)
  • 我只需要知道该放什么:-(void)webView: NSTimer * theTimer { NSLog(@"Me is here at 1 minute delay"); } 我会使用哪种目标方法?
  • 我刚刚写了一个非常基本的代码,你可能想从它开始:) 希望对你有帮助

标签: xcode ios5 uiwebview timeout loading


【解决方案1】:

timeoutInterval 用于连接。 webview 连接到 URL 后,您需要启动 NSTimer 并进行自己的超时处理。比如:

// define NSTimer *timer; somewhere in your class

- (void)cancelWeb
{
    NSLog(@"didn't finish loading within 20 sec");
    // do anything error
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [timer invalidate];
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    // webView connected
    timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(cancelWeb) userInfo:nil repeats:NO];
}

【讨论】:

  • 我添加了上面的方法,但20秒后它没有任何作用? - 我在cancelWeb 属性中放入了一个 UIAlertView,但它从不触发。
  • 抱歉有一处改动,不是NSTimer timerWithTimeInterval,而是scheduledTimerWithTimeInterval。一旦你的 webView 连接到 URL,webViewDidStartLoad 就会被调用。如果没有,您没有正确设置委托。然后该方法启动计时器以在 20 秒内调用 cancelWeb 方法。
  • 非常感谢!!!完美运行 :) 还有一个问题 - 如果他们在 viewWillDisappearviewDidUnload 中退出应用程序,我是否需要做任何事情来释放计时器?
  • 您可以使用某种标志变量跳过第一个 webViewDidStartLoad。当用户单击第一页中的链接时,webView 将启动并每次再次调用 webViewDidStartLoad。您需要通过用户的点击确定它是第一次加载还是稍后加载。或者你可以插入 js 来处理用户的点击,但这可能太多了。我希望这能回答你的问题
  • 哦,我明白了。太糟糕了。您可能需要在 jquery-mobile 上交流您的代码和 js 代码。我会尝试使用 stringByEvaluatingJavaScriptFromString:,或者这可能会工作 stackoverflow.com/questions/5671742/… 。我什至考虑使用 phonegap 或某种 webView 基础框架……抱歉,我帮不上什么忙
【解决方案2】:

我的方式类似于接受的答案,但只是在超时时停止加载并控制在 didFailLoadWithError 中。

- (void)timeout{
    if ([self.webView isLoading]) {
        [self.webView stopLoading];//fire in didFailLoadWithError
    }
}

- (void)webViewDidStartLoad:(UIWebView *)webView{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timeout) userInfo:nil repeats:NO];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    [self.timer invalidate];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{
    //Error 999 fire when stopLoading
    [self.timer invalidate];//invalidate for other errors, not time out. 
}

【讨论】:

  • 这是更好的答案,因为它实际上会在超时后停止 Web 视图。我还建议将self.timer 设置为nil 在您使其无效并完成之后。
【解决方案3】:

Swift 程序员可以这样做:

var timeOut: NSTimer!

   func webViewDidStartLoad(webView: UIWebView) {
    self.timeOut = Timer.scheduledTimer(timeInterval: 7.0, target: self, selector: Selector(("cancelWeb")), userInfo: nil, repeats: false)
}

func webViewDidFinishLoad(webView: UIWebView) {
    self.timeOut.invalidate()
}

func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
    self.timeOut.invalidate()
}

func cancelWeb() {
    print("cancelWeb")
}

【讨论】:

    【解决方案4】:

    所有建议的解决方案都不理想。处理此问题的正确方法是在 NSMutableURLRequest 本身上使用 timeoutInterval:

    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://web.site"]];
    
    request.timeoutInterval = 10;
    
    [webview loadRequest:request];
    

    【讨论】:

    • 超时后会不会调用didFailToLoad withError
    • @AlbertRenshaw 是的,它会自动调用委托方法
    猜你喜欢
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2011-09-03
    • 2013-03-14
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多