javascript - SwiftUI:在 macOS 上与 WKWebView 进行 Javascript 通信
问题描述
我希望 javascript 将消息发送回我的 WKWebView 对象,但我没有得到任何回应。我知道脚本正在运行,随着颜色的变化,但我希望在控制台中也能看到“来自 JS 的触发器”,但我没有。如果我在 Chrome 中运行 html,javascript 控制台会显示“无法读取未定义的属性 'messageHandlers'”。如果我为 iOS 构建(使用 UIViewRepresentable、MakeUIView 和 UpdateUIView),结果是一样的。如果有人能发现我错过的东西,我将不胜感激。
这是整个代码:
import SwiftUI
import WebKit
class HtmlData {
let html = """
<!DOCTYPE html>
<html>
<body>
<button onclick="sendMessage()">Send Message</button>
<script>
function sendMessage() {
document.body.style.backgroundColor = "red";
window.webkit.messageHandlers.testMessage.postMessage("trigger from JS");
}
</script>
</body>
</html>
"""
}
struct ContentView: View {
let htmlData = HtmlData()
var body: some View {
JSWebView(html: htmlData.html)
}
}
struct JSWebView: NSViewRepresentable {
let html: String
func makeNSView(context: Context) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
return WKWebView()
}
func updateNSView(_ view: WKWebView, context: Context) {
let userContentController = WKUserContentController()
let handler = ContentController(view)
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
configuration.userContentController.add(handler, name: "testMessage")
view.loadHTMLString(html, baseURL: Bundle.main.bundleURL)
}
class ContentController: NSObject, WKScriptMessageHandler {
var parent: WKWebView?
init(_ parent: WKWebView?) {
self.parent = parent
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.body)
}
}
}
解决方案
配置必须传入 WKWebView 的构造函数。初始化后无法设置。
struct JSWebView: NSViewRepresentable {
let html: String
func makeNSView(context: Context) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let handler = MessageHandler()
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(handler, name: "testMessage")
return WKWebView(frame: .zero, configuration: configuration)
}
func updateNSView(_ view: WKWebView, context: Context) {
view.loadHTMLString(html, baseURL: Bundle.main.bundleURL)
}
class MessageHandler: NSObject, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.body)
}
}
}
推荐阅读
- javascript - 如何重叠 iframe 标签的内容
- r - 在 R 中使用正则表达式从链接中提取字符串
- amazon-web-services - DynamoDB 读/写操作需要多长时间?
- node.js - 从 Web 浏览器调用普通套接字
- javascript - 如何使用 QuickChart 更改 Chart.js 图像渲染的字体和轴标签?
- angular - Ionic/Angular - 大屏幕的菜单图标消失
- python - 为什么包含 futures.ThreadpoolExecutor 的类方法在某些情况下不运行?
- kubernetes - kubectl exec 进入容器而不使用 pod 名称末尾的随机 guid
- python - 检查csv文件是否存在并满足条件?
- three.js - Raycaster 无法检测到立方体