Xcode 9でビルドしてからWKWebViewで突然落ちるようになったときには

注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。

Xcode及びiOS/macOS SDKは、定期的にバージョンアップが提供され、バグフィックスや新機能の追加がなされている。とはいえ、気づかぬうちに挙動が変更されるということもあり、その中にはアプリクラッシュに直結するものまである。今回はWKWebViewを使っているときに遭遇するであろう事象について説明したい。

さて、私が今回取り上げる事例は、任意のWKNavigationDelegateを実装しているクラスで以下のようなコードを書いていた場合、Xcode 9/iOS 11 SDKではクラッシュするようになったというものである。Xcode 8.xではiOS 11でもクラッシュせずに動いたものである。

Swiftで書いた場合は以下の通りである。

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if shouldAllow {
        decisionHandler(.allow)
    }
    decisionHandler(.cancel)
}

Objective-Cなら以下の通りである。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (shouldAllow) {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    decisionHandler(WKNavigationActionPolicyCancel);
}

上記のコードの場合、(これも問題なのだが)Xcode 8.xではクラッシュしなかったものであるが、Xcode 9.0/iOS 11 SDK環境では呼び出し回数チェックをするようになったのか、2回目に読んだ際にアプリクラッシュするようになっている。

このクラッシュを防ぐには、decisionHandler()を呼び出したら、returnなどで抜けるか、elseなどで多重コールしないようにすることである。

この件に関しては、decisionHandler()を複数回呼び出していたというライブラリーで問題になったことで発覚したもので、修正依頼は来ているものの、まだ反映はされていないようである。

新そのコードが正しいものなのかチェックするということは必要である。特に、間違ったコードでこれまでは問題なく動いていたように見えたのに、突然クラッシュするようになったということもあるからである。

タイトルとURLをコピーしました