DefaultCodable 使用教程
项目介绍
DefaultCodable 是一个基于 Swift 属性包装器实现的库,旨在提高代码的健壮性。它与 Codable 配合使用,可以在解析 JSON 数据时为某些可能为 null 或不存在的字段指定默认值,从而保证属性不为 nil。此外,当 JSON 中含有未声明的枚举时,通常会导致崩溃,但使用 @Default
属性包装器可以避免这种情况,例如设置 @Default FirstCase
则会默认使用第一个枚举值。
项目快速启动
安装
使用 Swift Package Manager 添加 DefaultCodable 作为依赖:
dependencies: [
.package(url: "https://github.com/gonzalezreal/DefaultCodable", from: "1.0.0")
]
示例代码
以下是一个简单的示例,展示了如何使用 DefaultCodable:
import DefaultCodable
// 定义一个模型
struct Model: Codable {
// 枚举需遵循 CaseIterable 协议
enum Category: String, Codable, CaseIterable {
case unknown, oneCase, twoCase
}
// 标记 title 默认值为空字符串
@Default<Empty> var title: String
// 标记 comments 默认值为空数组
@Default<EmptyArray> var comments: [Int]
// 标记 actions 默认值为空字典
@Default<EmptyDictionary> var actions: [String: Bool]
// 标记 flag 默认值为 true
@Default<True> var flag: Bool
// 标记 count 默认值为 0
@Default<Zero> var count: Int
// 标记 value 默认值为 1
@Default<One> var value: Double
// 标记 category1 默认值为第一个枚举
@Default<FirstCase> var category1: Category
// 标记 category2 默认值为最后一个枚举
@Default<LastCase> var category2: Category
}
// 解析 JSON
let jsonString = """
{
"title": "Hello",
"flag": false
}
"""
let data = jsonString.data(using: .utf8)!
let model = try! JSONDecoder().decode(Model.self, from: data)
print(model.title) // 输出: Hello
print(model.flag) // 输出: false
print(model.comments) // 输出: []
print(model.actions) // 输出: [:]
print(model.count) // 输出: 0
print(model.value) // 输出: 1.0
print(model.category1) // 输出: unknown
print(model.category2) // 输出: twoCase
应用案例和最佳实践
案例1:处理可选字段
在实际开发中,JSON 数据往往包含许多可选字段。使用 DefaultCodable 可以简化代码,避免大量的可选绑定操作。
struct User: Codable {
@Default<Empty> var name: String
@Default<Zero> var age: Int
@Default<EmptyArray> var hobbies: [String]
}
let userJson = """
{
"name": "Alice"
}
"""
let userData = userJson.data(using: .utf8)!
let user = try! JSONDecoder().decode(User.self, from: userData)
print(user.name) // 输出: Alice
print(user.age) // 输出: 0
print(user.hobbies) // 输出: []
案例2:处理枚举字段
当 JSON 数据中的枚举字段可能不存在或为 null 时,使用 DefaultCodable 可以确保枚举字段有一个默认值,避免程序崩溃。
enum Role: String, Codable, CaseIterable {
case user, admin
}
struct ChannelAccount: Codable {
var name: String
@Default<FirstCase> var role: Role
}
let channelJson = """
{
"name": "TechChannel"
}
"""
let channelData = channelJson.data(using: .utf8)!
let channel = try! JSONDecoder().decode(ChannelAccount.self, from: channelData)
print(channel.