如何在JS中调用一个返回值的swift函数?

时间:2016-02-15 07:11:58

标签: swift swift2 tvos

下面的代码就像一个魅力来定义Swift(2.0)中的一个函数,我可以从Javascript资源(tvos)调用它。函数storeSetPackageInfo接受一个参数并且不返回任何内容。

我试图了解如何使用不接受参数并返回布尔值的函数实现相同的目标。我似乎不理解语法。

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没有找到该函数。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我昨天在另一个背景下描述了一种可能的方式:How to retrieve values from settings.bundle in TVML?

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

答案 1 :(得分:0)

经过多次尝试,我找到了,答案和解决方案始终在我面前......我曾经尝试过,但最终我还有其他混乱的尝试。为了使遇到这些问题的人受益,这里有任何签名的解决方案

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

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