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]
}
CodableProperty 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到你的 Podfile
pod 'CodableProperty'
要将 CodableProperty 添加到基于 Swift Package Manager 的项目中,请添加以下内容
.package(url: "https://github.com/gcharita/CodableProperty.git", from: "1.0.0")
到你的 Package.swift
的 dependencies
值中。
特别感谢 John Sundell。 他在 这篇文章 中的示例启发了我编写这个项目。
CodableProperty 在 MIT 许可证下可用。 有关更多信息,请参阅 LICENSE 文件。