Last month, I launched a new app on the App Store called Hansel. It’s an app that helps you keep track of the places you’ve visited by running in the background. To save the location data, I used SwiftData along with iCloud support so that the data is stored in the cloud, not just on the device.

After the first version of the app was out, I wanted to add new features. To do this, I made changes to the SwiftData model I had set up earlier. This required using VersionedSchema and SchemaMigrationPlan. Everything worked fine during my testing, so I released the new version. But soon after, users reported that the app was crashing. For an iOS developer, this is one of the worst things that can happen. I hadn’t caught the issue myself, but a friend helped me debug it, and we figured out what went wrong.

The error users saw was: “Cannot use staged migration with an unknown model version.” After a few hours of investigation, I realized the issue happened because I hadn’t used VersionedSchema when I first set up SwiftData. This meant the initial model didn’t have a version. Later, when I made changes, I added the model to a versioned schema, created a new version, and implemented a migration plan. Since these changes were all part of a single build, SwiftData couldn’t migrate the model, which caused the app to crash.

From what I found, this problem has been around for more than a year, and Apple hasn’t fixed it or mentioned it in their SwiftData documentation. Many examples online also use SwiftData without versioning the model, which makes this issue even more likely to happen.

The proper way to handle my situation would have been to:

  1. Put the model in a versioned schema.
  2. Release a new app version so users switch to the versioned model.
  3. Wait for users to update the app.
  4. Create a migration plan with a new version.
  5. Release another app version.

This process takes time, and some users could still face crashes if they skip updates. Another option would be to create a completely new model within a versioned schema and migrate all data from the old model when the app opens. But that approach isn’t ideal, in my opinion.

I think Apple should include this information in their documentation or at least show a warning in Xcode. It’s unlikely that any app will use the same model forever, so starting development with a versioned schema should be standard practice when using SwiftData. I hope this post helps you avoid the same issue I faced.

Older post

How to bring back English as supported languages on App Store

After starting to use String Catalogs, I noticed that English was no longer listed as a supported language on the App Store. This post shows you how to bring it back.