由於具有關聯類型的enum
與任何JSON類型都不匹配,因此需要多一點手工並編寫自定義映射。
以下代碼包含三個選項。
- 與本案作爲密鑰A字典,並用參數的標籤作爲鍵的含詞典
- 編碼/解碼每個相關值作爲單獨的鍵/值對
- 編碼/解碼與陣列中的所有相關聯的值一個任意的鍵。
所有枚舉首先必須不符合Codable
enum PostType {
case fast(value: Int, value2: Int)
case middle(bool: Bool)
case slow(string: String, string2: String)
}
殼體fast
使用數組,middle
子字典,slow
單獨的密鑰/值對。
然後聲明MyStruct
結構,採用Codable
並聲明type
struct MyStruct : Codable {
var type : PostType
該解決方案需要自定義鍵
enum CodingKeys: String, CodingKey {
case value, string, string2, middle
}
的encode
方法的情況下switch
ES並創建相應類型
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch type {
case .fast(let value, let value2) :
try container.encode([value, value2], forKey: .value)
case .slow(let string, let string2) :
try container.encode(string, forKey: .string)
try container.encode(string2, forKey: .string2)
case .middle(let bool):
try container.encode(["bool" : bool], forKey: .middle)
}
}
在decode
方法中,您可以通過傳遞的鍵區分這些情況,確保它們是唯一的。
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let allKeys = values.allKeys
if allKeys.contains(.middle) {
let value = try values.decode([String:Bool].self, forKey: .middle)
type = PostType.middle(bool: value["bool"]!)
} else if allKeys.contains(.value) {
let value = try values.decode([Int].self, forKey: .value)
type = PostType.fast(value: value[0], value2: value[1])
} else {
let string = try values.decode(String.self, forKey: .string)
let string2 = try values.decode(String.self, forKey: .string2)
type = PostType.slow(string: string, string2: string2)
}
}
}
雖然有些鍵是硬編碼的,但第一個選項似乎是最合適的。
最後一個例子來使用它:
let jsonString = "[{\"value\": [2, 6]}, {\"string\" : \"foo\", \"string2\" : \"bar\"}, {\"middle\" : {\"bool\" : true}}]"
let jsonData = jsonString.data(using: .utf8)!
do {
let decoded = try JSONDecoder().decode([MyStruct].self, from: jsonData)
print("decoded:", decoded)
let newEncoded = try JSONEncoder().encode(decoded)
print("re-encoded:", String(data: newEncoded, encoding: .utf8)!)
} catch {
print(error)
}
這不是重複。這個問題是解碼一個結構。這是解碼一個元組的Enum。我知道如何解碼結構,但與枚舉是非常不同的。 –
什麼是您預期的關聯枚舉值的JSON表示? – vadian
@vadian多數民衆贊成的事情。我知道我希望我的結構看起來像'MyStruct',但我不知道JSON應該是什麼樣子。如果有人能告訴我,那麼我可以讓JSON成爲那個價值。 –