Why Offline handling?
- Offline data handling in iOS apps isn’t an extra feature anymore. Users want and expect it as a default feature in apps. So it is necessary to save data in our apps.
- Data from researches and surveys show that users abandon pages if they take more than 3 seconds to load. This makes Offline handling even more important, as it can make apps fast.
- Unlike laptops, which are generally used where the network/internet is available. But for mobile apps, the internet can’t be available all the time (user on a plane, a cafe, a subway etc.). So for better user experience, it becomes crucial that we give offline support too.
How to do it?
- There are many different ways: databases(realm and core data), cache etc. Each has its own advantages and disadvantages. We have to decide based on our requirement and ease of implementation.
- So, choose wisely weighing all pros and cons.
How to choose between Cache and Databases?
- Developers tend to overuse databases. But it is a bad practice as caches are much easier to implement. Databases are powerful but aren’t required for many applications.
- Most Common Ways to implement databases are Realm and Core Data.
- Some of the open-source implementations of cache are NSURLCache, PINCache etc.
- Caches can be used if you need a simple, lightweight solution. It can be used if logic to handle data from network call is already present and you want to just extend it to offline mode.
- You can use databases if you are sure that data isn’t too large. Databases ease the search operations over a large record.
- But databases are difficult to implement and can cause crashes in apps if not implemented properly.
- The simplest way to implement cache is denormalized caches, where you could store the entire data tree in a single entry. It is the simplest way of caching
- But this could cause inconsistencies, and in those cases, normalised caches can be used.
- It means the data tree is divided into many sub-models and each is cached separately with a unique ID.
- Databases can be implemented by defining data models, loading data from network calls and then saving data to the database or updating it whenever required.
Different Options popularly used for offline local data handling in iOS:-
- SQLite: It is shipped with iOS, and adds no overhead to the app. It requires developers to create and connect to Database, creates tables, inserts/update/delete rows.
- Property List files: Documents can either be NSArray or NSDictionary type, inside which we can save data. Only NSArray, NSDictionary, NSString, NSDate can be saved.
- Core Data: It uses SQLite as its main database. All the data is saved in .db files. This eliminates the need to install a separate database in your app. It provides an API to deal with common functionalities like save, delete etc. You have to create a data model (database schema), data model editor can be used to make the data model in .xcdatamodeld file. Entity, Attributes, and relationships have to be defined. NSManagedObject attributes can be written and read using Key-Value Coding. NSmanagedObjectContext is needed to save and fetch data to and from Core Data.
- NSUserdefaults: It is used to save logged in users’ state within the application. Can be used to save user’s confidential information like access tokens. It can be used to store small amounts of data. The saved data can be accessed globally throughout the application. NSUserDefault caches the information, and we don’t have to access the database for default values.
- Key-Chain: This is generally avoided because data becomes vulnerable if the device is jail-broken.
- To use Core data, it’s important to enable the “Use Core Data” option. This will cause XCode to generate code for NSPersistentContainer.
- NSPersistentContainer helps manage Core data, facilitates saving and retrieving data.
- The first step in modelling data for Core data is to create a managed object model. The Data Model is similar to a database schema.
- In the .xcdatamodeld file, a data model editor can be found. Add Entity option of this editor can be used to create a new entity. To rename the entity double click it. An entity is a definition of a class for Core data.
- We can also define attributes for entities. Even relationships can be defined by two entities.
- To save data, NSManagedObject instances are used. It represents an object saved in Core data. NSManagedObject doesn’t directly know about the attributes defined in the Data model. So, to read the data from Core data is through Key-Value pairing. The below code shows a way to save and fetch data from Core data
- It was earlier known as NSUserDefalts. It is used to save small data in your app, like app settings, user’s access token etc.
- UserDefault is a .plist file in your app and its structure is similar to a dictionary. So, the data is saved in Key-Value form.
- Internally, it can only store NSData, NSString, NSNumber, NSDate, NSArray and NSDictionary only.
- Before saving data or fetching it, the reference to the standard user defaults is required.
- The below code shows a way to save and fetch data :
Code to save data:-
Code to fetch data:-
Code to remove data:-
There are many different ways to achieve the offline data handling feature in an iOS app. It is important to consider and compare all of them before implementing them. I have covered a few in detail, please refer to the references for more detailed analysis.