如何将 Codable 协议用于具有其他枚举作为关联值的枚举(嵌套枚举)
How to use Codable protocol for an enum with other enum as associated value (nested enum)
我昨天问 如何在 UserDefaults
中保存嵌套枚举。
我正在尝试为此使用 Codable
协议,但不确定我是否正确执行。
这又是我要存储的枚举 -> UserState
:
enum UserState {
case LoggedIn(LoggedInState)
case LoggedOut(LoggedOutState)
}
enum LoggedInState: String {
case playing
case paused
case stopped
}
enum LoggedOutState: String {
case Unregistered
case Registered
}
以下是我到目前为止执行的步骤:
遵守 Codable 协议并指定我们使用的密钥 encode/decode:
extension UserState: Codable {
enum CodingKeys: String, CodingKey {
case loggedIn
case loggedOut
}
enum CodingError: Error {
case decoding(String)
}
}
为解码添加了初始值设定项:
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let loggedIn = try? values.decode(String.self, forKey: .loggedIn) {
self = .LoggedIn(LoggedInState(rawValue: loggedIn)!)
}
if let loggedOut = try? values.decode(String.self, forKey: .loggedOut) {
self = .LoggedOut(LoggedOutState(rawValue: loggedOut)!)
}
throw CodingError.decoding("Decoding failed")
}
添加编码方法:
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .LoggedIn(value):
try container.encode(value, forKey: .loggedIn) // --> Ambiguous reference to member 'encode(_:forKey:)'
case let .LoggedOut(value):
try container.encode(value, forKey: .loggedOut) // --> Ambiguous reference to member 'encode(_:forKey:)'
}
}
encode
方法给我上面的两个错误。现在不确定我做错了什么,或者我是否走在正确的轨道上。
知道我做错了什么以及导致这两个模棱两可的错误的原因吗?
关联的 value
是 LoggedInState
或 LoggedOutState
但您必须对其进行编码 rawValue
(字符串):
case let .LoggedIn(value):
try container.encode(value.rawValue, forKey: .loggedIn)
case let .LoggedOut(value):
try container.encode(value.rawValue, forKey: .loggedOut)
}
根据 decode
方法从 rawValue
创建枚举案例。
我昨天问 UserDefaults
中保存嵌套枚举。
我正在尝试为此使用 Codable
协议,但不确定我是否正确执行。
这又是我要存储的枚举 -> UserState
:
enum UserState {
case LoggedIn(LoggedInState)
case LoggedOut(LoggedOutState)
}
enum LoggedInState: String {
case playing
case paused
case stopped
}
enum LoggedOutState: String {
case Unregistered
case Registered
}
以下是我到目前为止执行的步骤:
遵守 Codable 协议并指定我们使用的密钥 encode/decode:
extension UserState: Codable {
enum CodingKeys: String, CodingKey {
case loggedIn
case loggedOut
}
enum CodingError: Error {
case decoding(String)
}
}
为解码添加了初始值设定项:
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let loggedIn = try? values.decode(String.self, forKey: .loggedIn) {
self = .LoggedIn(LoggedInState(rawValue: loggedIn)!)
}
if let loggedOut = try? values.decode(String.self, forKey: .loggedOut) {
self = .LoggedOut(LoggedOutState(rawValue: loggedOut)!)
}
throw CodingError.decoding("Decoding failed")
}
添加编码方法:
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .LoggedIn(value):
try container.encode(value, forKey: .loggedIn) // --> Ambiguous reference to member 'encode(_:forKey:)'
case let .LoggedOut(value):
try container.encode(value, forKey: .loggedOut) // --> Ambiguous reference to member 'encode(_:forKey:)'
}
}
encode
方法给我上面的两个错误。现在不确定我做错了什么,或者我是否走在正确的轨道上。
知道我做错了什么以及导致这两个模棱两可的错误的原因吗?
关联的 value
是 LoggedInState
或 LoggedOutState
但您必须对其进行编码 rawValue
(字符串):
case let .LoggedIn(value):
try container.encode(value.rawValue, forKey: .loggedIn)
case let .LoggedOut(value):
try container.encode(value.rawValue, forKey: .loggedOut)
}
根据 decode
方法从 rawValue
创建枚举案例。