Как определить причину сбоя WKWebView
Я использую WKWebView в приложении Swift, созданном для iOS 8+. Я использую экземпляры WKWebView во множестве представлений в моем приложении, например. в каждой вкладке в моем контроллере представления вкладок интерфейс основан на WKWebView.
Я и мои тестеры заметили, что эти взгляды иногда заканчиваются совершенно пустыми, и после изучения этой проблемы кажется, что WKWebView может сбой, и пустой результат является результатом. К счастью, это не сбивает приложение из-за того, как работает WKWebView, но я также не понимаю, как ловить/записывать информацию о том, что вызвало его сбой (если это на самом деле происходит).
Как определить, если/почему WKWebView разбился?
Мое текущее решение проблемы заключается в том, что я использую KVO (фактически, Facebook KVOController), чтобы отслеживать свойство URL-адреса WKWebView, и если он идет от non-nil до nil, я предполагаю, что произошел сбой, и я перезагружаю webview:
kvoController?.observe(webView, keyPath: "URL", options: NSKeyValueObservingOptions.New|NSKeyValueObservingOptions.Old) { (areaViewController, webView, change) -> Void in
if change[NSKeyValueChangeNewKey] is NSNull && !(change[NSKeyValueChangeOldKey] is NSNull) {
areaViewController.setup() // reload our webview
}
}
Но, очевидно, было бы неплохо выяснить основную причину сбоя.
Ответы
Ответ 1
Это очень неприятная проблема WKWebView, с которой мы столкнулись в Firefox для iOS.
См. следующий отчет об ошибке https://bugs.webkit.org/show_bug.cgi?id=148685
У меня нет отличного решения, но у меня есть два совета:
Во-первых, мы также выполняли перезагрузку, когда мы узнали через KVO, что webView.URL
повернул nil
. Однако оказывается, что он превращает nil
в ряд событий. Например, когда происходит перенаправление и, возможно, также при отправке формы. Так что это не идеально.
Во-вторых, в iOS9 существует новый API для обнаружения, когда процесс содержимого WebKit умер. Мы еще не пробовали это, но я думаю, что это будет лучший триггер для перезагрузки webView.
Пока еще нет документации, но вы можете увидеть это в файлах заголовков:
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
Ответ 2
- (void) webViewWebContentProcessDidTerminate: (WKWebView *) webView NS_AVAILABLE (10_11, 9_0); Этот делегат получает вызов только в iOS9.but, если вы перезагружаете webview, вы потеряете всю сохраненную информацию о состоянии.
возможно, может сохранить информацию для вызова [webview reload]
например:
NSString *jsString = @"var arry=[];
for(var i=0; i<sessionStorage.length; i++){
var a={};a[sessionStorage.key(i)]=sessionStorage.getItem(sessionStorage.key(i));arry.push(a)};arry";
[webView evaluateJavaScript:jsString completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
NSLog(@"jsString1===error=%@",error);
NSLog(@"jsString1==obj==®%@",obj);
if (obj == NULL ||obj ==[NSNull class]||obj==nil) {
//重启webview
[webView reload];
return ;
}
//保存sessionStorage
NSArray *arr = (NSArray*)obj;
//保存后重启webview
[webView reload];
}];