Replacing vs. Migrating Core Data Stores
Additionally you should almost never use
NSPersistentStoreCoordinator
’smigratePersistentStore
method but instead use the newerreplacePersistentStoreAtURL
. (you can replace emptiness to make a copy). The former loads the store into memory so you can do fairly radical things like write it out as a different store type. It pre-dates iOS. The latter will perform an APFS clone where possible.
[This] method is almost totally undocumented, so you’re on your own working out how to use it. The dev forums post mentioned above is from summer 2020. The
replacePersistentStore(...)
method was introduced five years earlier in iOS 9, but the forum post was the first time most of the information appeared.[This] is the first suggestion I’ve seen that
migratePersistentStore(...)
might not be a good idea anymore. It’s not deprecated and I haven’t seen any previous source recommending against its use.
There are some comments in the header.
Incidentally you won’t find this if you’re using Swift and ⌘-click on the function name. You need to find the Objective-C header. One way to do this in Xcode is to press ⌘-shift-O and start typing the class name.
[…]
Its declaration says it can throw. I tried intentionally causing some errors but it never threw. For example, what if
sourceURL
points to a nonexistent file? That seems like it would throw, especially since the function doesn’t return anything to indicate success or failure. It doesn’t throw, although there’s a console message readingRestore error: invalidSource("Source URL must exist")
.
He’s figured out a lot, though other important details like the APFS support remain a mystery.
The demo app I’ve been using is now on GitHub. You can take a look here. Or go directly to the diff of replacing
migrate
withreplace
here.[…]
The backup process is simpler than it used to be, because
replace
doesn’t have the same side-effect thatmigrate
did of unloading the persistent store.[…]
Even though the
migrate
andreplace
methods seem pretty similar, the semantics are slightly different when the destination is a currently-loaded store. My new restore code reflects that.
Previously: