CodableWrappers完全指南:用属性包装器简化Swift序列化的终极方案
【免费下载链接】CodableWrappersA Collection of PropertyWrappers to make custom Serialization of Swift Codable Types easy项目地址: https://gitcode.com/gh_mirrors/co/CodableWrappers
CodableWrappers是一个强大的Swift库,它通过属性包装器(Property Wrappers)让自定义序列化变得前所未有的简单。无论你是处理复杂的日期格式、特殊的布尔值表示,还是需要灵活的编码键策略,这个库都能提供直观且高效的解决方案,帮助开发者轻松应对各种序列化挑战。
为什么选择CodableWrappers?
在Swift开发中,Codable协议为数据序列化提供了基础支持,但面对实际项目中多样化的序列化需求,原生实现往往显得力不从心。CodableWrappers通过属性包装器这一优雅的设计模式,将复杂的序列化逻辑封装起来,让代码更加清晰、可维护。
核心优势
- ** declarative语法**:用简洁的属性包装器注解代替繁琐的手动编码/解码逻辑
- 丰富的内置解决方案:涵盖日期、数据、布尔值、集合等多种类型的序列化需求
- 高度可定制:轻松扩展以支持项目特有的序列化规则
- 减少样板代码:大幅简化Codable类型的实现
快速开始:安装与基础使用
安装方式
Swift Package Manager(推荐)
在你的Package.swift文件中添加以下依赖:
dependencies: [ .package(url: "https://gitcode.com/gh_mirrors/co/CodableWrappers.git", .upToNextMajor(from: "3.0.0" )), ]CocoaPods
pod 'CodableWrappers', '~> 3.0.0'第一个示例
下面是一个简单示例,展示了如何使用CodableWrappers简化用户模型的序列化:
@CustomCodable @SnakeCase struct User: Codable { let firstName: String let lastName: String @SecondsSince1970DateCoding var joinDate: Date @CustomCodingKey("data") var imageData: Data }在这个例子中:
@CustomCodable启用自定义编码功能@SnakeCase自动将属性名转换为snake_case编码键@SecondsSince1970DateCoding将Date类型序列化为时间戳@CustomCodingKey("data")为imageData属性指定自定义编码键
强大的编码键策略
CodableWrappers提供了丰富的编码键转换宏,满足各种命名风格需求:
常用编码键宏
| 宏 | 效果 | 示例 |
|---|---|---|
| @SnakeCase | 转换为snake_case | firstName → first_name |
| @CamelCase | 转换为camelCase | first-name → firstName |
| @PascalCase | 转换为PascalCase | firstProperty → FirstProperty |
| @KebabCase | 转换为kebab-case | firstName → first-name |
| @ScreamingSnakeCase | 转换为SCREAMING_SNAKE_CASE | firstName → FIRST_PROPERTY |
自定义编码键
除了预设的命名风格,你还可以使用@CustomCodingKey为单个属性指定任意编码键:
@CustomCodable struct UserProfile: Codable { @CustomCodingKey("user_name") let username: String @CustomCodingKey("registration_date") @ISO8601DateCoding let registerDate: Date }前缀和后缀
使用@CodingKeyPrefix和@CodingKeySuffix可以为整个结构体或单个属性的编码键添加前缀或后缀:
@CustomCodable @CodingKeyPrefix("user_") struct User: Codable { let name: String // 编码键为 "user_name" let age: Int // 编码键为 "user_age" @CodingKeySuffix("_info") let email: String // 编码键为 "user_email_info" }数据类型序列化定制
CodableWrappers为各种常见数据类型提供了专门的属性包装器,解决特定的序列化需求。
日期序列化
处理不同格式的日期是序列化中常见的挑战,CodableWrappers提供了多种日期编码方案:
struct Event: Codable { @SecondsSince1970DateCoding var timestamp: Date // 时间戳(秒) @MillisecondsSince1970DateCoding var preciseTime: Date // 时间戳(毫秒) @ISO8601DateCoding var isoDate: Date // ISO8601格式 @DateFormatterCoding<CustomDateCoder> var customDate: Date // 自定义格式 } // 自定义日期编码器示例 struct CustomDateCoder: DateFormatterStaticCoder { static let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" return formatter }() }数据(Data)序列化
对于Data类型,最常见的需求是Base64编码:
struct ImageData: Codable { @Base64Coding var image: Data // 自动进行Base64编码/解码 }布尔值序列化
有时后端API会使用数字或字符串表示布尔值:
struct Settings: Codable { @BoolAsIntCoding var isEnabled: Bool // 1表示true,0表示false @BoolAsStringCoding var isVerified: Bool // "true"表示true,"false"表示false }集合类型处理
处理包含nil值的集合时,可以使用Lossy系列包装器过滤nil值:
struct DataModel: Codable { @LossyArrayDecoding var tags: [String] // 解码时自动过滤nil值 @LossyDictionaryDecoding var properties: [String: String] // 解码时自动过滤nil值 @LossySetDecoding var categories: Set<String> // 解码时自动过滤nil值 }高级功能
默认值与回退策略
当数据缺失或无效时,可以使用回退策略提供默认值:
struct Product: Codable { @FallbackDecoding<EmptyString> var name: String // 缺失时使用空字符串 @FallbackCoding<EmptyArray> var tags: [String]? // 缺失或nil时使用空数组 @FallbackEncoding<EmptyInt> var stock: Int? // 为nil时编码为0 // 自定义回退值 @FallbackDecoding<DefaultPriceProvider> var price: Double } struct DefaultPriceProvider: FallbackValueProvider { static var defaultValue: Double { 9.99 } }忽略编码/解码
使用@OmitCoding可以排除不需要序列化的属性:
struct User: Codable { let id: String let name: String @OmitCoding var temporaryData: String? // 不会被编码或解码 }只编码或只解码
某些场景下可能只需要编码或解码功能:
struct ReadOnlyData: Decodable { @SecondsSince1970DateDecoding var createdAt: Date // 只解码 } struct WriteOnlyData: Encodable { @SecondsSince1970DateEncoding var updatedAt: Date // 只编码 }属性可变性控制
使用@Immutable可以创建解码后不可修改的属性:
struct User: Codable { @Immutable @SecondsSince1970DateCoding var createdAt: Date // 解码后不可修改 @SecondsSince1970DateCoding var updatedAt: Date // 可修改 }自定义序列化逻辑
CodableWrappers的强大之处在于其可扩展性。你可以通过实现StaticCoder协议创建完全自定义的序列化逻辑。
创建自定义编码器
下面是一个将日期编码为纳秒时间戳的示例:
struct NanosecondsSince1970Coder: StaticCoder { static func decode(from decoder: Decoder) throws -> Date { let nanoSeconds = try Double(from: decoder) let seconds = nanoSeconds * 0.000000001 return Date(secondsSince1970: seconds) } static func encode(value: Date, to encoder: Encoder) throws { let nanoSeconds = value.secondsSince1970 / 0.000000001 try nanoSeconds.encode(to: encoder) } } // 使用自定义编码器 typealias NanosecondsSince1970Coding = CodingUses<NanosecondsSince1970Coder> struct Event: Codable { @NanosecondsSince1970Coding var preciseTime: Date }总结
CodableWrappers通过属性包装器的方式,为Swift Codable提供了强大而灵活的扩展,极大简化了复杂序列化逻辑的实现。无论是处理各种日期格式、转换命名风格,还是实现自定义序列化规则,它都能让代码更加简洁、可读和可维护。
如果你正在寻找一种方式来简化Swift项目中的数据序列化工作,CodableWrappers绝对是一个值得尝试的终极方案!更多详细示例和高级用法,请参考项目中的CustomExamples.md和官方文档。
开始使用CodableWrappers,让Swift序列化工作变得前所未有的简单! 🚀
【免费下载链接】CodableWrappersA Collection of PropertyWrappers to make custom Serialization of Swift Codable Types easy项目地址: https://gitcode.com/gh_mirrors/co/CodableWrappers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考