使用 JavascriptCore 和 JSContext 从 javascript 调用本机 Swift 代码
Calling native Swift code from javascript using JavascriptCore and JSContext
我正在尝试在 JavaScript 中使用本机 Swift 代码,运行 在 JSContext 中。
例如,我在 Swift 中实现了这个 class:
class Greeter: NSObject {
public func greet() -> String {
return "Hello World!"
}
public func greetMe(_ name: String) -> String {
return "Hello, " + name + "!"
}
}
然后我使用 JSContext 来 运行 一个 javascript 代码:
let context = JSContext()!
context.setObject(Greeter.self, forKeyedSubscript: "Greeter" as (NSCopying & NSObjectProtocol))
// Try my native functions:
let jsv1 = context.evaluateScript("Greeter.greet()")!
let jsv2 = context.evaluateScript("Greeter.greetMe(\"Jon Arbuckle\")")!
print("Greeter.greet() = \(jsv1)") // prints Greeter.greet() = undefined
print("Greeter.greatMe(\"Jon Arbuckle\") = \(jsv2)") // prints Greeter.greetMe("Jon Arbuckle") = undefined
无法弄清楚我做错了什么。
我们不应该忘记的一件事是通过符合 JSExport 协议来公开方法或属性。
@objc protocol GreeterJSExports: JSExport {
func greet() -> String
func greetMe(_ name: String) -> String
static func getInstance() -> Greeter
//any other properties you may want to export to JS runtime
//var greetings: String {get set}
}
遵守此协议
class Greeter: NSObject, GreeterJSExports {
public func greet() -> String {
return "Hello World!"
}
public func greetMe(_ name: String) -> String {
return "Hello, " + name + "!"
}
class func getInstance() -> Greeter {
return Greeter()
}
}
像往常一样在 JSContext 中设置对象
let context = JSContext()
context?.setObject(Greeter.self, forKeyedSubscript: "Greeter" as (NSCopying & NSObjectProtocol))
let jsValue1 = context?.evaluateScript("(function(){ var greeter = Greeter.getInstance(); return greeter.greet()})()")
let jsValue2 = context?.evaluateScript("(function(){ var greeter = Greeter.getInstance(); return greeter.greetMe('rikesh')})()")
print(jsValue1!)
print(jsValue2!)
记住,上面的方法是实例方法。我们需要对象来调用它。 Swift 不暴露 init(),
因此,我向 return 一个实例添加了一个 getInstance 方法。
我正在尝试在 JavaScript 中使用本机 Swift 代码,运行 在 JSContext 中。
例如,我在 Swift 中实现了这个 class:
class Greeter: NSObject {
public func greet() -> String {
return "Hello World!"
}
public func greetMe(_ name: String) -> String {
return "Hello, " + name + "!"
}
}
然后我使用 JSContext 来 运行 一个 javascript 代码:
let context = JSContext()!
context.setObject(Greeter.self, forKeyedSubscript: "Greeter" as (NSCopying & NSObjectProtocol))
// Try my native functions:
let jsv1 = context.evaluateScript("Greeter.greet()")!
let jsv2 = context.evaluateScript("Greeter.greetMe(\"Jon Arbuckle\")")!
print("Greeter.greet() = \(jsv1)") // prints Greeter.greet() = undefined
print("Greeter.greatMe(\"Jon Arbuckle\") = \(jsv2)") // prints Greeter.greetMe("Jon Arbuckle") = undefined
无法弄清楚我做错了什么。
我们不应该忘记的一件事是通过符合 JSExport 协议来公开方法或属性。
@objc protocol GreeterJSExports: JSExport {
func greet() -> String
func greetMe(_ name: String) -> String
static func getInstance() -> Greeter
//any other properties you may want to export to JS runtime
//var greetings: String {get set}
}
遵守此协议
class Greeter: NSObject, GreeterJSExports {
public func greet() -> String {
return "Hello World!"
}
public func greetMe(_ name: String) -> String {
return "Hello, " + name + "!"
}
class func getInstance() -> Greeter {
return Greeter()
}
}
像往常一样在 JSContext 中设置对象
let context = JSContext()
context?.setObject(Greeter.self, forKeyedSubscript: "Greeter" as (NSCopying & NSObjectProtocol))
let jsValue1 = context?.evaluateScript("(function(){ var greeter = Greeter.getInstance(); return greeter.greet()})()")
let jsValue2 = context?.evaluateScript("(function(){ var greeter = Greeter.getInstance(); return greeter.greetMe('rikesh')})()")
print(jsValue1!)
print(jsValue2!)
记住,上面的方法是实例方法。我们需要对象来调用它。 Swift 不暴露 init(), 因此,我向 return 一个实例添加了一个 getInstance 方法。