Приложение 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?
Ответы
Ответ 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")
}