SwiftUI中向WKWebView注入CSS/JS失败,求技术指导
问题分析与解决方案
你的代码无法注入脚本的核心原因是:WKWebView创建后,其configuration对象是只读的,无法再修改添加用户脚本。你在updateUIView中尝试修改配置的操作完全无效,而且updateUIView会被SwiftUI多次触发,导致重复加载请求、清理缓存的冗余操作。
修改后的完整代码
import SwiftUI import WebKit struct WebView: UIViewRepresentable { func makeUIView(context: Context) -> WKWebView { // 1. 先创建配置对象,在这一步添加用户脚本 let config = WKWebViewConfiguration() // 注入自定义JS/CSS示例:这里的alert会在页面加载完成后触发 let userScript = WKUserScript( source: "alert('debug');", injectionTime: .atDocumentEnd, // 可选.atDocumentStart,根据需求选择注入时机 forMainFrameOnly: true ) config.userContentController.addUserScript(userScript) // 2. 清理缓存(仅执行一次,避免重复清理) WKWebsiteDataStore.default().removeData( ofTypes: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache], modifiedSince: Date(timeIntervalSince1970: 0) ) {} // 3. 使用配置好的config初始化WKWebView let webView = WKWebView(frame: .zero, configuration: config) // 4. 加载目标页面 guard let url = URL(string: "https://example.com") else { return webView } webView.load(URLRequest(url: url)) return webView } func updateUIView(_ webView: WKWebView, context: Context) { // 此方法用于响应SwiftUI状态变化,无特殊需求可留空 // 若需动态执行JS,可使用webView.evaluateJavaScript()方法,而非添加用户脚本 } } struct ContentView: View { var body: some View { WebView() } }
关键说明
配置必须在初始化时完成
WKWebViewConfiguration只能在创建WKWebView实例前修改,实例创建后configuration变为只读属性,任何后续修改都不会生效。避免
updateUIView的冗余操作updateUIView会在视图状态变化时多次调用,把加载请求、清理缓存这类一次性操作放在makeUIView中,只执行一次,避免重复请求和不必要的性能损耗。动态注入脚本的替代方案
如果需要根据SwiftUI的状态动态执行JS(而非页面加载时固定注入),可以在updateUIView中使用evaluateJavaScript方法:func updateUIView(_ webView: WKWebView, context: Context) { // 假设有一个@Binding状态控制脚本执行 // if shouldInjectScript { webView.evaluateJavaScript("document.body.style.backgroundColor = 'red';") { result, error in if let error = error { print("JS执行失败: \(error.localizedDescription)") } } // } }
内容的提问来源于stack exchange,提问作者Lasse
相关产品推荐
相关产品推荐

