Swift 编码 class 不嵌套 super class
Swift encode class without nesting super class
总结:
我想对我的超级 class 的所有字段进行编码,而不将它们嵌套在 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 super class 的所有属性都嵌套在 "employee"
json 字段中。
但是,我不想这样。我希望 giftString
的输出如下:
{"toy":{"name":"Teddy Bear"},"name":"John Appleseed","id":7,"birthday":597607945.92342305}
BasicEmployee
结构的属性不应嵌套,并且应与 GiftEmployee
结构的编码属性处于同一级别。
备注
我知道我可以通过更改结构的结构来避免所有麻烦,但是,现在这不可能。
如果我能在我的问题上得到任何帮助,我将不胜感激。
您可以调用 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)
}
总结: 我想对我的超级 class 的所有字段进行编码,而不将它们嵌套在 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 super class 的所有属性都嵌套在 "employee"
json 字段中。
但是,我不想这样。我希望 giftString
的输出如下:
{"toy":{"name":"Teddy Bear"},"name":"John Appleseed","id":7,"birthday":597607945.92342305}
BasicEmployee
结构的属性不应嵌套,并且应与 GiftEmployee
结构的编码属性处于同一级别。
备注
我知道我可以通过更改结构的结构来避免所有麻烦,但是,现在这不可能。
如果我能在我的问题上得到任何帮助,我将不胜感激。
您可以调用 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)
}