Saving Data in iOS

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

Part 2: JSON

14. JSON Encoding

Episode complete

Play next episode

About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 13. Saving On Device Next episode: 15. Challenge: Encoding JSON Arrays

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: 14. JSON Encoding

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

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

I'm 50% done with the whole Forgetful Felipe thing. I'm already remembering things thanks to the app loading storing data from the document directory. But unfortunately it's not saving any new things I don't want to forget about. Using the knowledge you acquired in part one, saving data to files, you will now start storing the single tasked disc. Open taskstore.swift and add a new method declaration that you will use to save a single task. The process is very similar to decoding data. You'll first encode your swift type to swift data, acquire the old route for where to store your data, and then save the file with your info to your device's storage. And Codable automatically handles writing it to the file in the correct format. So you'll be able to see how things are being stored to the document directory in a plain JSON file just like the ones you've seen in the project so far. Just as when loading, when you use JSON decoder, you have JSON encoder available to you. Add a JSON encoder at the beginning of the method. Very similar so far. As you did with the load method, you will have a do catch statement since encoding, as well as writing to your device's storage, can throw an exception. Just as when loading you print to the console, any errors that may take place during the process. As I mentioned before, the first step is to encode your swift type to data using the encode method on JSON encoder. The only parameter it takes is a swift object that conforms to the encodable protocol. When you added the codable protocol informants to a few of your models, you adhered to both encodable and decodable. For the object to encode you're just getting a single task out of a prioritized task object in your array. As always, start small and expand from that. If writing a single task succeeds, then you can proceed to write an array of prioritized tasks. Note how the call is marked with try as encoding can throw an exception. For now you would just store a single task in order to verify that things are working correctly and to do so you have to specify the URL of the file where you JSON will be saved. This should look very similar to you. You're getting a URL to a file named task.JSON, and storing it within the document directory. The final step in encoding is to write your encoded object to the JSON file. Once again the call is marked with try as it can throw an exception. And, similar to what you did in playgrounds, you're asking your encoded data to be written to a file at the specified URL. Once again the only option in this method is atomicWrite which is a fancy way of asking that the data be saved to a separate file first. Once that succeeds, it gets exchanged for the final file, the one you specified in the URL. This ensures that, should something crash or go wrong, the original task.JSON file doesn't get damaged or corrupted in the process. That pretty much does it as far as writing a task object to a file in your document directory. But where does it make sense to call this method? A good place to do this would be in the didSet of the prioritized task property. Think about it. Every time you modify or prioritize tasks is likely when you want to save your changes to a file. This will ensure that all changes made by a user are immediately persisted and not lost. Implement didSet for prioritized tasks. Build and run your app in the iOS simulator, be sure to have the document directory open in Finder for your app, ensure that it's empty, and add a new task in the app. Oh no! What's going on? Well, your array of prioritized tasks is empty but it needs to contain at least one prioritized task per priority available. To fix that for now, copy over the prioritizedtasks.JSON file to your apps document directory. We'll fix things so that file is required in the next video. Run your app one more time and try to add a task now. Excellent, your task got added. Open the apps document directory and look for a file named task.JSON. Select it and press the spacebar to preview. You can see that a single task is now getting correctly saved to the file. Hooray! One final thing worth mentioning is what to do when your swift types have date or date objects in them. Fortunately encodable and decodable can take care of it for you. Data and date get automatically serialized to JSON. Data is an encoded string, and date is a floating point. If you want to change the strategy to use when encoding or decoding these, you can use the data encoding strategy or date encoding strategy properties of JSON encoder and data decoding strategy and the date decoding strategy properties of JSON decoder. One of those when encoding dates is the formatted case that lets you specify a specific date formatter to use. While you don't need to worry about either of these in this course, you might at some point need to save or load JSON data that uses a specific format for dates. For data the convention is to use a basic d4 encoded string. But should you need to customize that too, just know that it's something that can be done. In preparation for saving and loading your tasks to and from the same file, take the task's JSON URL out of the load JSON prioritized tasks method and move it out to the taskstore class. Everything should continue to work as it was, except that you now have that URL available to use when you save the array of prioritized tasks. Are you up for a challenge? It's time to save all of the prioritized tasks to a file. Not just one. No more forgotten sunglasses or wallets at last.