My book on iOS interface design, Design Teardowns: Step-by-step iOS interface design walkthroughs is now available!
For a long while we had little in terms of mobile persistence options (other than Core Data, or
NSKeyedArchiver using the
NSCoding protocol) until earlier this year when Realm was released. Advertised as a mobile database, it aims to supplant Core Data and SQLite as storage solutions on iOS and later, Android.
Let's contrast this with the more traditional methods of working with data persistence on iOS and some more opinionated solutions. For this discussion a basic knowledge of Realm is assumed. Refer to the Getting Started guide for more information.
JSON Parsing and Serialization
One of the more popular methods of working with JSON on iOS is to use a mapping library such as Mantle or JSONModel to process the resulting property list output of NSJSONSerialization. The mess of
NSNumber objects are converted to native
NSObject subclasses that you define. Using such a mapping is advantageous for several reasons.
For one, there need not be a one-to-one correspondence in the structure of the input JSON and underlying model in the mobile application. Most of the time, the JSON is derived from API endpoints that are beyond control. It may also adopt different naming conventions that are not native to iOS.
Working with property list types often leads to tedious code and is also not type safe. It's also necessary to be constantly aware of the structure of the input to know how to access data.
Another issue with working with a database, is that we should check for existing data in the database to avoid ending up with duplicate data. One way to is to check for the presence of primary keys, retrieve and update an existing object (if it exists) before creating and adding new objects to the database.
Handling Reversible Edits in the UI
While typically a non-issue using
NSObject subclasses or Core Data, Realm actually exposes its database through its ORM and
RLMObjects cannot be mutated outside a transaction. This makes handling reversible edits rather difficult.
A possible solution to use a standalone object (one that hasn't yet been added to a Realm) as a backing model in the View Controller by creating a shallow copy of the one in the database and later merge the values back in a write transaction. This may involve first copying the values on the said object to a freshly allocated instance.
Using Data across Multiple Threads
Sometimes it's handy to create objects on the background thread (perhaps as a result of a networking operation) and then pass the objects to the main thread for presentation in the UI. Again this is not supported in Realm because the objects are not thread-safe. To "move" objects across threads, they have to be queried for again on a
RLMRealm instance on the desired thread.
The easy solution here is again to use primary keys. After getting the value of the primary key of a object on the source thread, simply query for matching primary key on the destination thread.
An implementation of the above solutions can be found here.