将未知的 Encodable 枚举值解码为默认值
Decoding unknown Encodable enum values to a default
我必须像这样反序列化 JSON 字符串:
{ "name" : "John Smith", "value" : "someValue" }
in Swift 4,其中 "value" 应该是一个枚举,整个对象是一个结构,如:
struct MyType {
name: String?
value: Value?
}
在未来的某个时候,可能会在后端添加新的枚举值,所以我认为有一些回退是明智的。
我想我可以创建一个像
这样的枚举
enum Value {
case someValue
case someOtherValue
case unknown(value: String)
}
但我只是想不通如何反序列化该枚举并使其正常工作。以前我只是简单地使用了一个 String
枚举,但是反序列化未知值会引发错误。
有没有一种简单的方法可以使它工作,或者我应该将值反序列化为 String
并在结构中创建一个自定义 getter,并将 switch 语句转换为 return 一个案例(可能甚至不在结构本身中,而是在我的视图模型中)?
您可以实施 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)
}
我必须像这样反序列化 JSON 字符串:
{ "name" : "John Smith", "value" : "someValue" }
in Swift 4,其中 "value" 应该是一个枚举,整个对象是一个结构,如:
struct MyType {
name: String?
value: Value?
}
在未来的某个时候,可能会在后端添加新的枚举值,所以我认为有一些回退是明智的。
我想我可以创建一个像
这样的枚举enum Value {
case someValue
case someOtherValue
case unknown(value: String)
}
但我只是想不通如何反序列化该枚举并使其正常工作。以前我只是简单地使用了一个 String
枚举,但是反序列化未知值会引发错误。
有没有一种简单的方法可以使它工作,或者我应该将值反序列化为 String
并在结构中创建一个自定义 getter,并将 switch 语句转换为 return 一个案例(可能甚至不在结构本身中,而是在我的视图模型中)?
您可以实施 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)
}