DefaultCodable 是一个 Swift 微型库,它提供了一种便捷的方式,可以在 Codable
类型中为不存在或值为 nil
的属性定义默认值。
考虑一个假设的 Apple 产品模型,其中只有属性 name
是必需的。
enum ProductType: String, Codable, CaseIterable {
case phone, pad, mac, accesory
}
struct Product: Codable {
var name: String
var description: String?
var isAvailable: Bool?
var type: ProductType?
}
使用 @Default
属性包装器,我们可以为非必需属性提供默认值,从而消除模型中的可选项。
struct Product: Codable {
var name: String
@Default<Empty>
var description: String
@Default<True>
var isAvailable: Bool
@Default<FirstCase>
var type: ProductType
}
这样设置之后,我们可以安全地将以下 JSON 解码为 Product
类型。
{
"name": "iPhone 11 Pro"
}
生成的 Product
实例将使用 JSON 中不存在的属性的默认值。
▿ Product
- name : "iPhone 11 Pro"
- description : ""
- isAvailable : true
- type : ProductType.phone
如果将结果编码回 JSON,则生成的 JSON 将与我们开始使用的 JSON 相同。如果 @Default
属性包装器的值等于默认值,则不会编码该值。
@Default
属性包装器接受一个 DefaultValueProvider
作为参数。当值不存在或为 nil
时,此类型提供默认值。
protocol DefaultValueProvider {
associatedtype Value: Equatable & Codable
static var `default`: Value { get }
}
DefaultCodable 提供了以下实现,以方便您的使用
它提供了一个 String
、Array
或任何实现了 RangeReplaceableCollection
的类型的空实例。
它提供了一个 Dictionary
的空实例。
分别为 Bool
属性提供 true
和 false
。
分别为 Int
属性提供 0
和 1
。
它提供 enum
类型的第一个 case 作为默认值。该 enum
必须实现 CaseIterable
协议。
为 Double
属性提供 0
。
您的自定义类型必须实现 DefaultValueProvider
协议才能与 @Default
属性包装器兼容。
考虑以下对会话中的角色进行建模的类型
struct Role: Codable, Equatable, Hashable, RawRepresentable {
let rawValue: String
init?(rawValue: String) {
self.rawValue = rawValue
}
static let user = Role(rawValue: "user")!
static let bot = Role(rawValue: "bot")!
}
如果我们希望默认角色为 user
,我们可以按如下方式实现 DefaultValueProvider
extension Role: DefaultValueProvider {
static let `default` = user
}
这样设置之后,我们可以在任何具有 Role
类型属性的类型中使用 @Default
属性包装器
struct ChannelAccount: Codable {
var name: String
@Default<Role>
var role: Role
}
使用 Swift Package Manager
将 DefaultCodable 作为依赖项添加到您的 Package.swift
文件。 有关更多信息,请参见 Swift Package Manager 文档。
.package(url: "https://github.com/gonzalezreal/DefaultCodable", from: "1.0.0")
DefaultCodable
进行一些更改,请打开一个 PR。