Key and Date Decoding Strategies
Use snake_case and date strategies.
Key and Date Decoding Strategies is a free Swift Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Decoding Strategies Overview
Instead of writing a CodingKeys enum for every type, you can set a global strategy on the decoder. Strategies transform keys and parse dates uniformly across all decoded types.
import Foundation
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
print("Strategy configured")convertFromSnakeCase
Setting keyDecodingStrategy = .convertFromSnakeCase automatically maps keys like first_name to the camelCase property firstName — no CodingKeys needed.
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)Encoding to Snake Case
The encoder has the mirror option: keyEncodingStrategy = .convertToSnakeCase writes camelCase properties out as snake_case JSON keys.
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)!)Strategy Applies to All Keys
A key strategy applies uniformly to every property of every nested type. This is ideal when an entire API is consistently 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)The Date Problem
JSON has no date type. Date values are encoded as numbers or strings, and the decoder needs to know the format. A dateDecodingStrategy tells it how.
import Foundation
struct Event: Codable {
var name: String
var date: Date
}
print("Date needs a strategy to parse")iso8601 Date Decoding
dateDecodingStrategy = .iso8601 parses standard ISO-8601 timestamps like 2020-01-01T00:00:00Z into Date values.
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 Date Encoding
The encoder counterpart is dateEncodingStrategy = .iso8601, which writes Date values as ISO-8601 strings.
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 Strategy
When an API sends Unix timestamps as numbers, use .secondsSince1970 to interpret them as seconds since the epoch.
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)Custom Date Formats
For non-standard formats, supply a DateFormatter via .formatted(_:). This handles dates like 2020-01-01 with no time component.
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)Combining Strategies
Key and date strategies can be set together on the same decoder, letting you handle a snake_case, ISO-8601 API with zero per-type boilerplate.
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)Strategy vs CodingKeys
A global strategy is concise for uniform APIs. When only a few keys differ, or names are irregular, an explicit CodingKeys enum gives precise per-key control. They can even be combined.
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)Quick Check: Strategies
Test your understanding of decoding strategies.
Recap: Key and Date Strategies
You learned global coder configuration:
keyDecodingStrategy = .convertFromSnakeCasemaps snake_case to camelCase;.convertToSnakeCaseencodes the other way.dateDecodingStrategy = .iso8601parses ISO timestamps;.secondsSince1970and.formatted(_:)cover other formats.- Strategies apply to every nested type uniformly.
- Use strategies for uniform APIs,
CodingKeysfor irregular ones.
Frequently asked questions
Is the “Key and Date Decoding Strategies” lesson free?
Yes — the full text of “Key and Date Decoding Strategies” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Key and Date Decoding Strategies”?
Use snake_case and date strategies. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Key and Date Decoding Strategies” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- CodingKeys for Renaming
- Key and Date Decoding Strategies
- Manual encode(to:) and init(from:)
- Decoding Heterogeneous JSON