我正在使用一个MacOS应用程序,它需要使用WKUserScript功能从网页向MacOS应用程序发送消息。我正在写一篇文章https://medium.com/capital-one-tech/javascript-manipulation-on-ios-using-webkit-2b1115e7e405,这篇文章展示了它在iOS中的工作原理,并且工作得很好。
然而,我已经挣扎了几个星期,试图让它在我的MacOS上工作。下面是我的示例代码,它遵从fine并运行,但未能成功打印在处理程序userContentController()中找到的消息
import Cocoa
import WebKit
class ViewController: NSViewController, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let userContentController = WKUserContentController()
// Add script message handlers that, when run, will make the function
// window.webkit.messageHandlers.test.postMessage() available in all frames.
userContentController.add(self, name: "test")
// Inject JavaScript into the webpage. You can specify when your script will be injected and for
// which frames–all frames or the main frame only.
let scriptSource = "window.webkit.messageHandlers.test.postMessage(`Hello, world!`);"
let userScript = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
userContentController.addUserScript(userScript)
// let config = WKWebViewConfiguration()
// config.userContentController = userContentController
// let webView = WKWebView(frame: .zero, configuration: config)
webView.navigationDelegate = self
webView.configuration.userContentController = userContentController
// Make sure in Info.plist you set `NSAllowsArbitraryLoads` to `YES` to load
// URLs with an HTTP connection. You can run a local server easily with services
// such as MAMP.
let htmlStr = "<html><body>Hello world - nojs</body></html>"
webView.loadHTMLString(htmlStr, baseURL: nil)
}
}
extension ViewController: WKScriptMessageHandler {
// Capture postMessage() calls inside loaded JavaScript from the webpage. Note that a Boolean
// will be parsed as a 0 for false and 1 for true in the message's body. See WebKit documentation:
// https://developer.apple.com/documentation/webkit/wkscriptmessage/1417901-body.
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let messageBody = message.body as? String {
print(messageBody)
}
}
}
另一件奇怪的事情是,我似乎无法创建一个简单的WKWebView应用程序来加载和显示页面。这些都只是简单的测试,我的主应用程序能够很好地使用AlamoFire/loadHTMLString()来加载/显示网页,我只是无法注入所需的JS。
我在转换过程中所做的一切都是非常直接的,除了userContentController的分配之外,几乎不需要或根本不需要做任何更改——所以也许这就是问题所在?这个例子在iOS中运行得很好,他的原始示例是一个原型。https://github.com/rckim77/WKWebViewDemoApp/blob/master/WKWebViewDemoApp/ViewController.swift
我猜这里一定少了一些很简单的东西。任何帮助都将不胜感激!
最佳答案
这是我如何在Mac上设置我的网络视图的方法,试试这样的方法
import Cocoa
import WebKit
class ViewController: NSViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let javascript = """
function printStatement() {
try {
window.webkit.messageHandlers
.callbackHandler.postMessage({'payload': 'Hello World!'})
} catch(err) {
console.log('The native context does yet exist')
}
}
"""
let script = WKUserScript(
source: javascript,
injectionTime: WKUserScriptInjectionTime.atDocumentEnd,
forMainFrameOnly: true
)
webView.configuration.userContentController.add(
name: "callbackHandler"
)
webView.configuration.userContentController
.addUserScript(script)
webView.navigationDelegate = self
let html = """
<div onClick='javascript:printStatement()'>Print Statement</div>
"""
webView.loadHTMLString(html, nil)
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "callbackHandler") {
guard let body = message.body as? [String: Any] else {
print("could not convert message body to dictionary: \(message.body)")
return
}
guard let payload = body["payload"] as? String else {
print("Could not locate payload param in callback request")
return
}
print(payload)
}
}
}
希望这能回答你的问题,如果不让我知道,我会努力解决它!
关于swift - 无法将JS注入(inject)Swift/Cocoa/NextStep中的WKWebView中/将WKWebView中网页上的用户选择推送到Swift/Cocoa中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54751886/