You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()
    }
}

关键说明

  1. 配置必须在初始化时完成
    WKWebViewConfiguration只能在创建WKWebView实例前修改,实例创建后configuration变为只读属性,任何后续修改都不会生效。

  2. 避免updateUIView的冗余操作
    updateUIView会在视图状态变化时多次调用,把加载请求、清理缓存这类一次性操作放在makeUIView中,只执行一次,避免重复请求和不必要的性能损耗。

  3. 动态注入脚本的替代方案
    如果需要根据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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:25:18