Topics

#86: Decodable 🔩

Topics

We continue our look at frameworks that map JSON into model types today with Decodable by Johannes Lund. Decodable is another fantastic solution for this task. It takes advantage of Swift 2's new error handling functionality, and unlike ObjectMapper (covered in Bite #84), the properties on your models don't need to be optionals. Let's take a closer look:

To get things wired up we just need to implement the Decodable protocol on our model types, like so:

struct Spaceship {
  var captain: User
  var topSpeed: Double
}

extension Spaceship: Decodable {
  static func decode(j: AnyObject) throws -> Spaceship {
    return try Spaceship(
      captain: j => "captain",
      topSpeed: j => "topSpeed"
    )
  }
}

Then we can convert from JSON to one of these structs like this:

do {
  let ship = try Spaceship.decode(json)
} catch let error { print(error) }

We can decode JSON arrays like this:

do {
  let ships = try [Spaceship].decode(array)
} catch let error { print(error) }

Decodable also handles nested types and is quite flexible. For example, we aren't even forced to use Decodable on every type. Here we bypass Decodable a bit and instantiate a value for our rank property manually:

extension User: Decodable {
  static func decode(j: AnyObject) throws -> User {
    return try User(name: j => "name", rank: Rank(name: j => "rank"))
  }
}

Some other noteworth Decodable features are its wonderful printable errors, and how easy it is to add custom decode functions for things like parsing custom date formats, etc.

More info about Decodable can be found at git.io/decodable