Decode JSON with Swift using Codable

Why use Codable?

Dealing with JSON in Swift isn’t as easy as it could be, hence why people use libraries such as SwiftyJSON.

The Swift Standard Library now comes with a Type Alias called Codable, which can be conformed to in order to signify the ability to convert to/from external representations, such as JSON.

A simple example

Create a struct which conforms to Codable. This is what your JSON will decode to:

struct Post: Codable {
    let id: Int
    let title: String
    let createdAt: Date
}

Create some JSON (this data would usually come from an API call):

let postJSON = "{ \"id\": 0, \"title\": \"Title of the Post\", \"createdAt\": 549885398.72194 }"
let postJSONData = postJSON.data(using: .utf8)

Create a JSONDecoder and decode the JSON into your struct (force unwrapped for brevity):

let decoder = JSONDecoder()
let post = try! decoder.decode(Post.self, from: postJSONData!)

You’ll have a Post object:
Screen Shot 2018-06-05 at 17.22.44

Decoding arrays and nested objects

If your JSON is an array of posts, just call:

let posts = try! decoder.decode([Post].self, from: postsJSONData!)

If you want to decode nested objects, simply declare those objects as Codable structs, and include them in your struct:

struct Post: Codable {
    let id: Int
    let title: String
    let createdAt: Date
    //This is also a Codable struct. Declaring it as optional means it doesn't have to be present in the JSON.
    let comment: Comment?
}

Dealing with different date formats

Use the dateDecodingStrategy property of JSONDecoder:

let commentJSON = "{ \"comment_text\": \"This is the text\", \"seen_at\": \"2018-06-05T10:19:04+00:00\"}"
let commentJSONData = commentJSON.data(using: .utf8)
decoder.dateDecodingStrategy = .iso8601
let comment = try decoder.decode(Comment.self, from: commentJSONData!)

Download the playground here.