【问题标题】:Swift 4 JSONEncoder returns empty JSON arraySwift 4 JSONEncoder 返回空的 JSON 数组
【发布时间】:2018-11-10 17:59:16
【问题描述】:

我有多个要转换为 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 转换。

【问题讨论】:

    标签: ios swift xcode swift4 jsonencoder


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您的错误是您尝试使用继承而不是泛型。你的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 方式卡住? 更喜欢使用 struct 而不是 class,除非你总是需要通过引用来复制对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多