Advertisements
Everything about iOS app development
NSCoding In IOS With Recipes

Offline support without Core Data with NSCoding in iOS

Recently I received a lot of comments about how to persist data locally on a device to support offline mode.

The scenario is the following: you have an app that downloads content from a server, user downloads it, everything is fine. But what if they close the app, lost network and open it again to see their saved favorites. If you don’t support offline mode they will not be able to see anything or interact with their content.

There are multiple ways to solve this issue:

  • Use a database like Core Data and sync/save everything into it, so when you’re connection drops you can just load the data from the database.
  • Save your downloaded content directly into files with the help of NSCoding. You are mainly going to download  data in a .json format, so why don’t you save the whole file to disk and load it when necessary?

To learn more about NSCoding make sure to check out the official documentation from Apple here.

I’m going to show you how to do the last option. But we go easy on this one for now. Let’s assume you have a Recipe app, and you wish to add a possibility to save your recipes as Favorites on your device locally.

What is NSCoding?

NSCoding is a protocol that you need to implement on your data class if you wish to support the encoding and decoding of that object. You must implement two methods of NSCoding that allows you to specify which data to persist.

As you can see, this is all you need to setup your code to be able to archive and unarchive it. But let’s see how it is done with real objects and properties in place.

Cache everything with NSCoding

Our Recipe object looks like this:

These are all the properties we are going to save when a user sets it as a favorite. If you have nested objects like we do (CookingStep, Ingredient classes), you need to implement the NSCoding protocol there too. Therefore, the whole object with all its objects will be saved on disk.

First of all let’s look at the encoding part. NSCoding protocol contains a method called: encodeWithCoder(aDecoder: NSCoder). We use the aDecoder variable to encode all our properties. Note that it has designated encoder methods for Int, Float, object, boolean etc.

You basically take all your properties and call aCoder.encodeObject(TheObject, forKey: KeyForYourObject). The encode method expects two parameters, one is the object that you wish to encode, and the key you wish to assign it too. Same like as you would do it in a dictionary (define a value for a key). If you have nested objects – like I do – you need to do the same thing on those objects too.

That’s all for encoding.

Decode your objects

Now that you encoded your objects properly, time to decode them when you wish to read them from a file. You’ll need an init method that you implemented earlier (see above) and another init method (optional) that uses all your decoded data as parameters.

In our example it will look like this:

I hope it makes sense to you but if it didn’t, let me explain it to you.

You opened the app and want to load your favorite Recipes therefore you call your manager object to load all objects. First of all, it grabs all the data it found and call the init?(coder…) method. Than you define which objects you want to get for a given key and assign it to a variable, than call the designated init method with all your properties and move on to the next object in your favorites. Just simply call: aDecoder.decodeObjectForKey(YourKeyForYourObject) and specify what type of object you wish to get.

Manage saving and loading objects

Now that you have NSCoding in place, let’s look at how to do save and load these objects.

Saving

We’ll have a manager object to help us organize our code and make our life easier. Therefore let’s create a new class called: FavoritesManager a subclass of NSObject.

It will have 2 methods:

  1. saveRecipes(recipes: [Recipe])
    1. saves an array of recipes
  2. readFavoritesFromDisk() -> [Recipe]?
    1. loads all the saved Recipe objects from disk

1.

2.

As you might noticed I skipped an important part which is the where… It’s okay to save and load your saved recipes but how do you tell your app where it can find them.
You can just add 2 new helpers:

That will serve as a reference to a folder, where the manager object should save your recipes to and load them from.

Wrap up

So it is really that simple. For years I had no idea what NSCoding is and how to use it, because of that I just skipped it and went the long way, boy I was wrong… Since everything in iOS or life is hard you tend to just pass it but cannot avoid it at the end.

Hope it was helpful to you and learned something today about NSCoding and lightweight caching.

I have a simple template on Codecanyon.net that uses this technique, if you wish to check it out, click on the button below.

Have an awesome coding day!

%d bloggers like this: