このブログ用に作っているサンプルアプリで、WKWebViewを使っているものがあります。先日、Xcodeを11.4にアップデートしたところ、このアプリがクラッシュするようになってしまいました。
対応方法などを記事にまとめました。
結論
結論を先に書くと、WebKit.framework
のリンクを追加することで修正されました。詳細を記事にまとめました。
症状と対応方法
発生している症状をまとめると次の通りです。
- iPhone 11 (13.4) シミュレータでアプリを起動しようとすると、クラッシュする。
- iPhone 11 (13.2.2) シミュレータでアプリを起動すると、クラッシュせずに正常に動作する。
クラッシュログ
クラッシュログが出力されているので、見てみました。
2020-03-27 11:13:19.558831+0900 EmbedWebBrowser[2025:60003] *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named WKWebView because no class named WKWebView was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target)'
*** First throw call stack:
... 以下省略
長いので、コールスタックの部分は省略します。また、重要なメッセージはこれです。
reason: 'Could not instantiate class named WKWebView because no class named WKWebView was found;
つまり、WKWebView
が見つからないためにクラッシュしています。WKWebView
はWebKit.framework
に入っているので、WebKit.framework
のリンク追加で修正できそうです。
修正方法
次のように操作します。
(1) ターゲットの設定を開き、Generalタブを表示する。
(2) 「Frameworks, Libraries, and Embedded Content」の「+」ボタンをクリックする。
(3) WebKit.framework
を選択して、「Add」ボタンをクリックする。
WebKit.framework
へのリンクが追加され、今度は起動できるようになるはずです。試してみると、クラッシュせずに起動でき、サイトを表示することもできました。
iOS 13.2.2までは起動できていた理由
XcodeというかLLVMには、フレームワークへの自動リンク機能があります。Swiftのimport
やObjective-Cの#import
で必要なフレームワークに自動的にリンクする機能です。
この機能は、ビルド設定で有効化できます。Xcode 11で作ったプロジェクトではデフォルトで有効になっており、サンプルアプリのプロジェクトでも有効になっています。
この機能により、iOS 13.2.2までは起動できていたはずです。しかし、iOS 13.4では明示的なリンクが必要でした。自動リンク機能は、Clang/LLVMのModules機能により実現されていたはずなので、WebKit.framework
のビルド時にオプションが無効になっているのではないかと思われます。
https://clang.llvm.org/docs/Modules.html
実機での動作
この問題はWebKit.framework
を明示的にリンクすれば回避できますが、既にリリースされているアプリは大丈夫なのだろうかと心配されます。
実機での動作も確認してみましたが、同様に明示的なリンクを追加していない場合にはクラッシュしてしまいました。
試した環境は以下の通りです。
- iPhone Xs + iOS 13.4
他のフレームワークでもクラッシュしてしまうものを見つけたときは、明示的なリンク追加を試してみましょう。