How to change JSON keys by using Swift's CodingKey protocol
Learn how to map JSON data to a different structure in Swift.
27 Mar 2023 · 3 min read
Swift's Codable protocol makes it easy to convert JSON data to native Swift types and the other way around. In the article on how to use the CodingKey protocol, we explored how to use custom names for Swift properties when decoding JSON data.
In some cases though, we might need an even more customized solution, for example to map the JSON data to a different structure.
Let's look at how to do that.

Let's say we get the following JSON data:
{"username" : "tanaschita","validated": true,"address": {"postalCode": "04275","city": "Leipzig",...}}
Our application is only interested in the user's city property, that's why we'd like to add it directly to our User struct without defining an extra Address type as follows:
struct User: Codable {let username: Stringlet isValidated: Boollet city: String}
To be able to map the data the way we want, we can provide a custom implementation of Encodable and Decodable to define our own encoding and decoding logic:
struct User: Codable {let username: Stringlet isValidated: Boollet city: Stringenum CodingKeys: String, CodingKey {case usernamecase isValidated = "validated"case address}enum AddressCodingKeys: String, CodingKey {case city}init(from decoder: Decoder) throws {let values = try decoder.container(keyedBy: CodingKeys.self)username = try values.decode(String.self, forKey: .username)isValidated = try values.decode(Bool.self, forKey: .isValidated)let address = try values.nestedContainer(keyedBy: AddressCodingKeys.self, forKey: .address)city = try address.decode(String.self, forKey: .city)}}
In the same way, we can add our own encoding logic:
func encode(to encoder: Encoder) throws {var container = encoder.container(keyedBy: CodingKeys.self)try container.encode(username, forKey: .username)try container.encode(isValidated, forKey: .isValidated)var address = container.nestedContainer(keyedBy: AddressCodingKeys.self, forKey: .address)try address.encode(city, forKey: .city)}
This possibility gives us a way to be fully independent of the JSON structure so we can create an entirely customized representation of that data in our iOS apps.

Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips