如何使用Codable协议将枚举与其他枚举作为关联值(嵌套枚举)

时间:2018-01-20 16:01:05

标签: swift enums codable

昨天我问question如何在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协议并指定我们用于编码/解码的密钥:

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

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

1 个答案:

答案 0 :(得分:1)

关联的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创建枚举案例。