1

I built an app about a year and a half ago that I'm coming back to. It was the project I cut my Swift teeth on and obviously a lot has changed since then, both in the language and my Swift abilities.

Yesterday for the first time, I updated my single CoreData model to add an optional string attribute. I did the file generation bit and made sure in the inspector column the new data model is appropriately selected.

On my Simulator and testing devices, I need to delete the old version of the app to install the new version or I get a crash. I assume that's just part of the development environment process. How can I ensure that upgrading users won't have to delete and reinstall when they do a simple update from the App Store? I assume that Xcode/CoreData/Apple have this handled with some internal scripts or processes that are invisible to the user, "it just works." But I wanted to post this here to understand if there's anything additional I need to do to ensure a smooth transition from v1 to v1.1 for the user.

All I did was an an optional string column, as I mentioned. I assume that all existing user data will be migrated over to the new schema with the new field being nil.

Any thoughts here would be very welcomed and appreciated. Thanks!

Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151
  • You have some choices to make as to how you'd like to migrate from the old version to the new one, I'd suggest reading here for a bit: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweightMigration.html – Fred Faust Feb 07 '17 at 14:26
  • Thanks, will take a look – Zack Shapiro Feb 07 '17 at 14:33
  • 1
    That crash is not part of the development process. You need to fix that before release. – Tom Harrington Feb 07 '17 at 15:25
  • 1
    @TomHarrington, understood. I've got it working locally, but it required me deleting the app from my simulator and doing another build and run. Similarly, I had to do that when putting it on my phone, deleting all my old coredata and starting fresh. Obviously unacceptable for the user, so I'll need to build and run with the old schema, create some data, build and run with the new schema and make sure the migration happens – Zack Shapiro Feb 07 '17 at 16:09

2 Answers2

8

If your app is crashing in the Simulator when upgrading, your users will have crashes too.

To avoid this, you need to make sure you follow these steps:

  1. Make sure you do NOT change the original version of your data model in any way.
  2. In Xcode, select your xcdatamodel file, then from the menu choose Editor > Add Model Version...
  3. Xcode will suggest a new version name, based on the current model. Make a mental note of the new version name, then click Finish.
  4. Select the xcdatamodel file again, go to File inspector and under Model Version, select the new version name to make this your current version.
  5. In Project Navigator, select the new version of the xcdatamodel. Add your attribute.

It's important to follow these steps in this order. If you add your attribute before creating the new model or making it your current version, you will have crashes.

EDIT: This will only work if you enable lightweight migrations. This is a code snippet of how to do this:

let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]

do {
    //coordinator is an NSPersistentStoreCoordinator
    try coordinator!.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options
} catch var error as NSError {

  // handle error however you want here...            
  abort()
}
Mike Taverne
  • 9,156
  • 2
  • 42
  • 58
0

In addition to @Mike Taverne's answer, I think it a better if I post some screenshots to illustrate the option

for Xcode 12.3

Choose from the main menu Editor -> Add Model Version

enter image description here

To add mark the New Model as the current model with a green checkmark Follow the below image

enter image description here

Amr Angry
  • 3,711
  • 1
  • 45
  • 37