Swift中WKWebView调用invokeUndefinedMethodFromWebScript失效求助
WKWebView JS-Swift 交互问题解决思路
嘿,我懂你刚接触Swift,想用WKWebView实现JS和Swift交互时卡壳的心情——你之前用的是UIWebView时代的老方法,但WKWebView的交互逻辑完全不一样,这就是点击按钮没反应的核心原因!
问题根源
你重写的invokeUndefinedMethod(fromWebScript:withArguments:)是UIWebView专属的方法,WKWebView根本不支持这套机制。WKWebView采用的是基于WKUserContentController的消息传递体系,必须显式注册JS可调用的接口,再通过协议方法处理交互请求。
正确实现方案
1. Swift端代码修改
我们需要遵循WKScriptMessageHandler协议,配置内容控制器并注册消息处理器,同时处理JS请求并返回结果:
import WebKit class ViewController: NSViewController, WKUIDelegate, WKScriptMessageHandler { @IBOutlet weak var wkWebView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // 配置WKWebView的内容控制器 let userContentController = WKUserContentController() // 注册JS可调用的消息标识,这里命名为"MY_SwiftFunction" userContentController.add(self, name: "MY_SwiftFunction") // 创建配置对象并关联内容控制器 let configuration = WKWebViewConfiguration() configuration.userContentController = userContentController configuration.preferences.javaScriptEnabled = true // 如果是Storyboard关联的WebView,也可以重新赋值确保配置生效 wkWebView = WKWebView(frame: view.bounds, configuration: configuration) wkWebView.uiDelegate = self view.addSubview(wkWebView) // 加载本地服务页面 let url = URL(string: "http://127.0.0.1:8080")! let request = URLRequest(url: url) wkWebView.load(request) } // 实现WKScriptMessageHandler协议方法,处理JS发来的消息 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { // 校验消息标识,确保是我们注册的接口 if message.name == "MY_SwiftFunction" { // 这里可以获取JS传递的参数:message.body let responseText = "Hello From Swift" // 通过evaluateJavaScript把结果回调给JS,直接设置输入框的值 wkWebView.evaluateJavaScript("document.getElementById('i').value = '\(responseText)'") { result, error in if let error = error { print("JS执行出错: \(error)") } } } } // 控制器销毁时移除消息处理器,避免内存泄漏 deinit { wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "MY_SwiftFunction") } }
2. HTML端代码修改
WKWebView中JS不能使用window.external,需要通过webkit.messageHandlers调用Swift注册的接口:
<html> <body> <p>Hello World</p> <input type=text id='i'/> <input type=button value='Submit' onclick='webkit.messageHandlers.MY_SwiftFunction.postMessage(null);'> </body> </html>
额外提示
- 如果需要JS给Swift传递参数,只需在
postMessage()中传入数据(比如postMessage("用户输入内容")),在Swift的message.body中即可获取。 - 如果需要Swift主动调用JS逻辑,直接使用
wkWebView.evaluateJavaScript(_:completionHandler:)方法即可。
内容的提问来源于stack exchange,提问作者Arundale Ramanathan
相关产品推荐
相关产品推荐

