JavascriptCore: выполнение функции обратного вызова, определенной javascript, из собственного кода.

У меня возникли трудности с выполнением функции javascript из собственного кода. Я хочу, чтобы сценарист мог определить «рецепт» в Javascript. Он создается путем вызова функции создания рецептов, которую я открываю из нативного кода. Функция recipe принимает config dict, который ожидает название рецепта и действие. Действие должно быть функцией без параметров и без возвращаемого значения.

Вернувшись в собственный код, когда я обрабатываю config dict, я не могу получить ссылку на определенную функцию действия. На самом деле я получаю 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) ");
       }
       ...
   }

person D.C.    schedule 09.03.2016    source источник


Ответы (1)


Хорошо, я разобрался с этим. Публикация этого на случай, если кто-то еще столкнется с этим.

Проблема в коде Swift, где JSValue приводится к словарю:

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

который использует toDictionary(), и это, кажется, отбрасывает свойство функции.

Вместо этого следует сохранить JSValue, а затем использовать valueForProperty для получения функции, которая сама является JSValue.

let actionValue = parameters.valueForProperty("action");
actionValue.callWithArguments(nil);
person D.C.    schedule 10.03.2016