我必须反序列化这样的JSON字符串:
{ "name" : "John Smith", "value" : "someValue" }
在Swift 4中,其中"值"应该是一个枚举,整个对象是一个结构,如:
struct MyType {
name: String?
value: Value?
}
在未来的某个时刻,可能会在后端添加新的枚举值,所以我认为有一些后备是明智的。
我以为我可以创建一个像
这样的枚举enum Value {
case someValue
case someOtherValue
case unknown(value: String)
}
但我无法解决如何对该枚举进行反序列化并使其工作的问题。以前我只使用了String
枚举,但反序列化未知值会引发错误。
是否有一种简单的方法可以使其工作,或者我应该将值反序列化为String
并使用switch语句在结构中创建自定义getter以返回其中一种情况(可能甚至不在结构中)本身,但在我看来模型)?
答案 0 :(得分:3)
您可以实施init(from decoder: Decoder)
和encode(to encoder: Encoder)
并明确处理每个案例,即
struct MyType: Codable
{
var name: String?
var value: Value?
enum CodingKeys: String, CodingKey
{
case name
case value
}
init(from decoder: Decoder) throws
{
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
let strValue = try values.decode(String.self, forKey: .value)
//You need to handle every case explicitly
switch strValue
{
case "someValue":
value = Value.someValue
case "someOtherValue":
value = Value.someOtherValue
default:
value = Value.unknown(value: strValue)
}
}
func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
if let val = value
{
//You need to handle every case explicitly
switch val
{
case .someValue, .someOtherValue:
try container.encode(String(describing: val), forKey: .value)
case .unknown(let strValue):
try container.encode(strValue, forKey: .value)
}
}
}
}
enum Value
{
case someValue
case someOtherValue
case unknown(value: String)
}