Skip to content

Commit fd60b4c

Browse files
committed
Change from migratePersistentStore to replacePersistentStore
1 parent e8b2deb commit fd60b4c

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

CDMoveDemo/NSPersistentContainer+extension.swift

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,24 @@ extension NSPersistentContainer {
3838
throw CopyPersistentStoreErrors.invalidSource("Source URL must exist")
3939
}
4040

41-
for persistentStore in persistentStoreCoordinator.persistentStores {
42-
guard let loadedStoreURL = persistentStore.url else {
41+
for persistentStoreDescription in persistentStoreDescriptions {
42+
guard let loadedStoreURL = persistentStoreDescription.url else {
4343
continue
4444
}
4545
let backupStoreURL = backupURL.appendingPathComponent(loadedStoreURL.lastPathComponent)
4646
guard FileManager.default.fileExists(atPath: backupStoreURL.path) else {
4747
throw CopyPersistentStoreErrors.invalidSource("Missing backup store for \(backupStoreURL)")
4848
}
4949
do {
50-
// Remove the existing persistent store first
51-
try persistentStoreCoordinator.remove(persistentStore)
52-
} catch {
53-
print("Error removing store: \(error)")
54-
throw CopyPersistentStoreErrors.copyStoreError("Could not remove persistent store before restore")
55-
}
56-
do {
57-
// Clear out the existing persistent store so that we'll have a clean slate for restoring.
58-
try persistentStoreCoordinator.destroyPersistentStore(at: loadedStoreURL, ofType: persistentStore.type, options: persistentStore.options)
59-
// Add the backup store at its current location
60-
let backupStore = try persistentStoreCoordinator.addPersistentStore(ofType: persistentStore.type, configurationName: persistentStore.configurationName, at: backupStoreURL, options: persistentStore.options)
61-
// Migrate the backup store to the non-backup location. This leaves the backup copy in place in case it's needed in the future, but backupStore won't be useful anymore.
62-
let restoredTemporaryStore = try persistentStoreCoordinator.migratePersistentStore(backupStore, to: loadedStoreURL, options: persistentStore.options, withType: persistentStore.type)
63-
print("Restored temp store: \(restoredTemporaryStore)")
50+
let storeOptions = persistentStoreDescription.options
51+
let configurationName = persistentStoreDescription.configuration
52+
let storeType = persistentStoreDescription.type
53+
54+
// Replace the current store with the backup copy. This has a side effect of removing the current store from the Core Data stack.
55+
// When restoring, it's necessary to use the current persistent store coordinator.
56+
try persistentStoreCoordinator.replacePersistentStore(at: loadedStoreURL, destinationOptions: storeOptions, withPersistentStoreFrom: backupStoreURL, sourceOptions: storeOptions, ofType: storeType)
57+
// Add the persistent store at the same location we've been using, because it was removed in the previous step.
58+
try persistentStoreCoordinator.addPersistentStore(ofType: storeType, configurationName: configurationName, at: loadedStoreURL, options: storeOptions)
6459
} catch {
6560
throw CopyPersistentStoreErrors.copyStoreError("Could not restore: \(error.localizedDescription)")
6661
}
@@ -102,24 +97,24 @@ extension NSPersistentContainer {
10297
throw CopyPersistentStoreErrors.destinationError("Could not create destination directory at \(destinationURL)")
10398
}
10499

105-
106100
for persistentStoreDescription in persistentStoreDescriptions {
107101
guard let storeURL = persistentStoreDescription.url else {
108102
continue
109103
}
110104
guard persistentStoreDescription.type != NSInMemoryStoreType else {
111105
continue
112106
}
113-
let temporaryPSC = NSPersistentStoreCoordinator(managedObjectModel: persistentStoreCoordinator.managedObjectModel)
114107
let destinationStoreURL = destinationURL.appendingPathComponent(storeURL.lastPathComponent)
115108

116109
if !overwriting && FileManager.default.fileExists(atPath: destinationStoreURL.path) {
117-
// If the destination exists, the migratePersistentStore call will update it in place. That's fine unless we're not overwriting.
110+
// If the destination exists, the replacePersistentStore call will update it in place. That's fine unless we're not overwriting.
118111
throw CopyPersistentStoreErrors.destinationError("Destination already exists at \(destinationStoreURL)")
119112
}
120113
do {
121-
let newStore = try temporaryPSC.addPersistentStore(ofType: persistentStoreDescription.type, configurationName: persistentStoreDescription.configuration, at: persistentStoreDescription.url, options: persistentStoreDescription.options)
122-
let _ = try temporaryPSC.migratePersistentStore(newStore, to: destinationStoreURL, options: persistentStoreDescription.options, withType: persistentStoreDescription.type)
114+
// Replace an existing backup, if any, with a new one with the same options and type. This doesn't affect the current Core Data stack.
115+
// The function name says "replace", but it works if there's nothing at the destination yet. In that case it creates a new persistent store.
116+
// Note that for backup, it doesn't matter if the persistent store coordinator is the one currently in use or a different one. It could be a class function, for this use.
117+
try persistentStoreCoordinator.replacePersistentStore(at: destinationStoreURL, destinationOptions: persistentStoreDescription.options, withPersistentStoreFrom: storeURL, sourceOptions: persistentStoreDescription.options, ofType: persistentStoreDescription.type)
123118
} catch {
124119
throw CopyPersistentStoreErrors.copyStoreError("\(error.localizedDescription)")
125120
}

0 commit comments

Comments
 (0)