如何使用Codable
解碼JSON並在創建時交叉引用對象(不是結構體)?在這個例子中,我希望Painting
類具有也在JSON中定義的Color
對象的數組。 (我也希望能夠將它們編碼回JSON了。)在Swift 4中,如何使用Codable解碼JSON並在解碼對象之間創建引用?
獎勵:在這種情況下,我寧願Painting.colors
是一個非可選let
屬性而不是var
。我不希望它在創建後改變,我不希望它永遠是零。 (我寧願使用一個空數組,而不是零的默認值。)
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!)
我已經考慮一些方法:
Manually encoding/decoding的JSON。看起來像很多額外的工作,但也許它給我我需要的控制?
將JSON解碼分解成步驟。將JSON反序列化成一個字典,先拉出並解碼顏色,然後繪製(可以訪問上下文中的顏色)。這感覺就像對抗
Codable
,它要求你使用Data
而不是Dictionary
一次全部解碼。已有
Painting
通過動態屬性在運行時動態查找Color
。但在我開始真正的工作之前,我寧願讓所有的對象關係建立和驗證,然後永遠不要改變。但也許這將是最簡單的?不使用可編碼
其他一些不好的想法
我會完全反對JSON。它沒有(本地)表達引用的能力。 – Alexander
簡短的回答是:JSON不能做到這一點。如果你想要一個存檔器(即它比序列化爲JSON的功能更強大),目前您需要構建自己的,或者找到構建它的其他人。它在stdlib中不存在。 'NSKeyedArchiver'是當前可用的Cocoa工具。 –