0Pricing
Swift Academy · Lesson

CodingKeys for Renaming

Map differing JSON and property names.

CodingKeys for Renaming is a free Swift Academy lesson on CoddyKit — lesson 1 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.

Why Rename Keys?

JSON APIs often use names that differ from your Swift property names — first_name vs firstName. A CodingKeys enum bridges the two without changing your model's API.

import Foundation

struct User: Codable {
    var firstName: String
    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
    }
}

print("CodingKeys maps firstName to first_name")

Anatomy of CodingKeys

CodingKeys is a nested enum that conforms to String, CodingKey. Each case matches a property name; its raw value is the JSON key to use.

import Foundation

struct Product: Codable {
    var productName: String
    var unitPrice: Double
    enum CodingKeys: String, CodingKey {
        case productName = "product_name"
        case unitPrice = "unit_price"
    }
}

print(Product.CodingKeys.productName.rawValue)

Decoding with Renamed Keys

When decoding, the decoder looks up each property using the raw value in CodingKeys, so snake_case JSON populates camelCase properties.

import Foundation

struct User: Codable {
    var firstName: String
    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
    }
}

let json = "{\"first_name\":\"Ada\"}"
let u = try JSONDecoder().decode(User.self, from: json.data(using: .utf8)!)
print(u.firstName)

Encoding with Renamed Keys

Encoding uses the same mapping in reverse: the output JSON contains the raw-value keys, not the Swift property names.

import Foundation

struct User: Codable {
    var firstName: String
    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
    }
}

let data = try JSONEncoder().encode(User(firstName: "Ada"))
print(String(data: data, encoding: .utf8)!)

Listing All Properties

Once you add a CodingKeys enum, it must include a case for every property you want encoded or decoded. Cases you keep with no raw value use the property name as-is.

import Foundation

struct Item: Codable {
    var id: Int
    var displayName: String
    enum CodingKeys: String, CodingKey {
        case id
        case displayName = "display_name"
    }
}

let data = try JSONEncoder().encode(Item(id: 1, displayName: "Pen"))
print(String(data: data, encoding: .utf8)!)

Omitting a Property

Leaving a property out of CodingKeys excludes it from encoding and decoding. Such a property must have a default value so the synthesized init can still build the type.

import Foundation

struct User: Codable {
    var name: String
    var cachedToken: String = "none"
    enum CodingKeys: String, CodingKey {
        case name
    }
}

let u = try JSONDecoder().decode(User.self, from: "{\"name\":\"Ada\"}".data(using: .utf8)!)
print(u.name, u.cachedToken)

Renaming Multiple Keys

Map as many keys as you need. Each case lines up a Swift property with the exact JSON key the server expects.

import Foundation

struct Account: Codable {
    var userId: Int
    var isVerified: Bool
    enum CodingKeys: String, CodingKey {
        case userId = "user_id"
        case isVerified = "is_verified"
    }
}

let json = "{\"user_id\":7,\"is_verified\":true}"
let a = try JSONDecoder().decode(Account.self, from: json.data(using: .utf8)!)
print(a.userId, a.isVerified)

Mapping to Friendlier Names

CodingKeys is not just for snake_case. Use it to rename cryptic API keys into clear Swift property names.

import Foundation

struct Reading: Codable {
    var temperature: Double
    enum CodingKeys: String, CodingKey {
        case temperature = "t"
    }
}

let json = "{\"t\":19.5}"
let r = try JSONDecoder().decode(Reading.self, from: json.data(using: .utf8)!)
print(r.temperature)

CodingKeys with Nested Types

Each Codable type has its own CodingKeys. A nested struct can rename its own keys independently of the parent.

import Foundation

struct Meta: Codable {
    var createdAt: String
    enum CodingKeys: String, CodingKey { case createdAt = "created_at" }
}
struct Doc: Codable { var title: String; var meta: Meta }

let json = "{\"title\":\"A\",\"meta\":{\"created_at\":\"today\"}}"
let d = try JSONDecoder().decode(Doc.self, from: json.data(using: .utf8)!)
print(d.meta.createdAt)

Round-Trip with Renamed Keys

The same CodingKeys drive both directions, so a value encodes to snake_case and decodes back to the same Swift value.

import Foundation

struct User: Codable {
    var firstName: String
    var lastName: String
    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
    }
}

let u = User(firstName: "Ada", lastName: "Lovelace")
let data = try JSONEncoder().encode(u)
let back = try JSONDecoder().decode(User.self, from: data)
print(back.firstName, back.lastName)

When to Reach for CodingKeys

Use an explicit CodingKeys enum when individual keys need precise control, when only some keys differ, or when you must omit a property. For a uniform snake_case API, a decoding strategy may be simpler.

import Foundation

struct Event: Codable {
    var eventName: String
    var startTime: String
    enum CodingKeys: String, CodingKey {
        case eventName = "name"
        case startTime = "start_time"
    }
}

let json = "{\"name\":\"Launch\",\"start_time\":\"10:00\"}"
let e = try JSONDecoder().decode(Event.self, from: json.data(using: .utf8)!)
print(e.eventName, e.startTime)

Quick Check: CodingKeys

Test your understanding of key renaming.

Recap: CodingKeys for Renaming

You learned precise key control:

  • Declare enum CodingKeys: String, CodingKey nested in the type.
  • Each case's raw value is the JSON key; cases drive both encoding and decoding.
  • List every property you want coded; omitting one excludes it (it needs a default).
  • Nested types have their own independent CodingKeys.

Frequently asked questions

Is the “CodingKeys for Renaming” lesson free?

Yes — the full text of “CodingKeys for Renaming” 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 “CodingKeys for Renaming”?

Map differing JSON and property names. 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 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “CodingKeys for Renaming” 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