簡體   English   中英

swift和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()中“返回”,我怎樣才能實現以下任何一種?

  1. 要么將消息發送到swift,以便它可以采取適當的措施

  2. 或者調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM