web-dev-qa-db-ja.com

iOSアプリ-UIWebViewロードのタイムアウトを設定

単一の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は、OS内で実際に240秒間タイムアウトしないように設定しています。

私はwebView didFailLoadWithErrorアクションが設定されていますが、ユーザーがネットワーク接続を持っている場合、これは呼び出されません。 webViewはnetworkActivityIndi​​catorを回転させてロードを続けます。

WebViewのタイムアウトを設定する方法はありますか?

23
adamdehaven

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

提案されたすべてのソリューションは理想的ではありません。これを処理する正しい方法は、NSMutableURLRequest自体にtimeoutIntervalを使用することです。

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

request.timeoutInterval = 10;

[webview loadRequest:request];
7
Sandy Chapman

私の方法は受け入れられた回答に似ていますが、タイムアウトしたときにstopLoadingし、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. 
}
3
LE SANG

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")
}
2
Satnam Sync