How to use JSONDecoder and PropertyListEncoder

Posted by

In this lesson, we’ll use JSONDecoder to decode json data into our Codable model objects. In addition to that, we will encode the model objects using PropertyListEncoder to save those models to User Defaults.

We will create a .json file in our project and try to decode/encode it.

After this tutorial you would will be able to

  • Create codable models
  • Add json file to your project and read data from that file
  • Convert that data to our codable model
  • Encode the model to property list format and save it safely in User Defaults
  • Fetch and decode models from User Defaults

Let’s get to it!

To begin with, create an Xcode project, and name it  ‘LearingCodable’.
Choose a single view application and now just run your project to make sure everything is setup!

In your project, add a new empty file and name it Data.json, like so:

Step 1:

Screen Shot 1397-05-24 at 12.48.01 PM.png

Step 2:

Screen Shot 1397-05-24 at 12.48.15 PM.png

Step 3:

Screen Shot 1397-05-24 at 12.48.27 PM.png

Now that we have an empty .json file, we can add some json data to it!

Suppose our json file contains information about a person. His name, age and the his work location

Add this to your json file:

{
    "name": "Jacob",
    "age": 25,
    "work_Location": "California"
}

That’s it, out json file is ready to use. But now we should create our codable model that corresponds to this json object!

In project Navigation, open ViewController.swift:

Below your View Controller class, declare a struct like so:


import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}							

struct Person: Codable {
    var name: String
    var age: Int
    var work_Location: String
}

There are two things to takeaway from struct code:

  1. Our declaration of struct   struct Person: Codable  allows our struct (‘model’) to be ecoded/decoded into specific formats. Codable protocol is actually just a typealais for Encodable & Decodable protocols.
  2. Our property variables are name, age, work_Location, the property names are exactly the same as the ones declared in our Data.json file. It is important because this way json decoder maps data directly to our model!

Now, lets read the Data.json file and get the data inside it:

Inside your viewDidLoad method of ViewController class, add

guard let file = Bundle.main.path(forResource: "Data", ofType: "json") else {return}

This line looks for a .json file that is named Data in your app’s bundle.

After this line, add the following lines of code:

do {
    // Read json data from file
    let data = try Data(contentsOf: URL(fileURLWithPath:  file), options: .mappedIfSafe)

    // Decode the json data into person (our model)
    let person = try JSONDecoder().decode(Person.self, from: data)

    print(person) // Person(name: "Jacob", age: 25, work_Location: "California")

    let encodedData = try PropertyListEncoder().encode(person) // Encode data using property list encodeer

    UserDefaults.standard.setValue(encodedData, forKey: "personData")// save data to user defaults

} catch let error {
    print(error)
}

First line is,

let data = try Data(contentsOf: URL(fileURLWithPath: file), options: .mappedIfSafe)

This line converts the content inside our file to data object. It reads the contents and maps the data to virtual memory if possible.

Second line,

let person = try JSONDecoder().decode(Person.self, from: data)

This line uses the relatively new Apple API JSONDecoder.
It decodes json data and maps it directly into our Person model.

so now after this line ‘person’ will be a value type and person.name will be “Jacob”

We can verify that by printing person in the next line as shown.

print(person)

And the result is

Person(name: "Jacob", age: 25, work_Location: "California")

Now, we have our model object in person and we can use it however we want!
We can store this to core data or save to user defaults. We will look how to save this to User defaults in this example.

To do that, we look at next line

let encodedData = try PropertyListEncoder().encode(person)

This line uses PropertyListEncoder to ‘encode’ our model into data!

But, what is PropertyListEncoder?

Our struct (model) conforms to protocol Codable, which means our model can be encoded as well as decoded. There are many ways data can be encrypted (encoded) or decrypted (decoded). JSONDecoder is an API that allows us to decrypt/encrypt json data using JSONDecoder().encode(… or JSONDecoder().decode(..

Similarly, PropertyListEncoder allows us to encode or decode data into a plist format, which is essentially how our user defaults stores data. Hence, it is a great practice to plist encode data and save it to user defaults.

Next line does exactly that:

UserDefaults.standard.setValue(encodedData, forKey: "personData")

It saves the encoded data to user defaults.

And we are done!

We have learnt how to convert JSON data to our codable models and how to save data to UserDefaults

Finally, we also need to see how to retreive data from UserDefaults later on.

To do that just do the following,

do {
    let person = try PropertyListDecoder().decode(Person.self, from: UserDefaults.standard.data(forKey: "personData")!)
    print("Encoded person ", person) // Encoded person  Person(name: "Jacob", age: 25, work_Location: "California")
} catch let error {
    print(error)
}

This time around, we used PropertyListDecoder to decode the data we encoded earlier.

 

This is the end of the tutorial,

Hope you enjoyed reading through it

Download Github project here

We appreciate your feedback, please comment below if you have any suggestions or requests!

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s