[英]How to call javascript from swift
I would like to extend my spreadsheet app with some user-defined macros. 我想用一些用户定义的宏扩展电子表格应用程序。 It seems to be a good idea to use javascript ...
使用javascript似乎是一个好主意...
It found a "small issue" (I am very unfamiliar with javascript at all) 它发现了一个“小问题”(我完全不熟悉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 ?????
If Foo.foo is undefined, how it could run just one line earlier? 如果Foo.foo是未定义的,它怎么能只运行一行呢?
finally I found a solution ... 终于我找到了解决方案...
context.objectForKeyedSubscript("Foo")?.objectForKeyedSubscript("foo")?.call(withArguments: [1, 2]) // 3
or better ... 或更好 ...
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])
and finaly I found, that 最后我发现
context.evaluateScript("Foo.foo")?.call(withArguments: [1, 2])
works without any trouble ... :-) 可以正常工作... :-)
You tried .call(withArguments
. But I think this works with Function.prototype.call()
that requires two arguments(object and arguments). For more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call 您尝试了
.call(withArguments
,但是我认为这可以与Function.prototype.call()
,该Function.prototype.call()
需要两个参数(对象和参数)。有关更多信息: https : //developer.mozilla.org/en-US/docs/网络/ JavaScript的/参考/ Global_Objects /功能/通话
This works 这有效
context.objectForKeyedSubscript("Foo")?.invokeMethod("foo", withArguments: [1, 2])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.