Saving Data in iOS

May 31 2022 · Swift 5.5, iOS 15, Xcode 13

Part 2: JSON

16. Codable Hierarchies

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 15. Challenge: Encoding JSON Arrays Next episode: 17. Conclusion

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 16. Codable Hierarchies

This course was originally recorded in April 2020. It has been reviewed and all content and materials updated as of November 2021.

Transcript: 16. Codable Hierarchies

You still need to correctly set up the initial prioritizedTasks array so your app doesn’t crash if you were to run it on a different similator or on a device.

There’s also a cool trick I want to show you of something that’s been happening automagically for you behind the scenes, and what to do if you want to use different variable names and JSON keys when encoding or decoding data.

Start with the array fix. The current issue, that results in a crasher unless you copy the initial prioritized tasks file, is that you are initializing prioritizedTasks as an empty array, when it needs to be an array of one PrioritizedTask per priority. Add the following instead of the empty prioritizedTasks array initial value.

@Published var prioritizedTasks: [PrioritizedTasks] = [
  PrioritizedTasks(priority: .high, tasks: []),
  PrioritizedTasks(priority: .medium, tasks: []),
  PrioritizedTasks(priority: .low, tasks: []),
  PrioritizedTasks(priority: .no, tasks: [])
  ] {
  didSet {
    saveJSONPrioritizedTasks()
  }
}

Run your app on a device or a different simulator now. If you want you can erase the contents of your current simulator to make sure this fix is working.

Already you can tell things are different as you have empty priority sections, whereas before, without the initial file, you had a blank screen with the buttons at the top.

Add a new task and the crash is now gone. If you stop and re-run the app your task should also be there too!

Fantastic.

Now, what happens when you want to encode or decode a type, that comforms to Codable, which also has a custom type as a property? Guess what, you’ve already been doing this. Open TaskStore.PrioritizedTask.swift and notice how your Structure, at it’s core, has a property for your custom type Priority, and an array of your custom Tasks.

The rule to making this nested setup work is to ensure that all your properties within a type also conform to Codable, fortunately, Xcode is pretty good at letting you know when they don’t and will throw an error even before you can run your app.

Now, what happens if you want to take your Task struct and store the id or completed properties under a different key in your JSON file? This is where CodingKeys come into play.

Open Task.swift and, within the structure definition, add the following enumeration.

enum CodingKeys: String, CodingKey {

}

This is an enumeration of Strings that conforms to the CodingKey protocol. What this protocol does is let you specify what your property names encode or decode into from your JSON file.

When you add this enumeration you need to specify cases for each of the properties you want to encode, so you need to add at least one case.

Because, up until now you were using the property names as the keys, you didn’t need this. Now that you want to customize them in the JSON file then you have added the enumeration. Add some cases so you can tweak the keys used in the JSON file.

case id = "identifier"
case name
case completed = "isComplete"

With this, you are telling Codable that you want to use name as the key for storing your Task name, but for the id you want it to be stored under the identifier key, and for completed you want to store it, in the JSON file, as isComplete.

Run your app and, if you want to see the resulting JSON file, use the simulator so you can see the PrioritizedTasks.json file. Add a task then check out the resulting JSON file. Your JSON file has keys, for a task, that differ from the property names you used in your app.

This will come in handy when you are loading data from a web service that, perhaps, doesn’t have the nicest key names, but you don’t want to be forced to use those as your property names.