可编码属性 1.0.0

CodableProperty 1.0.0

Giorgos Charitakis维护。



  • 作者
  • gcharita

CodableProperty

CI Status Version License Platform Swift Package Manager compatible

CodableProperty是一个用Swift编写的框架,它与内置的Codable协议协同工作。使用Swift 5.1的新功能propertyWrapper,以便于类型转换。

示例

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

要求

  • iOS 8.0+ / macOS 10.9+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 11+
  • Swift 5.1+

如何使用

要使用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包管理器

要将CodableProperty添加到基于Swift Package Manager的工程中,添加以下代码到您的Package.swift文件的dependencies值中。

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

在您的Package.swift文件中添加以下代码到dependencies值中。

特殊的感谢

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

许可证

CodableProperty是在MIT许可证下可用的。更多信息请参阅LICENSE文件。