LoginSignup
3
2

More than 1 year has passed since last update.

【SwiftUI】MutationObserverを使用してWKWebViewの要素をブロックする

Posted at

はじめに

Chrome拡張を作成した際にJavaScriptのMutationObserverというものを知りました。

WKWebViewでも動いたので方法を記録しておきます。

「HTMLを監視して変化があったら処理を実行できる」という機能だと認識しています。
普段、ほとんどiOSしかやってないので全く知りませんでした。

WebViewは以下のコードを使用します。

サンプルアプリ

「Googleでログイン」と「Appleのアカウントでログイン」を非表示にします。

simulator_screenshot_B379A600-6655-4A73-827F-8F108E7C6E5B.png simulator_screenshot_68AD93AF-6671-477D-98E0-0CC6955E7E05.png

実装

import SwiftUI
import WebKit

struct ContentView: View {
    var body: some View {
        WebView(url: url, configuration: configuration) { webView in
            webView.customUserAgent = customUserAgent
        }
    }

    var url: URL? {
        URL(string: "https://mobile.twitter.com/i/flow/login")
    }

    var customUserAgent: String {
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
    }

    var configuration: WKWebViewConfiguration {
        let mutationObserverScriptString = """
        const targetNode = document.body;
        const config = { attributes: true, childList: true, subtree: true };

        const callback = function(mutationsList, observer) {
            for (let mutation of mutationsList) {
                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                    const addedNodes = Array.from(mutation.addedNodes);
                    addedNodes.forEach(function(node) {
                        if (node.matches && node.matches('[data-testid=google_sign_in_container]')) {
                            node.style.display = 'none';
                        }
                        if (node.querySelector('[data-testid="apple_sign_in_button"]')) {
                            node.querySelector('[data-testid="apple_sign_in_button"]').style.display = 'none';
                        }
                        if (node.querySelector('.css-1dbjc4n.r-18u37iz.r-lz04qo.r-13qz1uu')) {
                            node.querySelector('.css-1dbjc4n.r-18u37iz.r-lz04qo.r-13qz1uu').style.display = 'none';
                        }
                    });
                }
            }
        };

        const observer = new MutationObserver(callback);
        observer.observe(targetNode, config);
        """
        let mutationObserverScript = WKUserScript(source: mutationObserverScriptString, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

        let controller = WKUserContentController()
        controller.addUserScript(mutationObserverScript)

        let configuration = WKWebViewConfiguration()
        configuration.userContentController = controller
        configuration.ignoresViewportScaleLimits = false

        return configuration
    }
}

おわり

MutationObserverを使用すれば動的サイトでも要素の非表示が簡単になりました。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2