Swift enum类型添加Codable默认值

1,851 阅读1分钟

Swift开发中在数据转model这一层,我采用了苹果官方的Codable协议来实现。Codable的具体步骤可以参考网上一大堆教程。 后台有时候会返回一些表示枚举的字符串数值,在转成model的过程中,会把这个字段设置成对应的Swift枚举。

enum ToolType: String, Codable {
    /// 自行车
    case Bike = "1"
    /// 电瓶车
    case Electromobile = "2"
    /// 大踏板车
    case Scooter = "3"
    /// 摩托车
    case Motorbike = "4"
    /// 轿车
    case Sedan = "5"
    /// 小货车
    case Buggy = "6"
}

struct Model {
    var toolType: ToolType?
}

extension Model: Codable {
    enum CodingKeys: String, CodingKey {
        case toolType = "tool_type"
    }
}

这样就可以很方便的实现数据转model。

但是如果后台返回的数据对应值不止 1~6 会怎么样呢?

答案是解析会抛出异常直接报错。

当数据转model的时候,实际调用的是这个方法

init(from decoder: Decoder) throws

如果出现value和enum的值都匹配不上的情况,并不会返回nil而是直接抛出异常。

所以我们要做的就是当解析出错的时候设置一个默认值

通过extension给Codable协议添加默认值

protocol CaseIterableDefaultsLast: Encodable & Decodable & CaseIterable & RawRepresentable where RawValue: Decodable, AllCases: BidirectionalCollection {}

extension CaseIterableDefaultsLast {
    init(from decoder: Decoder) throws {
        self = try Self(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? Self.allCases.last!
    }
}

enum ToolType: String, CaseIterableDefaultsLast {
    /// 自行车
    case Bike = "1"
    /// 电瓶车
    case Electromobile = "2"
    /// 大踏板车
    case Scooter = "3"
    /// 摩托车
    case Motorbike = "4"
    /// 轿车
    case Sedan = "5"
    /// 小货车
    case Buggy = "6"
    /// 未知
    case Unknown
}

如果初始化失败返回nil,则默认取最后一个为默认值。