When should I use the various storage mechanisms in iOS?

I thought this would be covered already, but my search returned nothing of relevance.

I am aware that there is NSUserDefaults, Core Data, object archiving, raw SQLite, plists, and of course, storage by web servers. What is unclear and somewhat hazy to a beginner is when to employ each of these various tools.

The usages of web servers vs Core Data is obvious, but what about NSUserDefaults vs plists? Core Data vs object archiving? A simple breakdown of use cases would really help me understand why there are so many options for storage in iOS.


I try to write a quick and simple list of common use cases, because as @rmaddy says this answer could fill a book chapter:

  • NSUserDefaults: stores simple user preferences, nothing too complex or secure. If your app has a setting page with a few switches, you could save the data here.

  • Keychain (see SSKeychain for a great wrapper): used to store sensitive data, like credentials.

  • PLists: used to store larger structured data (but not huge): it is a really flexible format and can be used in a great number of scenarios. Some examples are:

    • User generated content storage: a simple list of Geopoint that will be shown by a map or list.
    • Provide simple initial data to your app: in this case the plist will be included in the NSBundle, instead of being generated by user and filled by user data.
    • Separate the data needed for a particular module of your application from other data. For example, the data needed to build a step-by-step startup tutorial, where each step is similar to the others but just needs different data. Hard-coding this data would easily fill your code, so you could be a better developer and use plists to store the data and read from them instead.
    • You are writing a library or framework that could be configured in some way by the developer that uses it.
  • Object archiving could be useful to serialize more complex objects, maybe full of binary data, that can't (or that you don't want to) be mapped on simpler structures like plists.

  • Core Data is powerful, can be backed by different persistent stores (SQLite is just one of them, but you can also choose XML files or you can even write your own format!), and gives relationships between elements. It is complex and provides many features useful for the development, like KVO and contexts. You should use it for large data sets of many correlated records, that could be user generated or provided by a server.

  • Raw SQLite is useful when you need really, really fast access to a relational data source (Core Data introduces some overhead), or if you need to support the same SQLite format across multiple platforms (you should never mess with CoreData inner SQLite: it uses its own format, so you can't just "import" an existing SQLite in CoreData). For example, for a project I worked for, a webservice provided me some large SQLite instead of jsons or xmls: some of this SQLite were imported to CoreData (operation that could take a while, depending on the source size), because I needed all the features of it, while other SQLites were read directly for a really fast access.

  • Webserver storage well it should be obvious: if you need to store data to a server it is because the device shouldn't be the only owner of that data. But if you just need to synchronize the same App across different iOS devices (or even with a Mac-ported version of the App) you could also look at iCloud storage, obviously.