Codable
在创建对象(不是结构)时,如何使用它们来解码 JSON 并交叉引用它们?在此示例中,我希望Painting
该类具有Color
也在 JSON 中定义的对象数组。(我也希望能够将它们编码回 JSON。)
奖励:在这种情况下,我更愿意Painting.colors
成为非可选let
属性而不是 var
. 我不希望它在创建后改变,我也不希望它永远为零。(我宁愿使用空数组的默认值而不是 nil。)
class Art: Codable {
var colors: [Color]?
var Paintings: [Painting]?
}
class Color: Codable {
var id: String?
var hex: String?
}
class Painting: Codable {
var name: String?
var colors: [Color]?
}
let json = """
{
"colors": [
{"id": "black","hex": "000000"
},
{"id": "red", "hex": "FF0000"},
{"id": "blue", "hex": "0000FF"},
{"id": "green", "hex": "00FF00"},
{"id": "yellow", "hex": "FFFB00"},
{"id": "orange", "hex": "FF9300"},
{"id": "purple", "hex": "FF00FF"}
],
"paintings": [
{
"name": "Starry Night",
"colorIds": ["blue", "black", "purple", "yellow"]
},
{
"name": "The Scream",
"colorIds": ["orange", "black", "blue"]
},
{
"name": "Nighthawks",
"colorIds": ["green", "orange", "blue", "yellow"]
}
]
}
"""
let data = json.data(using: .utf8)
let art = try JSONDecoder().decode(Art.self, from: data!)
我考虑过的一些方法:
手动编码/解码json。似乎需要做很多额外的工作,但也许它给了我所需的控制权?
将 JSON 解码分解为多个步骤。将 JSON 反序列化为字典,首先提取并解码颜色,然后是绘画(可以访问上下文中的颜色)。这感觉就像是在与
Codable
想要你一次使用Data
而不是Dictionary
.通过动态属性在运行时
Painting
动态查找s。Color
但我更愿意在开始真正的工作之前设置和验证所有对象关系,然后再不改变。但也许这将是最简单的?不使用可编码
其他一些坏主意