Chapters

Hide chapters

Expert Swift

Second Edition · iOS 18.5 · Swift 6.1 · Xcode 16.3

8. Codable
Written by Marin Bencevic

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

When developing your app, you’ll often deal with a myriad of data models and various external pieces of data that you’ll want to represent as data models in your app.

To solve this problem, you’ll often use a technique called serialization, where you create an external representation of your data models in one of many consumable formats supported by multiple platforms. The most popular of the bunch by far is JSON (Javascript Object Notation).

The need for data serialization in Apple’s platforms is so common that they solved it all the way back in Xcode 3.0, with the introduction of NSCoding, which lets you describe how to encode and decode your data.

Unfortunately NSCoding, while an incredible abstraction at the time, suffers from many issues and a lack of modern touch that fits the Swift world — such as automatically synthesized encoding and decoding, support for value types and more. Enter Codable.

What is Codable?

Codable is a type alias combining two protocols: Encodable and Decodable. These let you define how objects are encoded and decoded to and from an external data representation, such as JSON.

The great thing about Codable is that it’s mostly agnostic toward the format it encodes to and decodes from. It uses an additional set of abstractions called Encoder and Decoder to achieve this separation.

These abstractions own the specific intimate knowledge of how to encode and decode in and out of their specific data formats. For example, a JSONEncoder would know how to encode a given data model into a JSON response, while a PropertyListDecoder would know exactly how to take a plist file and decode it into a given data model.

This abstraction means that your objects only have to conform to Codable or either of its parts once, and can be encoded to and decoded from many different formats using various encoders and decoders.

JSON data Plist data Custom data JSONEncoder PropertyListEncoder PropertyListDecoder Custom encoders Custom decoders PERSON id: UUID name: String address: struct favorite: enum Conforms to Codable JSONDecoder

What you’ll learn, and what you won’t

Because this is an advanced book, you’ll quickly browse through the basic Codable knowledge, mostly focusing on the advanced materials down the dark corners of Codable.

Brushing up on the basics

When decoding or encoding a data structure, you often get to use Codable with literally no boilerplate.

API #1: Ray’s Books

Getting started

Open the starter playground found in projects/starter and look at the Navigation pane on the left:

Basic decoding

Open the page 1. Ray’s Books. The easiest path to decoding the response is to start with properties you get “for free” from Swift.

Key decoding strategies

Add the following property to Book:

Data decoding strategies

Four keys decoded, and one final key to go — image_blob. This key contains a Base 64 representation of image data, so you can easily transport small thumbnails along with your JSON response.

Understanding coding keys

A CodingKey is a simple protocol describing how a key of a specific property is represented. It has two properties: stringValue, for string keys such as the ones you’ve just seen, and an optional intValue, for cases when the key is part of an array:

Custom key decoding strategies

As mentioned earlier, there’s one final challenge for you to tackle in this section: creating your own decoding strategy.

API #2: Magic: The Gathering

Magic: The Gathering was the first modern trading card game and it remains wildly popular among fans of the genre. Various cards have different powers, rarity, types and much more, and span over 20 different card sets.

Decoding the card’s mana

Each card has something called a Mana Cost — the cost needed to put the card into play. The first card in the JSON response has a manaCost of {3}{W}{W}, which means three of any color (colorless), and two white mana cards.

Understanding containers

If you’ve ever written a custom Decodable or Encodable initializer, it’s quite likely you’ve worked with a decoding or encoding container, accordingly:

Custom Decodable conformance for Card.Mana

With the Card.Mana.Color initializer ready to roll, it’s time to start taking care of Card.Mana itself. Start by conforming Card.Mana to Decodable by replacing:

Implementing the Mana object

Add the following property to Card:

Decoding the card’s rarity

The card rarity is mostly simple, comprising a fixed set of strings: Common, Mythic Rare, Basic Land etc.

Decoding the card’s set and attributes

Cards are released as part of sets, which contain a name and a symbol. Each creature card also features power and toughness, which determine how strong the creature’s attack is and how much damage it can withstand.

Decoding the card’s rulings

Each card possesses an array of rulings containing dates and textual rulings about the card throughout its history.

API #3: Alpha Vantage

You’ll tackle the most challenging task last.

Exploring the starter page

In the navigation pane, open the page 3. Alpha Vantage. You’ll notice there’s already some starter code waiting there for you:

Analyzing the response

If you look in av_1min.json again, you’ll notice the structure looks similar to the following:

Decoding the nested metadata

Because the structure of Stock doesn’t directly correlate with the JSON response, you’ll need a custom decoding initializer. Add the following initializer, along with coding keys for the top level and the Meta Data level:

Using nested containers

To start, add the following line inside your initializer:

Decoding custom date formats

Start by adding the following property to Stock:

Decoding the individual stock updates

As before, it’s best to try and define what you want the data structure to eventually look like in Swift.

Decoding updates into Stock

Now, to deal with Stock itself. Start by adding the following property to it:

Decoding your new keys

Finalize your initializer with this piece of code:

Testing your Stock decoding

To test all of the incredible work you’ve just done, below Stock, replace print(stock) with the following:

Passing information with user-info keys

The question you need to answer is: “How can I pass information down from the external world into my decodable initializer?” That answer is simpler than you’d come to expect.

Encoding

You’ve spent the majority of this chapter working on decoding because that’s where most of the challenges arise in daily work. But you’re definitely not going to leave this chapter without at least touching a bit on the other side of the equation: encoding.

Exploring the starter page

Open the 4. Encodable playground page in the Navigation pane and you’ll notice there’s already a considerable amount of boilerplate written for you:

Encoder customizations

Like JSONDecoder’s various customizable properties, JSONEncoder packs quite a punch. The first customization opportunity for you is output formatting. Add the following line immediately after creating your JSONEncoder:

Encoding strategies

Exactly like Decodable has decoding strategies, Encodable has encoding strategies: keyEncodingStrategy, dateEncodingStrategy and dataEncodingStrategy.

Customizing encoding with intermediate types

One thing you might have noticed is that two properties — accessKey and atmCode — contain rather sensitive information. It’s a good idea to encrypt this information before encoding the object to JSON.

Restructuring your output

To wrap up this chapter, you’ll learn about one final thing: How to manipulate the structure of the encoded JSON.

Encoding the customer’s information

Next, you’ll deal with the customer’s address and contact information. Can you guess how? Exactly like decoding, you can use nested containers to create nested structures in your encoding!

Key points

You covered a lot in this chapter. Here are some of the key takeaways:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now