iOS应用程序 - 为UIWebView加载设置超时

时间:2012-07-23 15:32:10

标签: xcode ios5 uiwebview timeout loading

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

我在viewDidLoad中加载了我的网址,就像这样(简化):

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

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

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

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

4 个答案:

答案 0 :(得分:41)

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

答案 1 :(得分:7)

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

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

request.timeoutInterval = 10;

[webview loadRequest:request];

答案 2 :(得分:3)

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

- (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. 
}

答案 3 :(得分:2)

Swift程序员可以这样做:

var timeOut: NSTimer!

func webViewDidStartLoad(webView: UIWebView) {
    self.timeOut = NSTimer.scheduledTimerWithTimeInterval(7.0, target: self, 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")
}