假设我有某种具有JSON表示形式的类型,
{
"count": 3,
"name": "Pianos",
"type": "instrument",
"id": 1,
}
假设我想将其表示为如下所示的Swift对象:
struct SomeObject: Codable { // this is the object I'd like to represent
let id: Int
let details: SomeDetails
}
struct SomeDetails: Codable {
let count: Int
let name: String
let type: String
}
毫无疑问地解码此对象。但是在这种情况下编码将如何工作,以便我可以编码为扁平结构-与我用来创建此对象并在上面的JSON示例中共享的结构相同?
答案 0 :(得分:1)
但是在这种情况下编码将如何工作?
它可以正常工作:
struct SomeObject: Codable {
let id: Int
let details: SomeDetails
}
struct SomeDetails: Codable {
let count: Int
let name: String
let type: String
}
let someobject = SomeObject(id: 10, details: SomeDetails(count: 3, name: "ho", type: "hey"))
let json = try! JSONEncoder().encode(someobject)
如果您坚持要人为压平,只需编写自己的encode(to:)
,如下所示:
struct SomeObject: Codable {
let id: Int
let details: SomeDetails
enum Keys : String, CodingKey {
case id
case count
case name
case type
}
func encode(to enc: Encoder) throws {
var con = try enc.container(keyedBy: Keys.self)
try con.encode(id, forKey: .id)
try con.encode(details.count, forKey: .count)
try con.encode(details.name, forKey: .name)
try con.encode(details.type, forKey: .type)
}
}
struct SomeDetails: Codable {
let count: Int
let name: String
let type: String
}
let someobject = SomeObject(id: 10, details: SomeDetails(count: 3, name: "ho", type: "hey"))
let json = try! JSONEncoder().encode(someobject)
答案 1 :(得分:0)
如果将来有人在阅读(嗨!),这只是步入您的构造类型而将抽象值装箱的问题。
localhost:8480/assets/images/logo.png
答案 2 :(得分:0)
对先前答案的改进。无需手动编码或解码其他对象,您只需转发初始化程序即可。
struct SomeDetails: Codable {
let count: Int
let name: String
let type: String
}
struct SomeObject: Codable {
enum CodingKeys: String, CodingKey {
case id
}
let id: Int
let details: SomeDetails
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
details = try SomeDetails(from: decoder)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try details.encode(to: encoder)
}
}
对于添加的糖,您可以使用Swift 5s动态成员查找,以便您可以很好地访问这些成员object.name
。
@dynamicMemberLookup
struct SomeObject {
...
subscript<T>(dynamicMember member: KeyPath<SomeDetails, T>) -> T {
details[keyPath: member]
}
}