如何将 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方法给我上面的两个错误。现在不确定我做错了什么,或者我是否走在正确的轨道上。

知道我做错了什么以及导致这两个模棱两可的错误的原因吗?

关联的 valueLoggedInStateLoggedOutState 但您必须对其进行编码 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 创建枚举案例。