0Pricing
Swift Academy · Lesson

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 = .convertFromSnakeCase maps snake_case to camelCase; .convertToSnakeCase encodes the other way.
  • dateDecodingStrategy = .iso8601 parses ISO timestamps; .secondsSince1970 and .formatted(_:) cover other formats.
  • Strategies apply to every nested type uniformly.
  • Use strategies for uniform APIs, CodingKeys for 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

  1. CodingKeys for Renaming
  2. Key and Date Decoding Strategies
  3. Manual encode(to:) and init(from:)
  4. Decoding Heterogeneous JSON
← Back to Swift Academy