【问题标题】:JavascriptCore: executing a javascript-defined callback function from native codeJavascriptCore:从本机代码执行 javascript 定义的回调函数
【发布时间】:2016-03-09 03:51:10
【问题描述】:

我在尝试从本机代码执行 javascript 函数时遇到了一些困难。我希望脚本编写者能够在 Javascript 中定义“配方”。它是通过调用我从本机代码公开的配方创建函数来创建的。 recipe 函数需要一个配置字典,它需要一个配方名称和一个动作。动作应该是一个无参数、无返回值的函数。

回到本机代码,当我处理配置字典时,我似乎无法获得对定义的操作函数的引用。我实际上得到的是一个没有键的 NSDictionary。

感谢您的帮助。

Javascript

// topLevel is a valid object I expose. It has a module 
// function that returns a new module 
var module = topLevel.module("Demo - Recipe");

// module has a recipe method that takes a config dict
// and returns a new recipe
module.recipe({
 name: "Recipe 1",
 action: function() {
   topLevel.debug("Hello from Recipe 1!");
 }
});

本机代码:

@objc public protocol ModuleScriptPluginExports: JSExport {
    func recipe(unsafeParameters: AnyObject) -> ModuleScriptPlugin
}

...

public func recipe(unsafeParameters: AnyObject) -> ModuleScriptPlugin {
   guard let parameters : [String:AnyObject] = unsafeParameters as? [String: AnyObject] else {
       // error, parameters was not the config dict we expected...
       return self;
   }

   guard let name = parameters["name"] as? String else {
       // error, there was no name string in the config dict
       return self;
   }

   guard let action = parameters["action"] as? () -> Void else {
       // error, action in the config dict was not a () -> Void callback like I expected
       // what was it...?
       if let unknownAction = parameters["action"] {
           // weird, its actually a NSDictionary with no keys!
           print("recipe action type unknown. action:\(unknownAction) --> \(unknownAction.dynamicType) ");
       }
       ...
   }

【问题讨论】:

    标签: javascript ios swift cocoa javascriptcore


    【解决方案1】:

    好的,我解决了这个问题。发布此内容以防其他人遇到此问题。

    问题出在 Swift 代码中,其中 JSValue 被强制转换为字典:

    parameters : [String:AnyObject] = unsafeParameters as? [String: AnyObject]
    

    它使用toDictionary(),这样做似乎丢掉了函数属性。

    相反,JSValue 应该保持不变,然后 valueForProperty 用于获取本身就是 JSValue 的函数。

    let actionValue = parameters.valueForProperty("action");
    actionValue.callWithArguments(nil);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 2012-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多