1

摘要: 我想对我的超类的所有字段进行编码,而不将它们嵌套在 json 结果中。

这就是我的意思:

假设我们有这些结构:

struct Toy: Codable {
  var name: String
}

class BasicEmployee: Codable {
  var name: String
  var id: Int

  init(name: String, id: Int) {
    self.name = name
    self.id = id
  }
}

class GiftEmployee: BasicEmployee {
  var birthday: Date
  var toy: Toy

  enum CodingKeys: CodingKey {
    case employee, birthday, toy
  }

  init(name: String, id: Int, birthday: Date, toy: Toy) {
    self.birthday = birthday
    self.toy = toy
    super.init(name: name, id: id)
  }

  required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    birthday = try container.decode(Date.self, forKey: .birthday)
    toy = try container.decode(Toy.self, forKey: .toy)
    let baseDecoder = try container.superDecoder(forKey: .employee)
    try super.init(from: baseDecoder)
  }

  override func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(birthday, forKey: .birthday)
    try container.encode(toy, forKey: .toy)

    let baseEncoder = container.superEncoder(forKey: .employee)
    try super.encode(to: baseEncoder)
  }
}

现在我们决定GiftEmployee像这样编码一个对象:

let encoder = JSONEncoder()
let decoder = JSONDecoder()

let giftEmployee = GiftEmployee(name: "John Appleseed", id: 7, birthday: Date(), toy: Toy(name: "Teddy Bear"))
let giftData = try encoder.encode(giftEmployee)
let giftString = String(data: giftData, encoding: .utf8)!

打印出来giftString给我们以下输出:

{"toy":{"name":"Teddy Bear"},"employee":{"name":"John Appleseed","id":7},"birthday":597607945.92342305}

如您所见,我们的 BasicEmployee 超类的所有属性都嵌套在"employee"json 字段中。

但是,我不希望那样。我希望的输出giftString如下:

{"toy":{"name":"Teddy Bear"},"name":"John Appleseed","id":7,"birthday":597607945.92342305}

结构的属性BasicEmployee不应嵌套,并且与GiftEmployee结构的编码属性处于同一级别。

笔记

我知道我可以通过改变结构的结构来避免所有的麻烦,但是,这现在是不可能的。

我将非常感谢我能在我的问题上获得的任何帮助。

4

1 回答 1

3

您可以致电super.init(from:)super.encode(to:)

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    birthday = try container.decode(Date.self, forKey: .birthday)
    toy = try container.decode(Toy.self, forKey: .toy)
   super.init(from: decoder)
}

override func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(birthday, forKey: .birthday)
    try container.encode(toy, forKey: .toy)
    try super.encode(to: encoder)
}
于 2019-12-09T18:29:51.760 回答