はじめに
Chrome拡張を作成した際にJavaScriptのMutationObserverというものを知りました。
WKWebViewでも動いたので方法を記録しておきます。
「HTMLを監視して変化があったら処理を実行できる」という機能だと認識しています。
普段、ほとんどiOSしかやってないので全く知りませんでした。
WebViewは以下のコードを使用します。
サンプルアプリ
「Googleでログイン」と「Appleのアカウントでログイン」を非表示にします。
実装
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を使用すれば動的サイトでも要素の非表示が簡単になりました。