提供 Swift 宏,用于自动生成可定制的 Codable
协议实现。
当我们将自定义类型遵循 Codable
协议时,Swift 编译器已经提供了自动实现。当您负责定义编码/解码格式时,这很好,但不幸的是,情况并非总是如此。当格式由其他人定义时,我们可能需要使用奇怪的属性名称,甚至自己实现 encode(to:)
和 init(:from)
。
当使用某些第三方提供的 REST API 时,通常会发生此类问题。例如,我们可能期望一个 Person
结构体如下所示
public struct Person: Codable {
var id: String
var name: String
var age: Int
}
但是,由于某些原因,REST API 的响应主体可能如下所示
{
"data": {
"id": "9F6E1D7A-EF6A-4F7A-A1E0-46105DD31F3E",
"meta": {
"name": "Serika",
"age": 15
}
}
}
在这种情况下,我们必须自己实现对 Codable
的遵循。
为了以更“Swift 式”的方式处理这种情况,swift-codable-macro
可以提供帮助。对于上面的例子,我们可以这样声明 Person
结构体
@Codable
public struct Person {
@CodingField("data", "id")
var id: String
@CodingField("data", "meta", "name")
var name: String
@CodingField("data", "meta", "age")
var age: Int
}
完成!Codable
的遵循以及 encode(to:)
和 init(from:)
的实现将自动生成!无需其他额外的实现代码!
这还不是此软件包的全部功能。以下代码简要概述了它可以做什么。
@Codable
struct Person {
@CodingField("data", "id")
@DecodeTransform(source: String.self, with: { UUID(uuidString: $0)! })
@EncodeTransform(source: UUID.self, with: \.uuidString)
var id: UUID
@CodingField("data", "meta", "name")
@CodingValidate(source: String.self, with: { !$0.isEmpty })
@CodingValidate(source: String.self, with: { !$0.contains(where: { $0.isNumber }) })
var name: String
@CodingIgnore
var habit: String = "writing Swift Macro"
}
@SingleValueCodable
struct FilePath {
@SingleValueCodableDelegate
var storage: String
var isDir: Bool = false
}
Codable
注释一个类或结构体,使其自动遵循 Codable
协议。它将查找类型定义中的所有存储属性,并基于找到的任何自定义项生成实现。
CodingField(_:default:)
为存储属性指定自定义编码路径和默认值。如果未提供编码路径,将使用属性的名称。不需要使用 default
参数设置默认值,您还可以为属性提供标准初始化器或使用可选类型。该宏能够考虑到这一点。
CodingIgnore
使存储属性在进行编码/解码时被忽略。它要求该属性是可选的或具有标准初始化器。
DecodeTransform(source:with:)
为属性的解码指定自定义转换。它将首先尝试将值解码为提供的 sourceType
,然后使用提供的转换来转换它。
EncodeTransform(source:with:)
为属性的编码指定自定义转换。它将首先使用提供的转换来转换该值,然后对转换后的值进行编码。
CodingValidate(source:with:)
为属性的解码指定验证规则。
SingleValueCodable
注释一个类或结构体,使其自动遵循 Codable
协议,通过提供的规则将一个实例从/转换为另一个符合 Codable
的类型的实例。
可以通过以下方式提供规则:
singleValueEncode()
和 init(from:)
SingleValueCodableDelegate
宏注释其中一个存储属性SingleValueCodableDelegate
与 SingleValueCodable
一起使用,将属性标记为编码和解码的唯一目标。
在 Package.swift
中,将以下行添加到您的依赖项中
.package(url: "https://github.com/Star-Lord-PHB/swift-codable-macro.git", from: "2.0.0")
将 CodableMacro
添加为目标的依赖项
.target(
name: "Target",
dependencies: [
.product(name: "CodableMacro", package: "swift-codable-macro"),
]
)
在您的源代码中添加 import CodableMacro
。