Swift Codable: 服务端新增枚举类型解析失败?

2022-05-06  本文已影响0人  夏天然后

前言: 服务端新增枚举类型, 客户端数据解析失败如何解决?

  1. 首先定义一个枚举类型, 准备在 model 中使用
/// 交易类型
enum TradeType: Int, CaseIterable {

    /// 普通商品交易进账
    case generalIncome = 1

    /// 提现成功
    case withdrawSuccess = 2

    /// 提现中
    case withdrawing = 5

    /// 提现失败
    case withdrawFailed = 6

    /// 匠人余额扣除
    case balanceDeduction = 7

    /// 卡券交易进账
    case couponIncome = 8

    /// 匠人保证金扣除
    case depositDeduction = 20

    /// 锁粉订单佣金减免
    case lockFansOrderCommissionReduce = 21
}

extension TradeType: Codable {}

在 model 中使用枚举

/// 收支明细列表项
struct TradingListItemModel: DJModel {
    
    /// 记录 ID
    @Codec
    var id: Int = 0
    
    /// 操作描述
    var desc: String?
    
    /// 交易类型
    var type: TradeType?
    
    /// 操作后剩余金额
    @Codec
    var remainAmount: CurrencyFen = 0
    
    /// 操作金额
    var amount: String?
}

如果是上面的定义会存在一个问题, 如果后续, 服务端扩展枚举类型, 而移动端没有进行对应的修改, 数据解析会不成功

所以接下来 我们 需要 有后备 case 的 Enum, 也就是说, 我们可以让 TradeType 这个 Enum 自动处理未知情况。 具体需要怎么做呢

声明一个协议,叫 CodableEnumeration:

protocol CodableEnumeration: RawRepresentable, Codable where RawValue: Codable {
    static var defaultCase: Self { get }
}

通过 extension,让协议提供默认 Decode 方法:

extension CodableEnumeration {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            let decoded = try container.decode(RawValue.self)
            self = Self.init(rawValue: decoded) ?? Self.defaultCase
        } catch {
            self = Self.defaultCase
        }
    }
}

之后枚举遵循这个协议

/// 交易类型
enum TradeType: Int, CaseIterable, CodableEnumeration {

    static var defaultCase: TradeType {
        .unknown
    }

    /// 未知
    case unknown = 99

    /// 普通商品交易进账
    case generalIncome = 1

    /// 提现成功
    case withdrawSuccess = 2

之后就不怕服务端新增类型, 做到能很好的兼容数据问题 !

上一篇下一篇

猜你喜欢

热点阅读