Search code examples
iosiphonecore-datacore-data-migrationiphonecoredatarecipes

Core data Missing Model Version?


I actually have a project with 6 core data models like V1 to V6,all are on app stores now when I am trying to update app from one of the older version (core data modelV3) to the current version it crashes (schema mismatch)

when investigated actually V3 model version is different between two project version from older V3 Model to current Model V3.

as in V3 version i added new entity and did not do LightWeight migration(forgot to do it), now is it any way I can allow users to upgrade this older app version with V3 model to the current app version like by solving this (Missing migration issue)

Please suggest any way to add a missing migration model if possible to provide smith upgradtion of the older app version to the current app version.


Solution

  • addPersistentStore should automatically perform necessary lightweight migration. Check if that code is reachable in all your application starting paths.

    For that to happen, you need to supply correct set of options, as below:

    do {
        let options = [ NSInferMappingModelAutomaticallyOption : true,
                        NSMigratePersistentStoresAutomaticallyOption : true]
    
        try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType,
                                                          configurationName: nil,
                                                          at: persistentStoreURL,
                                                          options: options)
    } catch {
        fatalError("Problem loading Persistent Store")
    }
    

    Please also make sure your main xcdatamodel file points to latest version of your datamodel. Also note that following picture is taken after selecting your latest version xcdatamodel file (yourdatamodel 2.xcdatamodel), not the root xcdatamodel file (yourdatamodel.xcdatamodel).

    enter image description here

    A word of caution:

    Reconsider: do you really need something beyond lightweight? In most situations, lightweight should resolve your problems.

    You can get away with lightweight by adding more fields and stop using older fields in your code, thus making the task easier for Core Data. For rows relying on older fields, simply run some insert/update/delete operation if core data model version change is detected.

    In order to check where lightweight fails, you can consider enabling following XCode argument:

    -com.apple.CoreData.MigrationDebug 1
    

    If lightweight isn't capable of fully migrating your model (such as you have renamed your entities, or data types have changed, which is very unrealistic and you should really reconsider your design if you are doing this), then you can consider this somewhat complex solution:

    • add persistent store with older model version and back up existing rows in some external file (non core data)
    • deleting the old persistent store and recreate it using addPersistentStore + newer model version
    • use newer persistent store to insert backed up data

    If all else fails, then consider mapping model alternative. Refer to this article for more details.