Подтвердить что ты не робот

Приложение iOS - установка таймаута для загрузки UIWebView

У меня есть простое родное приложение iOS, которое загружает один UIWebView. Я хотел бы, чтобы webView отображал сообщение об ошибке, если приложение НЕ ПОЛНОСТЬЮ завершает загрузку начальной страницы в webView в течение 20 секунд.

Я загружаю свой URL-адрес для webView в свой viewDidLoad как это (упрощенный):

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

timeoutInterval в приведенном выше коде фактически ничего не делает, так как Apple установила его в OS, чтобы на самом деле не было времени на 240 секунд.

У меня установлены мои действия webView didFailLoadWithError, но если у пользователя есть сетевое соединение, это никогда не будет вызвано. WebView просто продолжает загружаться с помощью функции networkActivityIndicator.

Есть ли способ установить тайм-аут для webView?

4b9b3361

Ответ 1

Тайм-аутInterval для подключения. Когда веб-просмотр подключен к 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];
}

Ответ 2

Все предлагаемые решения не идеальны. Правильный способ справиться с этим - использовать timeoutInterval в самом NSMutableURLRequest:

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

request.timeoutInterval = 10;

[webview loadRequest:request];

Ответ 3

Мой способ похож на принятый ответ, но просто 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. 
}

Ответ 4

Скоростные кодеры могут делать это следующим образом:

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")
}