Yes, you'll have to do a manual migration for this, if you want every object to have a UUID immediately. To create UUIDs, you'll need to run code during migration, and to run code, you need to write a custom migration policy-- that is, a subclass of NSEntityMigrationPolicy
. The general process will be similar to something I described in a previous answer.
If you don't need every object to have a unique ID immediately, you could do it on the fly, as you access records. One way to do that would be to implement awakeFromFetch
in your Core Data subclass. In that function, check to see if the object has a UUID, and create one if necessary. Then when you save changes you'll save the UUID. This could be simpler but it would also mean you can't be sure that every object has a UUID.
Update with a lot more detail...
I tried out a similar migration, adding a non-optional UUID property to an entity. Here's how I set it up:
- I made a subclass of
NSEntityMigrationPolicy
with this code:
class Migration1to2: NSEntityMigrationPolicy {
@objc func newUUID() -> UUID {
return UUID()
}
}
- I made a new mapping model that uses the original no-UUID model as the source and the newer with-UUID model as the destination. For my sample entity
Event
, I configured the mapping model to use the code above like this. The app name here is CDTest
:

- For the new property I made the entry in the mapping model look like this:

The migration worked. If yours still doesn't, try turning on migration debug logging. You can do this by editing the scheme and adding this to the "arguments" section:

When Core Data attempts to migrate, you'll see a lot of messages in Xcode's console about what's happening. (If no migration is needed, you'll see no messages from Core Data at all).
When migration works, it prints a bunch of messages about Incompatible version schema for persistent store
and version hashes, and then eventually a message that says found compatible mapping model
, and then the migration happens.
If you don't see that then Core Data couldn't match your mapping model to the model versions. That might mean that you edited the model after you created the mapping model. If that's true then you need to delete the mapping and re-create it. Another symptom of this is if the logs say Beginning lightweight migration on connection
anywhere. If it's trying lightweight migration then it couldn't find your mapping, so try the mapping model again.