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()
を複数回呼び出していたというライブラリーで問題になったことで発覚したもので、修正依頼は来ているものの、まだ反映はされていないようである。
新そのコードが正しいものなのかチェックするということは必要である。特に、間違ったコードでこれまでは問題なく動いていたように見えたのに、突然クラッシュするようになったということもあるからである。
ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。主にスマートフォン向けアプリやウェブアプリの開発を携わっています。ご用の方はコメントかコンタクトフォームにて。