WKWebView の WKUserContentController に気をつけろ!

概要

WKUserContentController の add(_ scriptMessageHandler:, name: ) メソッドは scriptMessageHandler を強参照するので気をつけよう と言う話です。

WKWebView で JS のメソッドをフックしたい時は下記のように「WKUserContentController に
hoge メソッドが実行されたら self に教えてね」と言うコードを書きます。

final class WebViewController: UIViewController {

    private let webView = WKWebView()

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.configuration.userContentController.add(self, name: "hoge")
    }
}

しかしのこのコードは循環参照を起こします。

原因

WKUserContentController の add メソッドですが、実は 第一引数を強参照します。
もしこの第一引数が WKWebView への参照を保持していれば循環参照が起きてしまいます。
まさに上記のようなコードです。

対応策

今回は下記のクラスを用意して擬似的に弱参照になるようにして循環参照を回避しました。

final class WeakScriptMessageHandlerReference: NSObject, WKScriptMessageHandler {

    private weak var handler: WKScriptMessageHandler?

    init(to handler: WKScriptMessageHandler) {
        self.handler = handler
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        handler?.userContentController(userContentController, didReceive: message)
    }
}

add メソッド呼び出し部分を変更

let reference = WeakScriptMessageHandlerReference(to: self)
webView.configuration.userContentController.add(reference, name: "hoge")

まとめ

いつまた同じようなことが起きるか油断できないので定期的にメモリ使用量とメモリグラフを確認しましょう。

参考

Apple の公式リファレンス – add(_:name:)
WKWebView causes my view controller to leak – Stackoverflow

プライバシーポリシー

本プライバシーポリシーは StudioRookery(以下、「当サイト」とします) の各種サービス(当サイトによる情報提供、各種お問合せの受付等)において、当サイトの利用者(以下、「利用者」とします。)の個人情報もしくはそれに準ずる情報を取り扱う際に、当サイトが遵守する方針を示したものです。

基本方針

当サイトは、個人情報の重要性を認識し、個人情報を保護することが社会的責務であると考え、個人情報に関する法令を遵守し、当サイトで取扱う個人情報の取得、利用、管理を適正に行います。当サイトで収集した情報は、利用目的の範囲内で適切に取り扱います。

適用範囲

本プライバシーポリシーは、当サイトおよび当サイトの各種サービスにおいてのみ適用されます。

個人情報の取得と利用目的

当サイトで取得する訪問者の個人情報と利用目的は下記の通りです。

広告配信

当サイトの各種サービスは広告配信のため AdMob を利用しているものがあります。
AdMob についての詳細はこちらをご参照ください。

利用状況解析

当サイトの各種サービスは利用状況解析のため Google Firebase Analytics および Fabric を利用しているものがあります。

これらのツールの利用によりアプリの操作データや Cookie を収集していますが、トラフィックデータは匿名で収集されており個人を特定するものではありません。

Google Firebase Analytics によって収集されたデータは Googleの プライバシーポリシー に基づいて管理されます。

Fabric によって収集されたデータは Fabric の プライバシーポリシー に基づいて管理されます。

その他

利用者からのお問い合わせ内容や不具合報告などにメールアドレスやアプリのデータなどの個人情報が含まれる場合があります。

個人情報の安全対策

当サイトは、個人情報の正確性及び安全性確保のために、セキュリティに万全の対策を講じています。

ご本人の照会

ユーザーがご本人の個人情報の照会・修正・削除などをご希望される場合には、ご本人であることを確認の上、対応させていただきます。

法令、規範の遵守と見直し

当運営者は、保有する個人情報に関して適用される日本の法令、その他規範を遵守するとともに、本ポリシーの内容を適宜見直し、その改善に努めます。
この方針は、事業内容の変更、法令の改正等により、事前に公表することなく任意の時期に変更される場合があります。