![](/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.