gpt4 book ai didi

swift - swift与Javascriptcore的异步通信

转载 作者:行者123 更新时间:2023-11-28 08:33:59 26 4
gpt4 key购买 nike

我想在 Web View 之外使用 WKWebView 提供的异步功能。JS 上下文选项不提供异步功能。

在WKWebView中,我的逻辑是这样写的。

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

在 javascript 代码中,我向 swift 发送消息

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

然后,swift 代码可以调用适当的 JS 回调作为处理消息的一部分。

但这取决于 webview 是前景 View 。如果我想使用独立于 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: block

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

你的导出类的协议(protocol)。在这里你必须声明你想要使用 Javascript 的所有属性和方法。

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

有了它,您应该可以从 javascript 调用一个函数并让它继续运行。在这个例子中,您现在可以像这样从 Javascript 访问类 JavascriptHandler 的函数:

MyJSHandler.swiftFunc2();

如果你想将你的 WebView 所在的类与你的 JS 逻辑所在的类分开,那也应该不是问题。您还应该能够将 block 语法与 JSExport 方法结合起来。

如果它没有按预期工作/表现,请告诉我。

关于swift - swift与Javascriptcore的异步通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38283348/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com