Encoding and Decoding in Swift
In this tutorial, you’ll learn all about encoding and decoding in Swift, exploring the basics and advanced topics like custom dates and custom encoding. By Cosmin Pupăză.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Encoding and Decoding in Swift
25 mins
- Getting Started
- Encoding and Decoding Nested Types
- Switching Between Snake Case and Camel Case Formats
- Working With Custom JSON Keys
- Working With Flat JSON Hierarchies
- Working With Deep JSON Hierarchies
- Encoding and Decoding Dates
- Encoding and Decoding Subclasses
- Handling Arrays With Mixed Types
- Working With Arrays
- Working With Arrays Within Objects
- Where to Go From Here?
A common task for iOS apps is to save data and send it over the network. But before you can do that, you need to convert the data to a suitable format through a process called encoding or serialization.

You’ll also need to convert the saved data sent over the network to a suitable format before using it in your app. This reverse process is called decoding or deserialization.

In this tutorial, you’ll learn all you need to know about encoding and decoding in Swift by managing your very own toy store. You’ll explore the following topics along the way:
- Switching between snake case and camel case formats.
- Defining custom coding keys.
- Working with keyed, unkeyed and nested containers.
- Handling nested types, dates, subclasses and polymorphic types.
There’s quite a lot to cover, so it’s time to get started! :]
Getting Started
Download the starter playground using the Download Materials link at the top or bottom of the tutorial.
Make sure the Project navigator is visible in Xcode by going to View ▸ Navigators ▸ Show Project Navigator. Open Nested types.
Add Codable conformance to Toy and Employee:
struct Toy: Codable {
...
}
struct Employee: Codable {
...
}
Codable isn’t a protocol on it’s own, but an alias for two other protocols: Encodable and Decodable. As you might guess, those two protocols declare that types can be encoded to and decoded from a different format.
You don’t need to do anything more, because all the stored properties of both Toy and Employee are codable. Many basic types in the Swift Standard Library and Foundation types (for example, String and URL) are codable by default.
Add a JSONEncoder and a JSONDecoder to handle JSON encoding and decoding of toys and employees:
let encoder = JSONEncoder()
let decoder = JSONDecoder()
That’s all you need to work with JSON. Time for your first encoding and decoding challenge!
Encoding and Decoding Nested Types
Employee contains a Toy property — it’s a nested type. The JSON structure of your encoded employee matches the Employee struct:
{
"name" : "John Appleseed",
"id" : 7,
"favoriteToy" : {
"name" : "Teddy Bear"
}
}
public struct Employee: Codable {
var name: String
var id: Int
var favoriteToy: Toy
}
The JSON nests name inside favoriteToy and all the JSON keys are the same as the Employee and Toy stored properties, so you can easily understand the JSON structure based on your data types hierarchy. If your property names match your JSON field names, and your properties are all Codable, then you can convert to or from JSON very easily. You’ll try that now.
The Gifts department gives employees their favorite toys as birthday gifts. Add the following code to send your employee’s data to the Gifts department:
// 1
let data = try encoder.encode(employee)
// 2
let string = String(data: data, encoding: .utf8)!
Here’s how this code works:
- Encode
employeeto JSON withencode(_:)(I told you it was easy!). - Create a string from the encoded
datato visualize it.
print values to the debugger console or click the Show Result button in the results sidebar.The encoding process generates valid data, so the Gifts department can recreate the employee:
let sameEmployee = try decoder.decode(Employee.self, from: data)
Here, you’ve used decode(_:from:) to decode data back to Employee… and you’ve made your employee very happy. Press the blue play button to run the Playground and see the results.
Time for your next challenge!
Switching Between Snake Case and Camel Case Formats
The Gifts department API has switched from camel case (which looksLikeThis) to snake case (which looks_like_this_instead) to format keys for its JSON.
But all of the stored properties of Employee and Toy use camel case only! Fortunately, Foundation has you covered.
Open Snake case vs camel case and add the following code just after the encoder and decoder are created, before they get used:
encoder.keyEncodingStrategy = .convertToSnakeCase
decoder.keyDecodingStrategy = .convertFromSnakeCase
Here, you set keyEncodingStrategy to .convertToSnakeCase to encode employee. You also set keyDecodingStrategy to .convertFromSnakeCase to decode snakeData.
Run the playground and inspect snakeString. The encoded employee looks like this in this case (pun intended):
{
"name" : "John Appleseed",
"id" : 7,
"favorite_toy" : {
"name" : "Teddy Bear"
}
}
The formatting in JSON is now favorite_toy and you’ve transformed it back to favoriteToy in the Employee struct. You’ve saved the (employee’s birth)day again! :]
Working With Custom JSON Keys
The Gifts department has changed its API again to use different JSON keys than your Employee and Toy stored properties use:
{
"name" : "John Appleseed",
"id" : 7,
"gift" : {
"name" : "Teddy Bear"
}
}
Now, the API replaces favoriteToy with gift.
This means that the field names in the JSON will no longer match up with the property names in your type. You can define custom coding keys to supply coding names for your properties. You do this by adding a special enum to your type. Open Custom coding keys and add this code inside the Employee type:
enum CodingKeys: String, CodingKey {
case name, id, favoriteToy = "gift"
}
CodingKeys is the special enum mentioned above. It conforms to CodingKey and has String raw values. Here’s where you map favoriteToy to gift.
If this enum exists, only the cases present here will be used for encoding and decoding, so even if your property doesn’t require mapping, it has to be included in the enum, as name and id are here.
Run the playground and look at the encoded string value — you’ll see the new field name in use. The JSON doesn’t depend on your stored properties anymore, thanks to custom coding keys.
Time for your next challenge!
