Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
swift与Javascriptcore的异步通信_Swift_Wkwebview_Javascriptcore - Fatal编程技术网

swift与Javascriptcore的异步通信

swift与Javascriptcore的异步通信,swift,wkwebview,javascriptcore,Swift,Wkwebview,Javascriptcore,我想在web视图之外使用WKWebView提供的异步功能。 JS上下文选项不提供异步功能 在WKWebView中,我按照如下方式编写我的逻辑 func swiftFunc1() { webView.evaluateJavaScript("jsFunc1(), completionHandler: nil) } 在javascript代码中,我向swift发布了一条消息 function jsFunc1() { window.webkit.messageHandlers.myMsg

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

在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函数,以便采取适当的操作


  • 如果您不希望您的脚本在执行后终止,我是否理解正确

    如果我理解错了,也许下面会有帮助(我不在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()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    function jsFunc1() {
       swiftFunc2();
     }
    
    您的swiftFunc2将如下所示:

    func swiftFunc1() {
        myCtxt = JSContext()
        myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
        exportedToJS = exportToJS() //confirms to JSExport and uses @objc
        myCtxt.evaluateScript("swiftFunc2()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    function jsFunc1() {
       swiftFunc2();
     }
    
    您的JS代码如下所示:

    func swiftFunc1() {
        myCtxt = JSContext()
        myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
        exportedToJS = exportToJS() //confirms to JSExport and uses @objc
        myCtxt.evaluateScript("swiftFunc2()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    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方法相结合


    如果它不能正常工作/运行,请告诉我。

    如果您不希望脚本在执行后终止,我是否理解您的意思

    如果我理解错了,也许下面会有帮助(我不在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()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    function jsFunc1() {
       swiftFunc2();
     }
    
    您的swiftFunc2将如下所示:

    func swiftFunc1() {
        myCtxt = JSContext()
        myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
        exportedToJS = exportToJS() //confirms to JSExport and uses @objc
        myCtxt.evaluateScript("swiftFunc2()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    function jsFunc1() {
       swiftFunc2();
     }
    
    您的JS代码如下所示:

    func swiftFunc1() {
        myCtxt = JSContext()
        myCtxt.setObject(unsafeBitCast(swiftFunc2, AnyObject.self), forKeyedSubscript: "swiftFunc2")
        exportedToJS = exportToJS() //confirms to JSExport and uses @objc
        myCtxt.evaluateScript("swiftFunc2()")
    }
    
    let swiftFunc2: @convention(block) Void -> Void = { 
      // do something here
    }
    
    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方法相结合


    如果它不能正常工作/运行,请告诉我。

    谢谢您的回答。但这是否意味着我应该只使用块/闭包来解决这个问题?JSExport不能处理这种调用序列,是吗?JSExport也应该可以。如果明天我有时间,也许我可以试着举个例子。期待着!你能发现这是可能的吗?我以前尝试过这种安排,发现当有这样的循环时,XCode只是挂起。谢谢你的回答。但这是否意味着我应该只使用块/闭包来解决这个问题?JSExport不能处理这种调用序列,是吗?JSExport也应该可以。如果明天我有时间,也许我可以试着举个例子。期待着!你能发现这是可能的吗?我以前尝试过这种安排,发现当有这样的循环时,XCode只是挂起。看见