How do you parse JSON with Swift 4? Maybe you’ve done it with Swift 3 before, and if you have, you’ll be pleased to know that it’s so much better in Swift 4. And guess what? Nobody even calls it parsing any more — it’s decoding now. Apple has some new classes and protocols we can use: JSONDecoder
and Decodable
for decoding from JSON data to a model object, and JSONEncoder
and Encodable
for encoding from a model object to JSON data.
Let’s look at how to parse — or decode — the JSON feed from roadfiresoftware.com, which you can see for yourself here. It looks something like this, though I’ve removed a bunch of JSON properties for the sake of simplicity:
{
"home_page_url": "http://roadfiresoftware.com",
"title": "Roadfire Software",
"items": [
{
"id": "http://roadfiresoftware.com/2018/01/whats-the-best-way-to-learn-ios-development-with-swift/",
"url": "http://roadfiresoftware.com/2018/01/whats-the-best-way-to-learn-ios-development-with-swift/",
"title": "What’s the best way to learn iOS development with Swift?"
},
{
"id": "http://roadfiresoftware.com/2018/01/how-to-write-a-singleton-in-swift/",
"url": "http://roadfiresoftware.com/2018/01/how-to-write-a-singleton-in-swift/",
"title": "How to write a singleton in Swift"
}
]
}
We can decode this in just two steps: first, we’ll define our model objects, and then we’ll use JSONDecoder
to transform JSON data into our models.
1. Defining model objects that conform to Decodable
If we wanted to take all that JSON and turn it into objects, we might have Blog
and Article
models to represent it. Here are those models:
struct Blog: Decodable {
let title: String
let homepageURL: URL
let articles: [Article]
enum CodingKeys : String, CodingKey {
case title
case homepageURL = "home_page_url"
case articles = "items"
}
}
struct Article: Decodable {
let id: String
let url: URL
let title: String
}
Notice that both models conform to the Decodable
protocol. This allows us to decode them later with JSONDecoder
, a new Foundation class in Swift 4. Additionally, they’re both structs, which I generally prefer for model objects — but you can define classes instead if you like.
The other thing you probably noticed is that Blog
has a strange new enum called CodingKeys
with String
as the raw type, and it conforms to the CodingKey
protocol. This lets us map property names in our model to JSON keys when the names and keys aren’t the same. For us, this means that we can have a homepageURL
property on our Blog
that maps to the home_page_url
key in JSON. And similarly for articles
, we’re mapping to items
in JSON.
Our Article
model doesn’t need CodingKeys
since all of the properties we want to map have names that match. The JSON id
maps to the Article
id
, and the same goes for url
and title
.
2. Decoding JSON into model objects with JSONDecoder
And now that our models specify the mappings from JSON to Swift (and vice-versa), we just need to ask JSONDecoder
to decode the data and transform it into a Blog
.
guard let data = data else {
print("Error: No data to decode")
return
}
guard let blog = try? JSONDecoder().decode(Blog.self, from: data) else {
print("Error: Couldn't decode data into Blog")
return
}
print("blog title: \(blog.title)")
print("blog home: \(blog.homepageURL)")
print("articles:")
for article in blog.articles {
print("- \(article.title)")
}
We start by verifying that we actually have data to decode. Then we use JSONDecoder
‘s decode(_:from:)
to transform that data into a Blog
. And this is it — all we have to do is tell it that we want to turn this data into this type and all the magic happens under the hood. It prints the blog title, home, and a list of recent articles.
Conclusion
I hope this helps you to start working with JSON in Swift 4 — and furthermore, I hope you see that it’s relatively simple to do using the JSONDecoder
class from the Foundation framework. So many people seem to want grab a third-party library to parse JSON, but for most use cases, I see very little benefit to using one to do something so simple — especially now that Swift 4 makes it so easy. You don’t need a third-party library for everything.
See all of this working live and tweak it to use your JSON endpoint by grabbing the playground for this article. Just drop your name and email in the boxes below and I’ll send you the playground right away.