UserDefaults vs FileManager vs Keychain vs Core Data vs SwiftData


Greetings, traveler!

Starting a new project where you will need to save data, you can face the choice of technology that will allow you to do this. In Swift, there are several options to choose from:

  1. UserDefaults
  2. FileManager
  3. Keychain
  4. Core Data
  5. SwiftData

Let’s determine what technology will be the most suitable for concrete cases.

UserDefaults

Apple’s Documentation says:

An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app.

You should use it to store small amounts of data like flags, IDs, dictionaries, dates, etc. It was not designed to store large amounts of data. Also, you shouldn’t save sensitive information like passwords, tokens, etc.

The main advantage of using UserDefaults is its simplicity, and after Apple presented a new @AppStorage property wrapper, it became even simpler.

By the way, I have an article about the @AppStorage property wrapper. Feel free to read more about this API.

FileManager

The file system provides a way to store different types of data, such as images, videos, custom data types, etc. Unlike UserDefaults, it can be used to save larger data sets. However, it has a slightly more complex interface. You should be ready to handle file paths and errors.

FileManager does not have built-in security tools, but you can create your own mechanism for using the file system. However, we should remember that this is not a secure way to store sensitive data by default.

If you care about the performance of your application, I should remind you that the file system is relatively slow compared to other solutions.

Keychain

Since we have touched on security questions, let’s talk about Keychain, Apple’s tool for storing sensitive data.

The Keychain provides strong encryption and access controls, making it suitable for storing sensitive and confidential data. While its security features can also make it more complex to work with, several cool open-source libraries provide convenient wrappers for it.

What about performance? Since the Keychain is a complex mechanism, it can sometimes demonstrate a lack of speed. However, it is not designed to store big amounts of data, so this potential lack should not be noticeable.

Core Data

Core Data can become a more suitable choice if you have highly structured data with relationships between entities. CoreData is not a database in the traditional sense. To be clear, Core Data is not a mechanism for storing data directly; instead, it provides an interface to an object store, commonly backed by an SQLite database on the device’s file system.

Core Data allows defining complex relationships between models, as well as sophisticated querying capabilities. While it is easy to start with Core Data, making complex tools for working with it can become more challenging. But if you don’t want to create complex data-saving scenarios, you can use it without any headache, even with SwiftUI, since it has convenient tools for this framework. Also, it is very fast!

Since iOS 5, Core Data persistent stores have used Data Protection to encrypt data, but Apple recommends that sensitive information like passwords or tokens should only ever be stored in the Keychain.

SwiftData

SwiftData builds on top of Core Data. However, since it is still a new technology, you won’t find all of the Core Data features in SwiftData. For example, there is no equivalent for NSFetchedResultsController and NSCompoundPredicate. Another downside is that it requires iOS 17 and later.

But this technology will grow and develop fast. While there is less information about it now, Apple will provide more and more convenient tools for SwiftData in the future, and the SwiftData community will grow. So, if you are choosing between Core Data and SwiftData, here are some arguments for choosing the latter:

  1. It is much easier to learn and use SwiftData than Core Data.
  2. As mentioned, SwiftData builds on top of Core Data, so you can easily switch to Core Data if necessary.

Conclusion

We discussed the main mechanisms for storing data in an iOS app. Each mechanism has its own purpose, and it is essential to choose the right one based on an understanding of its design.