← All topics/Data persistence

Question 1

Choosing the right storage strategy

You're building a feature with structured data, user settings, and large media files. How do you decide what goes in Core Data/SwiftData vs files vs Keychain?

Follow-ups

  • What should never go in UserDefaults?

Answer outline

Split the data by what it is and by how you read and write it. Each kind has a natural home on iOS:

  1. 1.Core Data or SwiftData: structured app data that you filter, sort, and update incrementally. Anything with relationships between records belongs here.
  2. 2.UserDefaults: small preferences and flags, such as a chosen theme or whether onboarding has run. It's a property list rather than a database, so keep it small.
  3. 3.File system: binary payloads such as images, video, documents, and other large blobs. Store the bytes on disk and keep only a relative path or file name plus metadata in the database, since the app container's absolute path changes across updates and restores.
  4. 4.Keychain: secrets such as auth tokens, refresh tokens, and private keys. It's encrypted at rest and meant for small values, so keep anything bulky out of it.

Large media belongs on disk, where file I/O and cleanup are easier to reason about. The directory you choose matters, because iOS gives each location different durability and eviction rules:

  1. 1.Temporary and cache storage (tmp and Library/Caches): regenerable data such as thumbnails, decoded buffers, and downloads you can fetch again. The system may purge these under storage pressure and doesn't back them up, so never keep anything there that you can't rebuild.
  2. 2.Durable app storage (Documents and Library/Application Support): data that must survive until you remove it or the user deletes the app, such as exports and offline copies you can't easily re-download. Both are backed up by default, with Documents for user-facing files and Application Support for app-managed ones.

Give every cache an explicit cleanup rule, such as a time to live (TTL), a maximum size, or a purge on logout. Without one, growth is unpredictable.

Principles

  • Only secrets go in the Keychain, which is encrypted but built for small values.
  • UserDefaults holds small preferences, never an app database or a payload cache.
  • Keep metadata in the database and heavy bytes in files, linked by stable IDs.
  • Treat tmp and Library/Caches as disposable, and keep anything you can't regenerate in durable storage.

Follow-up angles

  • Secrets, large blobs, and anything you need to query never belong in UserDefaults. It's a plain property list, unencrypted and loaded whole into memory. Tokens go in the Keychain, and payloads go on disk or in the database.