TL DR
At least with Xcode 8/9, open the mapping model, then select Update Data Models from the Editor menu. Usually you need to restart Xcode. If this is not the case, you can try reinstalling the destination at the bottom of the model editor.
Additional tips
Definitely NEVER change the model after it is distributed in the application assembly.
In this example, suppose you publish Data Model 1 (DM1) and move on to DM2. If you install DM2 as the active version, then run the application, the migration will be launched in your permanent storage. If you then make another change to DM2, launch the application ... Boom!
The problem is that your store has already been transferred to "DM2", but the data in the store no longer fits into the model. And we cannot switch from DM2 to DM2 again.
This may seem like an obvious solution and create a DM3. this is usually a good idea, although minimizing the number of models and migrations during development.
So ... now you have a permanent store that has been migrated to a non-existent DM2. How do you test migration again? You can return your application and generate some data using DM1, but I prefer to use backups
Backup
Before starting the application with DM2, you can copy the existing storage (with DM1), which will be used for subsequent test migrations. On macOS, you can easily do this manually. The code below should also do the trick. Normally, you would not want to send this, rather, you could just put it somewhere before your normal CD stack opens, start the application, and then stop the application (maybe put a breakpoint right after you finish working through Xcode).
let fm = FileManager.default let url = // The store URL you would use in β // try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil) let dir = url.deleteLastPathComponent().appendingPathComponent("Backup", isDirectory: true).appendingPathComponent("DM1", isDirectory: true) print("Saving DB backup for DM1") if !fm.fileExists(atPath: dir.path) { do { // Create a directory try fm.createDirectory(at: dir, withIntermediateDirectories: true, attributes: nil) let backupURL = dir.appendingPathComponent(url.lastPathComponent) try fm.copyItem(at: url, to: backupURL) } catch { print("Failed to save DB backup") } }
Sorry, I need to make another change ...
If you start your migration to DM2, then realize that you need to make another change, you will want to double-check your migration from DM1 β DM2. This is where the backup takes place.
Just as you made a backup, run this code.
let fm = FileManager.default let url = // The store URL you would use to add the store let dir = url.deleteLastPathComponent().appendingPathComponent("Backup", isDirectory: true).appendingPathComponent("DM1", isDirectory: true) let backupURL = dir.appendingPathComponent(url.lastPathComponent) if fm.fileExists(atPath: backupURL.path) { do { fm.removeItem(at: url.path) try fm.copyItem(at: backupURL, to: url) } catch { print("Failed to restore DB backup") } }
You now have a refurbished DM1 store and changes to DM2. If you run the application, the migration may succeed, but it will not use your custom mapping model.
Remember that if you use custom mapping, you still have to use the Update Data Models technique before the mapping model works.