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
相关产品推荐
相关产品推荐

