![](/img/trans.png)
[英]How to call an async javascript function from a javascript SDK in Swift with JavaScriptCore
[英]Async communication of swift and Javascriptcore
我想在Web视图之外使用WKWebView提供的Async功能。 JS Context选项不提供Async功能。
在WKWebView中,我按如下方式编写逻辑。
func swiftFunc1() {
webView.evaluateJavaScript("jsFunc1(), completionHandler: nil)
}
在javascript代码中,我向swift发布了一条消息
function jsFunc1() {
window.webkit.messageHandlers.myMsg.postMessage("call swiftFunc2");
}
然后,swift代码可以调用适当的JS回调作为处理消息的一部分。
但这取决于webview是前景视图。 如果我想使用独立于webview的JS逻辑,JSContext是可选的。 我试过跟随
func swiftFunc1() {
myCtxt = JSContext()
exportedToJS = exportToJS() //confirms to JSExport and uses @objc
myCtxt.setObject(exportedToJS.self, forKeyedSubscript: "swiftIface")
myFunc = myCtxt.objectForKeyedSubscript("jsFunc1")
myFunc.callWithArguments(nil)
}
现在在javascript代码中我无法向swift发布消息。 如果我尝试按如下方式调用swift函数,代码将永远陷入困境。
function jsFunc1() {
swiftIface.swiftFunc2() // This creates a deadklock
}
如果没有从被调用的Javascript函数jsFunc1()中“返回”,我怎样才能实现以下任何一种?
要么将消息发送到swift,以便它可以采取适当的措施
或者调用swift函数以便采取适当的操作
如果你不希望你的javscript在执行后终止,我理解你是对的吗?
如果我理解你错了,也许跟着帮忙(我不在Mac上测试,但是如果修改你的代码可能会有效)
选项1:块
swiftFunc1看起来像这样:
func swiftFunc1() {
myCtxt = JSContext()
myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
exportedToJS = exportToJS() //confirms to JSExport and uses @objc
myCtxt.evaluateScript("swiftFunc2()")
}
你的swiftFunc2看起来像这样:
let swiftFunc2: @convention(block) Void -> Void = {
// do something here
}
你的JS代码看起来像这样:
function jsFunc1() {
swiftFunc2();
}
选项2:JSExport你有一个可以访问所有javascript的导出类:
import Foundation
import JavaScriptCore
@objc class JavascriptHandler: NSObject, JavascriptHandlerExport {
let context: JSContext = JSContext()
init () {
context.setObject(self, forKeyedSubscript: "MyJSHandler") // set the object name for self accessible in javascript code
}
func swiftFunc1() {
context.evaluateScript("MyJSHandler.swiftFunc2();")
}
func swiftFunc2 () {
// do something here
}
}
您导出的类的协议。在这里,您必须声明要使用Javascript的所有属性和方法。
import Foundation
import JavaScriptCore
@objc protocol JavascriptHandlerExport: JSExport {
func swiftFunc2 ( ) -> Void
}
有了这个,你应该可以从javascript调用一个函数,但仍然让它继续。 您现在可以在此示例中从Javascript访问类JavascriptHandler的函数:
MyJSHandler.swiftFunc2();
如果你想要将你的WebView所在的类与JS逻辑所在的类分开,这也应该不是问题。 您还应该能够将块语法与JSExport方法结合使用。
如果它不能正常工作/表现,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.