Decode JSON in Swift: A Full Micro-Project

Photo by Michael Dziedzic on Unsplash

Before we start

Difficulty: Beginner | Easy | Normal | Challenging

The video

The content of this article is covered in the following video!

  • This article skips over setting up a project, and gets rid of the storyboard and uses programmatic constraints as in this article
  • Later in the article a real example is used, that is Decoding JSON and the internal workings of this are kind of skipped over
  • If you are interested in testing, or a more in-depth explanation of JSON decoding you can look at this article

JSON: JavaScript Object Notation, a lightweight format for storing and transporting data Swift: An open source programming language for macOS, iOS, watchOS and tvOS

The expected result

This Project is going to take data from an endpoint (the specific endpoint is one of those hosted at reqres) and displays the result in a UITextView.

The end project looks something like the following:

So let us press on!

I’ve used [weak self] (the difference between weak and unowned is explained here )

Users Model The model is defined by the structure of the data from the endpoint. https://reqres.in/api/users?page=2 is

{"page":2,"per_page":6,"total":12,"total_pages":2,"data":[{"id":7,"email":"michael.lawson@reqres.in","first_name":"Michael","last_name":"Lawson","avatar":"https://reqres.in/img/faces/7-image.jpg"},{"id":8,"email":"lindsay.ferguson@reqres.in","first_name":"Lindsay","last_name":"Ferguson","avatar":"https://reqres.in/img/faces/8-image.jpg"},{"id":9,"email":"tobias.funke@reqres.in","first_name":"Tobias","last_name":"Funke","avatar":"https://reqres.in/img/faces/9-image.jpg"},{"id":10,"email":"byron.fields@reqres.in","first_name":"Byron","last_name":"Fields","avatar":"https://reqres.in/img/faces/10-image.jpg"},{"id":11,"email":"george.edwards@reqres.in","first_name":"George","last_name":"Edwards","avatar":"https://reqres.in/img/faces/11-image.jpg"},{"id":12,"email":"rachel.howell@reqres.in","first_name":"Rachel","last_name":"Howell","avatar":"https://reqres.in/img/faces/12-image.jpg"}],"support":{"url":"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions towards server costs are appreciated!"}}

can be placed into http://json.parser.online.fr which gives us a clear view of the structure of the JSON. In a usual working situation you might well be given a clear API with documentation, but this online parser can still be useful.

Now usually we might expect that the properties in our mode struct exactly mirror those of the endpoint. However in Swift we usually use Camel Case rather than snake case, and this is something will we cover when we decode the data - but in this case we can manually translate the Camel Case to Snake Case (for example per_page to perPage).

In order to decode the JSON using JSONDecoder() the model must conform to Codable, and this applies to the struct of the model (called User here) and any nested struct.

Although in the video I decided NOT to use nested struct instances for Users, UserData and Support since the nested struct instances are not referenced from outside the Struct I feel that we are actually better to nest them.

ViewController The view controller will instantiate the ViewModel through it's own initializer, requiring us to create the property and initializer

Most of the rest of the details in the class are about creating (the poorly named — sorry) UITextView, where the action takes place mostly in viewDidLoad.

However the real action goes on in viewDidAppear - now I know this loading will happen in front of the user (after all, the view will have appeared to the user before we even make the network call).

now we assign the completion hanlder in the view model (more to come of this later), which will return a Users object. Now instead of explicitly defining a name for the object $0 is used as a shorthand for the first argument (and represents a the Users array), and the second shorthand argument $0 represents each User in turn.

The full classes

Now there is the full code in the repo at https://github.com/stevencurtis/SwiftCoding/tree/master/DecodeReqres, but here is the code reproduced:

SceneDelegate

ViewController

ViewModel

Users

Some people claim that mobile development is nothing but taking JSON strings and displaying them on screen. In that case, this article certainly has you covered.

In any case, this is a good start in processing the data that you would need to be able to do in order to create a worthwhile project in Swift.

I hope this is of help to you.

If you’ve any questions, comments or suggestions please hit me up on Twitter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store