Mason G. Zhwiti
Mason G. Zhwiti

Reputation: 6530

How to determine why WKWebView is crashing

I am using WKWebView in a Swift app built for iOS 8+. I use instances of WKWebView in a variety of views in my app, e.g. in each of the tabs in my tab view controller, the interface is based on WKWebView.

I and my testers have noticed these views sometimes go completely blank, and after researching that issue, it seems that WKWebView can crash, and the blank view is the result. Luckily, it doesn't bring down the app due to the way WKWebView operates, but I also am not clear on how to trap/log information about what caused it to crash (if that is actually what is happening).

How can I determine if/why a WKWebView has crashed?

My current workaround for the issue is that I use KVO (actually, Facebook's KVOController), to monitor the "URL" property of the WKWebView, and if it goes from non-nil to nil, I assume a crash has happened, and I reload the 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
    }
}

But obviously it would be nice to figure out the root cause of the crash.

Upvotes: 16

Views: 12090

Answers (2)

iosdeveloperchn
iosdeveloperchn

Reputation: 1

  • (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0); This delegate getting called only in iOS9.but if you reload webview ,you will lost all of the state information stored. maybe can save info befor called [webview reload]

for example:

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

Upvotes: 0

Stefan Arentz
Stefan Arentz

Reputation: 34935

This is very nasty WKWebView issue that we also encountered in Firefox for iOS.

See the following bug report https://bugs.webkit.org/show_bug.cgi?id=148685

I have no great solution but I do have two tips:

First, we were also doing the reload when we found out via KVO that webView.URL turned nil. However it turns out that it turns nil on a number of events. For example when a redirect happens and possibly also when a form is submitted. So this is not ideal.

Second, in iOS9 there is a new API to detect when the WebKit content process has died. We have not tried this yet but I think that will be a better trigger to reload the webView.

There is no documentation yet I think, but you can see this in the header files:

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);

Upvotes: 11

Related Questions