简体   繁体   English

swift和Javascriptcore的异步通信

[英]Async communication of swift and Javascriptcore

I want to use the Async functionality offered by WKWebView outside web view. 我想在Web视图之外使用WKWebView提供的Async功能。 The JS Context option does not provide the Async functionality. JS Context选项不提供Async功能。

In WKWebView, I write my logic as follows. 在WKWebView中,我按如下方式编写逻辑。

func swiftFunc1() {
   webView.evaluateJavaScript("jsFunc1(), completionHandler: nil)
}

In javascript code I post a message to swift 在javascript代码中,我向swift发布了一条消息

function jsFunc1() {
    window.webkit.messageHandlers.myMsg.postMessage("call swiftFunc2");
}

The swift code can then call appropriate JS callback as a part of handling message. 然后,swift代码可以调用适当的JS回调作为处理消息的一部分。

But this is dependent upon the webview being the foreground view. 但这取决于webview是前景视图。 If I want to use the JS logic independent of the webview, JSContext is the option. 如果我想使用独立于webview的JS逻辑,JSContext是可选的。 I tried following 我试过跟随

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)
}

Now in javascript code I cannot post a message to swift. 现在在javascript代码中我无法向swift发布消息。 If I try to call a swift function as follows, code gets stuck forever. 如果我尝试按如下方式调用swift函数,代码将永远陷入困境。

function jsFunc1() {
   swiftIface.swiftFunc2() // This creates a deadklock
 }

How can I achieve either of the following without "returning" from the called Javascript function jsFunc1()? 如果没有从被调用的Javascript函数jsFunc1()中“返回”,我怎样才能实现以下任何一种?

  1. Either post a message to swift so that it can take appropriate action 要么将消息发送到swift,以便它可以采取适当的措施

  2. Or call a swift function so that the appropriate action is taken 或者调用swift函数以便采取适当的操作

Do I understand you right, if you do not want your javscript to terminate after execution? 如果你不希望你的javscript在执行后终止,我理解你是对的吗?

If I understood you wrong, maybe following helps (I am not at home at Mac to test, but maybe it works if you modify your code as follows). 如果我理解你错了,也许跟着帮忙(我不在Mac上测试,但是如果修改你的代码可能会有效)

Option 1: Blocks 选项1:块

The swiftFunc1 could look like this: swiftFunc1看起来像这样:

func swiftFunc1() {
    myCtxt = JSContext()
    myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
    exportedToJS = exportToJS() //confirms to JSExport and uses @objc
    myCtxt.evaluateScript("swiftFunc2()")
}

Your swiftFunc2 would look like this: 你的swiftFunc2看起来像这样:

let swiftFunc2: @convention(block) Void -> Void = { 
  // do something here
}

Your JS code would look like this: 你的JS代码看起来像这样:

function jsFunc1() {
   swiftFunc2();
 }

Option 2: JSExport Your have an exported class which is accessible for all javascript: 选项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
  }
}

Your protocol for the exported class.Here you have to declare all properties and methods you want to use with Javascript. 您导出的类的协议。在这里,您必须声明要使用Javascript的所有属性和方法。

import Foundation
import JavaScriptCore
@objc protocol JavascriptHandlerExport: JSExport {
  func swiftFunc2 ( ) -> Void
}

With this it should be possible for you to call a function from javascript and still let it continue. 有了这个,你应该可以从javascript调用一个函数,但仍然让它继续。 You can now access the functions of the class JavascriptHandler from Javascript like this in this example: 您现在可以在此示例中从Javascript访问类JavascriptHandler的函数:

MyJSHandler.swiftFunc2();

If you want to seperate the class where your WebView is from the one where your JS logic lies that should also not be a problem. 如果你想要将你的WebView所在的类与JS逻辑所在的类分开,这也应该不是问题。 You should also be able to combine the block syntax with the JSExport method. 您还应该能够将块语法与JSExport方法结合使用。

Let me know if it's not working/behaving as wanted. 如果它不能正常工作/表现,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM