JSValue.toObjectOf возвращает ноль - PullRequest
0 голосов
/ 18 мая 2019

Я экспериментирую с JavaScriptCore и JSValue.toObjectOfClass. Мой вопрос, учитывая приведенный ниже код, почему ofObjectToClass возвращает nil вместо экземпляра моего Pet класса?

ПРИМЕЧАНИЕ. Это урезанный пример, который имитирует то, что я пытаюсь сделать с гораздо большей кодовой базой. Пожалуйста, извините за его простую природу и не стесняйтесь разобраться во внутренней работе ofObjectToClass. Кажется, об этом очень мало информации.

Вот код, с которым я работаю - вы можете поместить его прямо на игровую площадку Swift и попробовать сами:

import JavaScriptCore

let javascript = """
var Pet = (function() {
    function Pet(name) {
        this._name = name;
    }

    Object.defineProperty(Pet.prototype, 'name', {
        get: function () {return this._name;},
        set: function (name) {this._name = name;}
    });

    return Pet;
})();

var fetchPet = function(name) {
    return new Pet(name);
}
"""

@objc public class Pet: NSObject, JSExport {
    public var name: String?
}

let context = JSContext()!
context.evaluateScript(javascript)
let fcn = context.objectForKeyedSubscript("fetchPet")!
let petValue = fcn.call(withArguments: ["Fido"])
print("petValue.name is \(petValue?.forProperty("name")?.toString() ?? "???")")
if let petObj = petValue?.toObjectOf(Pet.self) as? Pet {
    print("pet.name is \(petObj.name)")
}
else {
    print("pet is nil :(")
}

А вот вывод, который я получаю:

petValue.name is Fido
pet is nil :(

И вывод, который я ожидаю:

petValue.name is Fido
pet.name is Fido

Спасибо за внимание и хороших выходных!

Редактировать. Мне известна документация Apple, в которой говорится: «... ноль, если значение не может быть преобразовано в ожидаемый класс». Я после почему .

1 Ответ

0 голосов
/ 18 мая 2019

почему ofObjectToClass возвращает nil вместо экземпляра моего Pet класса?

Поскольку ваш класс JavaScript Pet не имеет ничегоделать с вашим классом Swift Pet.

Вам необходимо явно экспортировать свой класс Swift Pet:

import JavaScriptCore

let javascript = """
var fetchPet = function(name) {
    return new Pet(name);
};
"""

@objc protocol PetProtocol: JSExport {
    var name: String {get set}

    init(name: String)
}

class Pet: NSObject, PetProtocol {
    var name: String

    required init(name: String) {
        self.name = name
    }
}

let context = JSContext()!
context.setObject(Pet.self, forKeyedSubscript: "Pet" as NSString) //<-
context.evaluateScript(javascript)
let fcn = context.objectForKeyedSubscript("fetchPet")!
let petValue = fcn.call(withArguments: ["Fido"])
print("petValue.name is \(petValue?.forProperty("name")?.toString() ?? "???")")
if let petObj = petValue?.toObjectOf(Pet.self) as? Pet {
    print("pet.name is \(petObj.name)")
}
else {
    print("pet is nil :(")
}
...