Как определить причину сбоя 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];
}];