首页 > 解决方案 > 解码一个带有额外 Codable 属性的包装 Codable 类型的 Swift 类型

问题描述

我有一个 Codable 类型,比方说Car,它定义为:

struct Car: Codable {
    let age: Int
    let color: String
}

我可以很好地编码/解码这个。

使用我的持久性系统,当一个对象被存储时,它会被分配一个_id属性,即 a String,例如5cae04b533376609456d40ed

因此,当我Data从持久存储中读取并尝试对其进行解码时,其中有额外的字节表示_id属性及其关联String值。

我无法控制可以编码和存储在商店中的各种类型。对它们的唯一限制是它们是Codable.

我想要做的是将Data我从商店读取时得到的(包含的_id东西)解码为类似于 的类型,Wrapped<T: Codable>它将被定义为(以最简单的形式):

struct Wrapped<T: Codable> {
    let _id: String
    let value: T
}

但是,我不确定要这样做。

我所做的一次尝试是定义一个自定义decode函数,但这并没有走得太远,因为我似乎无法访问该T类型的CodingKeys,据我所知,这使得事情不可能使用这种方法。

也许还有另一种方法可以让事情按我的意愿工作?

标签: swiftcodable

解决方案


您可以为您的类型编写一个自定义解码函数Wrapped,解析出_id然后将解码器传递给包装类型,以便它可以解码它自己的属性:

struct Wrapped<T: Codable>: Decodable {
    let _id: String
    let value: T

    private enum CodingKeys: String, CodingKey {
        case _id
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        _id = try container.decode(String.self, forKey: ._id)
        value = try T(from: decoder)
    }
}

推荐阅读