如何在 JS 中调用一个 swift 函数 returns 一个值?

How to call a swift function in JS that returns a value?

下面的代码非常有用,可以在 Swift (2.0) 中定义一个函数,我可以从 Javascript 资源 (tvos) 中调用该函数。函数 storeSetPackageInfo 接受一个参数并且 returns 什么都没有。

我想了解如何使用不接受任何参数且 returns 布尔值的函数实现相同的目标。我似乎不明白语法。

private typealias JavascriptClosure = (JSContext) -> Void
private typealias ObjectivecCompletionBlock = @convention(block) (String) -> Void

func setupStoreSetPackageInfo() {
        let selectComponent: JavascriptClosure = {
            [unowned self](context: JSContext) -> Void in
            let objCompletion: ObjectivecCompletionBlock = {
                (str: String) -> Void in
                (self.delegate as? myTVAppControllerDelegate)?.storeSetPackageInfo(str)
            }
            context.setObject(unsafeBitCast(objCompletion, AnyObject.self), forKeyedSubscript: "storeSetPackageInfo")
        }
        evaluateInJavaScriptContext(selectComponent, completion: nil)
    }

我尝试了多种编译方法,但导致 JSContext 找不到函数。非常感谢任何帮助。

我昨天在另一个上下文中描述了一种可能的方法:

AppDelegate.swift

func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext) {
    let jsInterface: cJsInterface = cJsInterface();
    jsContext.setObject(jsInterface, forKeyedSubscript: "swiftInterface")
}

JsInterface.swift

@objc protocol jsInterfaceProtocol : JSExport {
    func getSetting(setting: String) -> String
}
class cJsInterface: NSObject, jsInterfaceProtocol {
    func getSetting(setting: String) -> String {
        return "<yourSetting>"
    }
}

在 JS 方面...

swiftInterface.getSetting(...)

与您的示例相比,这绝对是一种不同的语法,但已知可以正常工作。参见 https://github.com/iBaa/PlexConnectApp

经过多次尝试,我找到了,答案和解决方案一直在我面前...我以前尝试过,但我最终还是遇到了其他乱七八糟的尝试。为了让遇到这个问题的人受益,这里是任何签名的解决方案

private typealias ObjectivecCompletionBlock = @convention(block) () -> Bool

完成块必须与签名匹配

() -> Bool in

因此最终代码为

private typealias JavascriptClosure = (JSContext) -> Void
private typealias ObjectivecCompletionBlock = @convention(block) () -> Bool
func setupStoreSetPackageInfo() {
        let selectComponent: JavascriptClosure = {
            [unowned self](context: JSContext) -> Void in
            let objCompletion: ObjectivecCompletionBlock = {
                () -> Bool in
                (self.delegate as? myTVAppControllerDelegate)?.storeSetPackageInfo(str)
            }
            context.setObject(unsafeBitCast(objCompletion, AnyObject.self), forKeyedSubscript: "storeSetPackageInfo")
        }
        evaluateInJavaScriptContext(selectComponent, completion: nil)
    }

再次非常简单(一旦你把头从桶里拉出来......)