CodableProperty

CI Status Version License Platform Swift Package Manager compatible

CodableProperty 是一个用 Swift 编写的框架,它与内置的 Codable 协议一起工作。它利用 Swift 5.1 的新 propertyWrapper 功能,使类型转换更容易。

示例

要运行示例项目,请克隆仓库,并首先从示例目录运行 pod install

要求

如何使用

要使用 CodableProperty,只需实现 CodableTransformer 协议,并在你的 Codable 模型中像这样使用它

@CodableProperty<CustomCodableTransformer> var someProperty: SomeType

例如,如果你有以下 JSON

{
    "currency": "PLN",
    "rates": {
        "USD": 3.76,
        "EUR": 4.24,
        "SEK": 0.41
    }
}

并且你想把它映射到一个像这样的模型中

struct CurrencyConversion {
    var currency: String
    var rates: [ExchangeRate]
}

struct ExchangeRate {
    let currency: String
    let rate: Double
}

你可以通过实现 CodableTransformer 协议将 JSON 类型转换为你的模型类型

struct RatesTransformer: CodableTransformer {
    typealias Value = [ExchangeRate]

    func value(from decoder: Decoder) throws -> Value {
        let container = try decoder.singleValueContainer()
        let dictionary = try container.decode([String: Double].self)

        return dictionary.map { key, value in
            ExchangeRate(currency: key, rate: value)
        }
    }

    func encode(value: Value, to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        let dictionary = value.reduce(into: [String: Double]()) { result, exchangeRate in
            result[exchangeRate.currency] = exchangeRate.rate
        }
        try container.encode(dictionary)
    }
}

并在你的 Codable 模型中像这样使用它

struct CurrencyConversion: Codable {
    var currency: String
    @CodableProperty<RatesTransformer> var rates: [ExchangeRate]
}

struct ExchangeRate {
    let currency: String
    let rate: Double
}

如果你的模型实现的是 Decodable 协议而不是 Codable 协议,你可以通过实现 DecodableTransformer 协议来专门进行解码过程中的类型转换

struct RatesTransformer: DecodableTransformer {
    typealias Value = [ExchangeRate]

    func value(from decoder: Decoder) throws -> Value {
        let container = try decoder.singleValueContainer()
        let dictionary = try container.decode([String: Double].self)

        return dictionary.map { key, value in
            ExchangeRate(currency: key, rate: value)
        }
    }
}

并像这样使用它

struct CurrencyConversion: Decodable {
    var currency: String
    @DecodableProperty<RatesTransformer> var rates: [ExchangeRate]
}

同样适用于 Encodable 模型

struct RatesTransformer: EncodableTransformer {
    typealias Value = [ExchangeRate]

    func encode(value: Value, to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        let dictionary = value.reduce(into: [String: Double]()) { result, exchangeRate in
            result[exchangeRate.currency] = exchangeRate.rate
        }
        try container.encode(dictionary)
    }
}

struct CurrencyConversion: Encodable {
    var currency: String
    @EncodableProperty<RatesTransformer> var rates: [ExchangeRate]
}

交流

安装

CocoaPods

CodableProperty 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到你的 Podfile

pod 'CodableProperty'

Swift Package Manager

要将 CodableProperty 添加到基于 Swift Package Manager 的项目中,请添加以下内容

.package(url: "https://github.com/gcharita/CodableProperty.git", from: "1.0.0")

到你的 Package.swiftdependencies 值中。

特别感谢

特别感谢 John Sundell。 他在 这篇文章 中的示例启发了我编写这个项目。

许可协议

CodableProperty 在 MIT 许可证下可用。 有关更多信息,请参阅 LICENSE 文件。