【问题标题】:Calling native Swift code from javascript using JavascriptCore and JSContext使用 JavascriptCore 和 JSContext 从 javascript 调用本机 Swift 代码
【发布时间】:2018-08-17 12:28:43
【问题描述】:

我正在尝试在运行在 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

无法弄清楚我做错了什么。

【问题讨论】:

    标签: javascript swift javascriptcore


    【解决方案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 方法来返回一个实例。

    【讨论】:

    • 遗憾的是,您的回答并没有解决我的问题。我上传了我的 Swift 游乐场的 screenshot。我正在使用 Xcode 9.4.1。
    • 它不在 Playground 中工作,但在实际项目中工作。这是截图imgur.com/a/VkbjEVz
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多