Skip to content
nedmiz-6habsu-zyJcog edited this page Sep 2, 2019 · 1 revision

There are several modules within the xmpp framework that require some kind of storage mechanism. The perfect example is the roster. This module handles fetching the roster (buddy list), and keeping track of who's online / offline. In order to accomplish its task, it needs to store all the user information somewhere. The trouble is that different applications have very different use cases and requirements. Perhaps the roster contains thousands of users, so caching the information to disk is best. Or perhaps the roster is small, and users go online/offline at a rapid pace - thus storing the information in memory is preferred. The upshot is that the framework allows you to choose which storage mechanism best suites your needs. To accomplish this, you'll notice that storage is often abstracted within a module. The module provides one or two storage implementations, and specifies a protocol for implementing your own custom storage (if needed). For example, the XMPPRoster module comes with XMPPRosterMemoryStorage and XMPPRosterCoreDataStorage. Plus it specifies the XMPPRosterStorage protocol in case you'd like to implement your own.

Now after implementing CoreDataStorage for several modules within the xmpp framework, we noticed several patterns emerge. Some of them were obvious, such as the standard boilerplate code that's required to setup a core data stack. However others came with age, such as optimizing disk IO, and properly managing core data in a multithreaded context.

## Core Data Overview

There are some technologies that Apple creates that almost seem magical. They take a complicated thing, and make it so simple that it "just works" without much effort. Core Data is NOT one of these technologies. Over the years I've seen many developers jump into core data without bothering to first research the technology. Their app becomes buggy or slow and they throw their hands in the air, declare that core data sucks, and move on to some other storage mechanism. In reality, core data is a wonderful technology, but requires a deeper understanding of how it works to properly use it.

Often times when people complain about core data, I ask them what they want. Here's what they say:

> _First, this magical new storage technology should be built on top of SQLite. This database is incredibly powerful and fast, has been around for years, and benefits from extensive use, debugging and optimizations. In other words, it's an industry standard. There's no use reinventing the wheel here._

> What else?

> _The magical new storage technology should let me use objects, just like I do now. If I make changes to the object, it should automatically save to the database. And when I fetch from the database, I want it to give me objects back. I don't want to have to deal with database rows and columns. I don't want to have to create my objects from a database row. Just have it give me objects._

> Sounds pretty cool. I bet you could write something like this yourself, even without being an SQLite expert. Now what are you going to do when you write version 2.0 of your app, and your objects don't look the same?

> _Oh, well for that I'll cook in some kind of clever versioning. Yeah... And it will be automatic if the changes are obvious. Otherwise I'll add hooks so I can manually implement versioning myself._

> Sounds fancy. And what about thread-safety? I hear those new iPhones and iPads even come with multi-core CPUs these days, and everyone is writing more multithreaded code. What happens when you change an object on a background thread, and the main thread is also using that object?

> _Yeah, thread-safety... Um... I suppose I may not want to block the main thread with disk access all the time, so interacting with the database on background threads would be pretty cool. So um..._

And now we've circled back to explaining what core data is. It's a mature implementation of all the features listed above.

Core Data can be layered atop SQLite. It provides a base class called NSManagedObject. Create your own objects atop this, and Core Data can manage most of the data storage for you. It has powerful support for versioning, oftentimes doing everything for you automatically. And it has well-defined thread-safety rules, and even provides change notifications to sync objects when they're changed on another thread. It even provides various rules to deal with conflicts. It's data storage, all grown up. But it's complicated, and not without caveats (just like grown up TV shows).

Clone this wiki locally