TechnologyJun 04, 2018

Using Codable for JSON in Swift 4

Stephen Morrow

While Swift versions 1-3 were never able to interact with JSON data on their own, Swift 4 now provides a built-in tool for mapping to and from JSON data. And it’s actually incredibly easy to use.

At a high level, utilizing this feature simply requires inheriting the provided Codable class, and using the new JSONDecoder and JSONEncoder classes to marshall and unmarshall your data. Let’s take a quick look at the details of this new feature in Swift 4.

how it works

When your object inherits the Codable protocol, decoding and encoding of primitives comes out-of-the-box, as well as any other Foundation classes that also inherit Codable. This means that any of your own classes that inherit from Codable can also be used. In other words, you can encode and decode nested objects in your JSON with no additional configuration.

Here is a representative list of the most common data types that can be utilized:

  • String

  • Date

  • Data

  • URL

  • Array

  • Dictionary

  • Optional

an example

Now that we know all the types that can be used in our JSON data, let’s look at a quick example of how to declare, encode, and decode a basic object using these types. We start off by defining our data model. We will use a Car for this example. The following code snippet defines the Car data model and inherits Codable:

struct Car: Codable { let year: Int; let make: String; let image: Data; let colors: [String]; let homepage: URL; let manufactureDate: Date; let features: [String: Bool]?;}

Now that we have a data model, we can instantiate a JSONDecoder to decode our JSON data into an instance of our Car model. Since we have a Date and a Data property on our Car model, we need to tell the JSONDecoder how to decode those properties. Here is the code to do that:

let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 decoder.dataDecodingStrategy = .base64 let car = try decoder.decode(Car.self, from: json)

If we want to encode a Car object into JSON for sending along with an HTTP request, we can instead declare a JSONEncoder like so:

let encoder = JSONEncoder() let carJSON = try encoder.encode(car)String(data: carJSON, encoding: .utf8)

The previous example assumes all your JSON keys match your property names. In other words the manufactureDate property is represented in the JSON as “manufactureDate: 2012-02-12T00:00:00+00:00”. If the JSON property follows a different naming approach, you will need to define a CodingKeys enum on your Codable object. One thing to keep in mind, when you define the CodingKeys enum, you are overriding the default implementation, so you will need to include each of your object properties. You can see our Car object modified below to include custom CodingKeys for certain properties:

struct Car: Codable { let year: Int; let make: String; let image: Data; let colors: [String]; let homepage: URL; let manufactureDate: Date; let features: [String: Bool]?;   enum CodingKeys: String, CodingKey { case year; case make; case image; case colors; case homepage; case manufactureDate = "manufacture_date"; case features }

Considering no extra dependencies were pulled in, utilizing this new feature in Swift 4 streamlines the problem of dealing with JSON in your application. It is also more efficient in most cases than other libraries. To take a deeper dive, Apple’s documentation provides all the details for utilizing JSONEncoder and JSONDecoder.

If your company would like help implementing changes like the one mentioned in this article in your own iOS and Android application, Credera would be pleased to help you reach your goals. Contact us at