【Swift】WebKitのSendable-related warningsの対応

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」の影響ですが、今まで意識できていなかった部分も、こうやって明示してくれると(大変な部分はあるけど)理解できるようになるので良いですね。

コメント

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