1

我有多个要转换为 JSON 字符串的 Codeable 类。

class MyCodable: NSObject, Codable {

    override init() {

    }

    func encode(to encoder: Encoder) throws {

    }

}

class Category: MyCodable {

   required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self);
        //... assign values and call super.init
    }

    override func encode(to encoder: Encoder) throws {

    }

    var categoyId: Int64;
    var categoryName: String;

    enum CodingKeys: String, CodingKey {
        case categoryId
        case categoryName
    }

}

class Product: MyCodable {

    required init(from decoder: Decoder) throws {
        //..assign values and call super.init
    }

    override func encode(to encoder: Encoder) throws {

    }

    var productId: Int64;
    var categoryId: Int64;
    var productName: String;

    enum CodingKeys: String, CodingKey {
        case productId
        case categoryId
        case productName
    }

}

我有一个用于转换的实用程序类。

class JSONUtil: NSObject {

    public static func encode(objects: [MyCodable]) -> String {
        var json: String = "";
        do {
            let encoder = JSONEncoder();
            encoder.outputFormatting = .prettyPrinted;
            let jsonData = try encoder.encode(objects);
            json = String(data: jsonData, encoding: String.Encoding.utf8)!
        } catch let convertError { json = "[{error: '" + convertError.localizedDescription + "'}]"; }
        return json;
    }

    public static func toJson(object: MyCodable) -> String {
        var objects = [MyCodable]();
        objects.append(object);
        return encode(objects: objects);
    }

}

无论 MyCodable 对象数组中的内容是什么,返回值始终为“[{}]”。调试时,我可以看到 Category 对象的值已填充。

由于 MyCodable 没有属性,这就是 JSONEncoder 不打印 Category 属性的原因吗?.. 或者它为什么不打印 Category 属性?

我对 Product 对象有同样的问题。

目标是避免必须为我要打印到 JSON 的每个类自定义 JSON 转换。

4

2 回答 2

0

你的错误是你试图使用继承而不是泛型。你的JSONUtil班级应该是这样的。

class JSONUtil: NSObject {

    public static func encode<T: Encodable>(objects: [T]) -> String {
        var json: String = "";
        do {
            let encoder = JSONEncoder();
            encoder.outputFormatting = .prettyPrinted;
            let jsonData = try encoder.encode(objects);
            json = String(data: jsonData, encoding: String.Encoding.utf8)!
        } catch let convertError { json = "[{error: '" + convertError.localizedDescription + "'}]"; }
        return json;
    }

    public static func toJson<T: Encodable>(object: T) -> String {
        return encode(objects: [object]);
    }

}

我不确定你为什么要创建继承自NSObject. 你可能会停留在旧的 Objective-C 方式中 更喜欢使用structover class,除非你总是需要通过引用来复制对象。

于 2018-11-10T19:32:21.117 回答
0

你的推理是正确的, MyCodable 没有属性,所以没有什么可以读/写的。您实际上偶然发现了 swift JSON 编码器和解码器的一个错误。他们不能很好地处理继承。因此,您的 Product 和 Category 类成为匿名的 MyCodable 类,没有任何东西需要编码或解码。

查看您的代码,我认为没有理由使用 MyCodable 类。只需让 Product 和 Category 遵守 Codable 协议。如果您需要能够以相同方式引用 Product 和 Category 的多态性,请定义一个遵循 Codable 的 protoocl 并让 Product 和 Category 遵循您定义的协议。在我看来,这是多余的,但是在某些用例中它可能是一个合理的解决方案。

于 2018-11-10T18:07:45.810 回答