CoreData has been at the heart of Money Out and Money In from the very beginning. It offers a great variety of features such as data modeling tools, versioning and migrations, object graph with inheritance, powerful API that allows to run complex queries and small memory footprint.
One of the greatest additions of CoreData is ability to store data in iCloud allowing to persist data across devices. Although we read many complains about iCloud support and there is really not much told about it on the web, we decided to give it a try. Deep down we believed that things should have been fixed by iOS 9.
Unfortunately, we found that it was entirely broken. Even on a very simple model, relationships would arrive too late causing validation errors and bringing the entire sync down. Recent deprecation of Core Data iCloud didn’t come as a surprise, what’s surprising that it’s been around for so long.
We started looking for alternatives and discovered Ensembles which guarantees data consistency, multiple transports and offers global identifiers for objects which allow to identify duplicate records across devices and relink them together.
Things we learnt using Ensembles and trying to build a synchronization into our apps:
- You cannot change global identifiers for existing objects. Instead you have to delete and add new ones, losing all relationships and breaking any references outside of CoreData too, i.e. local notification corresponding to relevant object.
- De-duplication can be hard because sometimes you want to merge, not to just drop one object and leave the other.
- App extensions cannot use Ensembles side-by-side with the main app. CoreData should work just fine across processes since iOS 8.2 when used from shared container, but Ensembles may not function properly.
- Storing user settings apart from CoreData may result in data inconsistency if settings affect the way you populate database. In our apps we create financial periods over time and we re-arrange existing financial periods when relevant settings change.
- Local notifications have to be managed each time you merge from cloud. I.e. you can’t schedule notification ahead of time and forget about it. You have to make sure it’s still relevant when you get data from other devices.
- Seed data has to be versioned, your app should be ready to handle different versions of seed.
Over the year of development our data model has been continuously changing and growing, we’ve been spending increasingly more time on data reintegration than actually adding features. We had to make a hard decision to pull out CoreData synchronization from Money In and Money Out.
However, our users can still backup their data using standard iTunes backup or automatic backup built into iOS.