Xcode16に更新したところWebKitのimportで以下のような警告が表示されるようになり、対応方法を調べたので紹介します。
Add ‘@preconcurrency’ to suppress ‘Sendable’-related warnings from module ‘WebKit’
原因
私の開発しているプロジェクトでは、WKNavigationDelegateやWKUIDelegateを実装しています。
このdelegateメソッドのうち、引数にdecisionHandler
,completionHandler
等のクロージャを持つものについて、以下のように実装していました。
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// 必要な処理を記載…
}
上記はXcode15でWebKitに定義されていたメソッド定義を使っていましたが、Xcode16では次のように更新されていました。
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping @MainActor (WKNavigationActionPolicy) -> Void) {
// 必要な処理を記載…
}
違いはクロージャに対する@MainActorの有無になります。
上記の違いを元に、メソッド引数のクロージャ全てに@MainActorを追加したところ、警告が消えました。
このため、対応方法としては
WKNavigationDelegate / WKUIDelegateのメソッド定義を最新に更新する(クロージャに@MainActorを付与する)
となります。
警告の意味
警告文を素直に読むと、「WebKitがSendableに対応していないから、’@preconcurrency’を追加してスレッドセーフではないことを明示してね」と読めます。
意味合いとしては、並列実行された場合、データの安全性が確保できていないよ、ということを指しています。
WebKitはUIKitの一部であり、メインスレッドでの実行を前提としており、それによってデータの安全性を担保している認識です。(非同期に対応していない)
上記に対し、今回は「@MainActor」の定義が抜けていたため、非同期実行できる体に見えるけど、Sendableに対応していないため、スレッドセーフではないよという意味で警告でていた…という理解です。
まとめ
warningの警告文と原因の紐付けがわかりづらく、理解するまでに時間がかかりましたが、原因がわかればとても単純でした。
Xcode16でデフォルトで機能することになった「Strict Concurrency Checking」の影響ですが、今まで意識できていなかった部分も、こうやって明示してくれると(大変な部分はあるけど)理解できるようになるので良いですね。
コメント