如何从Swift调用JavaScript

时间:2019-04-11 12:23:26

标签: javascript swift

我想用一些用户定义的宏扩展电子表格应用程序。使用javascript ...似乎是个好主意...

它发现了一个“小问题”(我完全不熟悉javascript)

import JavaScriptCore

let context = JSContext()!
context.exceptionHandler = { context, exception in
    print("exception:", exception?.toString() ?? "")
}

context.evaluateScript(
    """
    foo = function(a, b) {
        return a + b
    }
    """
)
context.evaluateScript("foo(1, 2)") // 3
context.objectForKeyedSubscript("foo")?.call(withArguments: [1,2]) // 3

context.evaluateScript(
    """
    Foo = function() {}
    Foo.foo = function(a, b) {
        return a + b
    }
    """
)
context.evaluateScript("Foo.foo(1, 2)") // 3

// exception.  TypeError: undefined is not an object
context.objectForKeyedSubscript("Foo.foo")?.call(withArguments: [1, 2]) // Foo.foo is undefined ?????

如果未定义Foo.foo,它怎么能只运行一行呢?

2 个答案:

答案 0 :(得分:0)

最后我找到了解决方案...

context.objectForKeyedSubscript("Foo")?.objectForKeyedSubscript("foo")?.call(withArguments: [1, 2]) // 3

或更佳...

extension JSContext {
    func objectForKeySubscript(_ dotted: String) -> JSValue! {
        var iterator = dotted.split(separator: ".").makeIterator()
        var jsValue = self.objectForKeyedSubscript(iterator.next())
        while let str = iterator.next() {
            jsValue = jsValue?.objectForKeyedSubscript(str)
        }
        return jsValue
    }
}
context.objectForKeySubscript("Foo.foo")?.call(withArguments: [1, 2])

最后我发现

context.evaluateScript("Foo.foo")?.call(withArguments: [1, 2])

可以正常工作...:-)

答案 1 :(得分:0)

您尝试了.call(withArguments。但是我认为这适用于需要两个参数(对象和参数)的Function.prototype.call()。有关更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

这有效

context.objectForKeyedSubscript("Foo")?.invokeMethod("foo", withArguments: [1, 2])