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

SwiftUI中使用WebKit的evaluateJavaScript调用JavaScript函数失败求助

解决SwiftUI中WebKit调用JavaScript函数失败的问题

从你给出的错误信息来看,核心问题是调用retrieveChartData时,这个JavaScript函数还没有被加载到网页的全局上下文中,或者你的代码逻辑存在调用时机错误。我给你几个具体的解决建议:


1. 修复导航代理方法的位置(最关键错误)

你现在把webView(_:didFinish:)方法写在了WebView结构体里,但你设置的WKWebView的navigationDelegate是Coordinator实例,这个方法根本不会被触发!也就是说你以为会在页面加载完成后调用JS函数,但实际上这段代码从来没执行过。

把这个方法移到Coordinator类里,这样页面加载完成时才会正确回调:

class Coordinator: NSObject, WKNavigationDelegate {
    let parent: WebView
    
    init(_ parent: WebView) {
        self.parent = parent
    }
    
    // 把didFinish方法移到这里!
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("页面加载完成,准备调用JS函数")
        // 注意给字符串参数加引号,避免JS解析错误
        let jsCommand = "retrieveChartData('\(parent.ticker)')"
        webView.evaluateJavaScript(jsCommand) { result, error in
            guard error == nil else {
                print("调用失败:\(error!)")
                return
            }
            print("调用成功,结果:\(result ?? "无返回值")")
        }
    }
}

2. 调整updateUIView的执行顺序

你现在在updateUIView里先调用evaluateJavaScript再加载网页,这完全搞反了顺序——网页还没加载,JS函数肯定不存在。修改成先加载网页,剩下的交给导航代理的didFinish处理:

func updateUIView(_ uiView: WKWebView, context: Context) {
    print("准备加载网页:\(url)")
    uiView.load(URLRequest(url: url))
}

3. 确保JavaScript函数在全局作用域

检查你网页里的retrieveChartData函数,必须定义在全局window对象上,这样WebKit才能访问到。比如:

// 正确的全局定义方式
function retrieveChartData(ticker) {
    // 你的函数逻辑
}

// 或者显式挂载到window,确保全局可访问
window.retrieveChartData = function(ticker) {
    // 你的函数逻辑
};

如果函数是在某个局部作用域(比如document ready回调里)定义的,WebKit的evaluateJavaScript是访问不到的。

4. 调试JS上下文确认函数存在

可以在didFinish方法里先执行一段调试代码,用Safari的Web Inspector查看结果:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    // 先检查函数是否存在
    webView.evaluateJavaScript("console.log('retrieveChartData:', window.retrieveChartData)") { _, _ in
        // 打开Safari -> 开发 -> 你的模拟器/设备 -> 对应的网页
        // 在控制台可以看到输出,确认函数是否存在
    }
    // 再调用目标函数
    let jsCommand = "retrieveChartData('\(parent.ticker)')"
    webView.evaluateJavaScript(jsCommand) { result, error in
        // ... 处理结果
    }
}

按照上面的步骤调整后,应该就能正确调用到JavaScript函数了。

内容的提问来源于stack exchange,提问作者user18835126

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 19:47:51