我正在嘗試為動態資料撰寫一個結構。資料的鍵是未知的,它們的值也是未知的。該結構如下所示:
enum EntryData: Codable {
case string(String)
case array([EntryData]
case nested([String: EntryData])
}
struct Entry: Codable {
var data: [String: EntryData]
}
這樣做的目標是能夠像這樣解碼 JSON:
{
"data": {
"testA": "valueA",
"testB": ["valueB", ["valueC"]],
"testC": {
"testD": "valueD",
"testE": ["valueE", "valueF"]
}
}
}
并具有以下代碼:
var data = EntryData(data: [
"testA": .string("valueA"),
"testB": .array([.string("valueB"), .array([.string("valueC")])]),
"testC": .nested([
"testD": .string("valueD"),
"testeE": .array([.string("valueE"), .string("valueF")])
])
])
編碼為上述 JSON 輸出。
這在 Swift 中可行嗎?如果是這樣,實作會是什么樣子?
提前謝謝了。
uj5u.com熱心網友回復:
您可以使用singleValueContainer對 的每種情況進行解碼/編碼EntryData,而無需使用任何硬編碼密鑰。解碼的時候,我們可以試著把三種情況都解碼,看哪一種成功了。
enum EntryData: Codable {
case string(String)
case array([EntryData])
case nested([String: EntryData])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let nested = try? container.decode([String: EntryData].self)
let array = try? container.decode([EntryData].self)
let string = try? container.decode(String.self)
switch (string, array, nested) {
case (let s?, nil, nil):
self = .string(s)
case (nil, let a?, nil):
self = .array(a)
case (nil, nil, let n?):
self = .nested(n)
default:
throw DecodingError.valueNotFound(
EntryData.self,
.init(codingPath: decoder.codingPath,
debugDescription: "Value must be either string, array or a dictionary!",
underlyingError: nil))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let s):
try container.encode(s)
case .array(let a):
try container.encode(a)
case .nested(let n):
try container.encode(n)
}
}
}
現在你可以這樣做:
let entry = try JSONDecoder().decode(Entry.self, from: data)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384088.html
