使用JavascriptCore和JSContext从JavaScript调用本机Swift代码

时间:2018-08-17 12:28:44

标签: javascript swift javascriptcore

我正在尝试在运行于JSContext中的javacript中使用本机Swift代码。

例如,我在Swift中实现了此类:

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

无法弄清楚我在做什么。

1 个答案:

答案 0 :(得分:1)

我们不应该忘记的一件事就是通过遵循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(), 因此,我在getInstance中添加了一个方法来返回实例。