键与日期解码策略
使用 snake_case 和日期解码策略。
键与日期解码策略 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
解码策略概览
您不必为每种类型都编写一个 CodingKeys 枚举,也可以在解码器上设置全局策略。策略会统一转换键,并在所有解码类型中以一致的方式解析日期。
import Foundation
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
print("Strategy configured")convertFromSnakeCase
设置 keyDecodingStrategy = .convertFromSnakeCase 后,会自动将类似 first_name 的键映射到 camelCase 属性 firstName,无需使用 CodingKeys。
import Foundation
struct User: Codable {
var firstName: String
var lastName: String
}
let json = "{\"first_name\":\"Ada\",\"last_name\":\"Lovelace\"}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let u = try decoder.decode(User.self, from: json.data(using: .utf8)!)
print(u.firstName, u.lastName)编码为蛇形命名法
编码器也有对应的选项:keyEncodingStrategy = .convertToSnakeCase 会将 camelCase 属性写出为 snake_case JSON 键。
import Foundation
struct User: Codable {
var firstName: String
}
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let data = try encoder.encode(User(firstName: "Ada"))
print(String(data: data, encoding: .utf8)!)策略应用于所有键
键策略会统一应用于每种嵌套类型的每个属性。当整个 API 都一致使用 snake_case 时,这种方式非常理想。
import Foundation
struct Meta: Codable { var createdAt: String }
struct Doc: Codable { var docTitle: String; var docMeta: Meta }
let json = "{\"doc_title\":\"A\",\"doc_meta\":{\"created_at\":\"now\"}}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let d = try decoder.decode(Doc.self, from: json.data(using: .utf8)!)
print(d.docTitle, d.docMeta.createdAt)日期问题
JSON 没有日期类型。Date 值会被编码为数字或字符串,解码器需要知道具体格式。dateDecodingStrategy 会告诉它应如何解析。
import Foundation
struct Event: Codable {
var name: String
var date: Date
}
print("Date needs a strategy to parse")iso8601 日期解码
dateDecodingStrategy = .iso8601 会将类似 2020-01-01T00:00:00Z 的标准 ISO-8601 时间戳解析为 Date 值。
import Foundation
struct Event: Codable {
var name: String
var date: Date
}
let json = "{\"name\":\"Launch\",\"date\":\"2020-01-01T00:00:00Z\"}"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let e = try decoder.decode(Event.self, from: json.data(using: .utf8)!)
print(e.date.timeIntervalSince1970)iso8601 日期编码
编码器对应的选项是 dateEncodingStrategy = .iso8601,它会将 Date 值写成 ISO-8601 字符串。
import Foundation
struct Event: Codable {
var name: String
var date: Date
}
let e = Event(name: "Launch", date: Date(timeIntervalSince1970: 1577836800))
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(e)
print(String(data: data, encoding: .utf8)!)secondsSince1970 策略
当 API 以数字发送 Unix 时间戳时,请使用 .secondsSince1970 将其解释为自纪元以来经过的秒数。
import Foundation
struct Event: Codable {
var date: Date
}
let json = "{\"date\":1577836800}"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let e = try decoder.decode(Event.self, from: json.data(using: .utf8)!)
print(e.date.timeIntervalSince1970)自定义日期格式
对于非标准格式,请通过 .formatted(_:) 提供一个 DateFormatter。这样可以处理类似 2020-01-01 这种不包含时间部分的日期。
import Foundation
struct Event: Codable { var date: Date }
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
fmt.timeZone = TimeZone(identifier: "UTC")
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(fmt)
let e = try decoder.decode(Event.self, from: "{\"date\":\"2020-01-01\"}".data(using: .utf8)!)
print(e.date.timeIntervalSince1970)组合使用策略
您可以在同一个解码器上同时设置键策略和日期策略,从而处理使用 snake_case 且采用 ISO-8601 格式的 API,无需为每种类型编写额外样板代码。
import Foundation
struct LogEntry: Codable {
var eventName: String
var occurredAt: Date
}
let json = "{\"event_name\":\"login\",\"occurred_at\":\"2020-01-01T00:00:00Z\"}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
let entry = try decoder.decode(LogEntry.self, from: json.data(using: .utf8)!)
print(entry.eventName, entry.occurredAt.timeIntervalSince1970)策略与 CodingKeys
对于格式统一的 API,全局策略更加简洁。当只有少数键不同或名称不规则时,显式的 CodingKeys 枚举可以对每个键进行精确控制。两种方式甚至可以结合使用。
import Foundation
struct Item: Codable {
var itemName: String
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let i = try decoder.decode(Item.self, from: "{\"item_name\":\"Pen\"}".data(using: .utf8)!)
print(i.itemName)快速检查:策略
检验您对解码策略的理解。
回顾:键策略与日期策略
您学习了如何配置全局编码器:
keyDecodingStrategy = .convertFromSnakeCase会将 snake_case 映射为 camelCase;.convertToSnakeCase则以相反方向进行编码。dateDecodingStrategy = .iso8601会解析 ISO 时间戳;.secondsSince1970和.formatted(_:)可处理其他格式。- 策略会统一应用于每种嵌套类型。
- 对于格式统一的 API,请使用策略;对于不规则的 API,请使用
CodingKeys。
常见问题解答
「键与日期解码策略」课时是免费的吗?
是的 — 「键与日期解码策略」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「键与日期解码策略」这节课中我会学到什么?
使用 snake_case 和日期解码策略。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「键与日期解码策略」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。