首页 > 解决方案 > JSValue.toObjectOf 返回 nil

问题描述

我正在试验 JavaScriptCore 和JSValue.toObjectOfClass. 我的问题是,鉴于下面的代码,为什么ofObjectToClass返回nil而不是我的类的实例Pet

注意:这是一个简化的示例,它模拟了我尝试使用更大的代码库所做的事情。请原谅其简单的性质,并随时了解ofObjectToClass. 关于它的信息似乎很少。

这是我正在使用的代码 - 您可以将其直接放入 Swift Playground 并亲自尝试:

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 文档指出,“......如果值无法转换为预期的类,则为零。” 我在寻找为什么

标签: iosswiftjavascriptcore

解决方案


为什么ofObjectToClass返回nil而不是我的类的实例Pet

因为您的 JavaScript 类Pet与您的 Swift 类无关Pet

你需要Pet明确地导出你的 Swift 类:

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 :(")
}

推荐阅读