Platform Compatibility Swift Compatibility Action Status MIT License

CodableX 提供了属性包装器,可以方便地按照您想要的方式解码和编码结构体或类,而无需从头开始实现自定义的 codable 结构体或类。

安装

Swift Package Manager

在您的 Package.swift 中添加它作为依赖项,

dependencies: [
    .package(url: "https://github.com/dscyrescotti/CodableX.git", from: "0.2.0")
]

CocoaPods

在您的 Podfile 中,

pod 'CodableX', :git => 'https://github.com/dscyrescotti/CodableX.git'

目前,可以通过 Swift Package ManagerCocoaPods 安装 CodableX

@AnyValuable

@AnyValuable 与原始的 @Anyable 属性包装器非常相似。 它将解码后的值包装在 AnyValue 中,该值可以保存符合 AnyCodable 的类型,并且提供比 Any 更容易的访问值的方式。

用法

使用 CodableX 的默认选项。

struct  AnyValuableExample: Codable {
    @AnyValuable<DefaultOptions> var value: AnyValue  // Int, String, Bool or Double inside AnyValue
}

let data = #"{ "value": 1 }"#.data(using: .utf8)!

let decoded = try  JSONDecoder().decode(AnyValuableExample.self, from: data)

print(decoded) // AnyValuableExample(value: AnyValue(value: 1))

注意:DefaultOptions 仅支持 IntStringBoolDouble

访问 AnyValue 中的值

// You can directly access data via value
print(decoded.value) // 1

或者

// You can access data via type casting. It's helpful for optional unwrapping and is also clear to read.
print(decoded.value.int) // Optional(1)

注意:AnyValue 已经为 Swift 内置类型进行了类型转换。 对于您的自定义类型,您可以扩展 AnyValue 来声明它们。

使用自定义选项。

struct  Custom: AnyCodable {
    let value: String
}

// For type casting
extension AnyValue {
	var custom: Custom? {
		value as? Custom
	}
}


struct  CustomOptions: OptionConfigurable {
    static  var options: [Option] = [
        .init(Int.self),
        .init(Custom.self),
        // add more
    ]
}

struct  AnyValuableExample: Codable {
    @AnyValuable<CustomOptions> var value: AnyValue  // Int, Custom or types you specify inside AnyValue
}

注意:结构体或类的所有选项必须符合 AnyCodable

对于 AnyValuable 数组和可选的 AnyValuable,您可以使用 @ArrayAnyValuable@OptionalAnyValuable

@Anyable

@Anyable 旨在解码和编码与您预配置的类型之一匹配的任何值。 当 API 响应的值肯定是 API 发送的值之一时,它非常方便。

用法

使用 CodableX 的默认选项。

struct  AnyableExample: Codable {
    @Anyable<DefaultOptions> var value: Any  // Int, String, Bool or Double
}

let data = #"{ "value": 1 }"#.data(using: .utf8)!

let decoded = try  JSONDecoder().decode(AnyableExample.self, from: data)

print(decoded) // AnyableExample(value: 1)

注意:DefaultOptions 仅支持 IntStringBoolDouble

使用自定义选项。

struct  Custom: AnyCodable {
    let value: String
}

struct  CustomOptions: OptionConfigurable {
    static  var options: [Option] = [
        .init(Int.self),
        .init(Custom.self),
        // add more
    ]
}

struct  AnyableExample: Codable {
    @Anyable<CustomOptions> var value: Any  // Int, Custom or types you specify
}

注意:结构体或类的所有选项必须符合 AnyCodable

对于 Anyable 数组和可选的 Anyable,您可以使用 @ArrayAnyable@OptionalAnyable

@Forcable

所有功劳归于 BetterCodable

@Forcable 用于强制将值在解码时设为您设置的特定类型。

用法

struct  ForceValue: Codable {
    @Forcable<Bool, DefaultOptions> var value: Bool
}

let data = #"{ "value": "true" }"#.data(using: .utf8)!

let decoded = try  JSONDecoder().decode(ForceValue.self, from: data)

print(decoded) // ForceValue(value: true)

它允许您自定义选项列表,就像 @Anyable 一样。 它将从您的列表中找到与 API 响应的数据匹配的类型,然后强制转换为您想要的特定类型。

对于 Forcable 数组和可选的 Forcable,您可以使用 @ArrayForcable@OptionalForcable

@Nullable

@Nullable 用作 Swift 的传统 Optional(又名 ?)。 编码时,它能够将 nil 编码为 JSON 中的 null

用法

struct  NullValue: Codable {
    @Nullable  var value: Int?
}

let data = #"{ "value": null }"#.data(using: .utf8)!

let decoded = try  JSONDecoder().decode(NullValue.self, from: data)

print(decoded) // NullValue(value: nil)

@Defaultable

@Defaultable 在找不到 coding key 或值丢失时提供默认值。

用法

对于 Swift 内置类型,它将使用默认的 init() 方法。 对于您的自定义结构体或类,您必须使它们符合 DefaultCodable 并设置默认值。

struct  DefaultValue: Codable {
    @Defaultable  var value: String
}

let data = #"{ "value": null }"#.data(using: .utf8)!

let decoded = try  JSONDecoder().decode(DefaultValue.self, from: data)

print(decoded) // DefaultValue(value: "")

如果您想要相同结构体或类的不同默认值,或者您需要内置类型的自定义默认值,@CustomDefaultable 将会解决它。

struct  CustomDefault: DefaultConfigurable {
    static  var defaultValue: String = "dope"
}

struct  DefaultValue: Codable {
    @CustomDefaultable<String, CustomDefault> var value: String
}

@Compactable

@Compactable 旨在解码可选值数组并存储非空值。 它的名字来自 Swift 的 compactMap(_:),因为它从数组中删除空值和无效值。

用法

struct  CompactValue: Codable {
    @Compactable  var array: [Int]
}

@Jsonable

@Jsonable 方便地使用 Swift 的字典将数据解码为 JSON 对象结构。 从字面上看,它的工作方式类似于 JavaScript 中的 JSON.parse()

用法

struct  JsonValue: Codable {
    @Jsonable  var json: Any
}

作者

Dscyre Scotti (@dscyrescotti)

致谢

CodableX 的灵感来自 BetterCodableAnyCodable

贡献

如果您有任何改进的想法,或者发现任何类型的错误,CodableX 欢迎所有开发者贡献并提出 issue。

许可证

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