iosswiftcore-datanspersistentstore

Restore Core Data


I've managed to create a local backup of my PersistentStore using the following code:

func backup(){
    let backUpFolderUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!
    let backupUrl = backUpFolderUrl.appendingPathComponent("backup")
    let container = NSPersistentContainer(name: "MyApp")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in })

    let store:NSPersistentStore
    store = container.persistentStoreCoordinator.persistentStores.last!
    do {
        try container.persistentStoreCoordinator.migratePersistentStore(store,
                                                                        to: backupUrl,
                                                                        options: nil,
                                                                        withType: NSSQLiteStoreType)
    } catch {
        print("Failed to migrate")
    }
}

This seems to work. The backup files are created. This answer: Backup core data locally, and restore from backup - Swift Suggests I need to deallocate my NSPersistentContainer and then use replacePersistentStore(at:destinationOptions:withPersistentStoreFrom:sourceOptions:ofType:) to restore my backup. So I tried like this:

func restoreFromStore(){
    let storeFolderUrl = FileManager.default.urls(for: .applicationSupportDirectory, in:.userDomainMask).first!
    let storeUrl = storeFolderUrl.appendingPathComponent("MyApp")
    let backUpFolderUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!
    let backupUrl = backUpFolderUrl.appendingPathComponent("backup")

    let container = NSPersistentContainer(name: "MyApp")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in })

    let stores = container.persistentStoreCoordinator.persistentStores

    for store in stores {
        do {
            try container.deall
        } catch {
            print("Couldnt clear store")
        }
    }

    do{
        try
            container.persistentStoreCoordinator.replacePersistentStore(at: storeUrl,
                                                                        destinationOptions: nil,
                                                                        withPersistentStoreFrom: backupUrl,
                                                                        sourceOptions: nil,
                                                                        ofType: NSSQLiteStoreType)
    } catch {
        print("Failed to restore")
    }
}

This doesn’t seem to do anything. I don’t get any errors or warnings but it also doesn’t seem to restore my core data at the point I backed it up.

Sorry, I know this is probably awful code. I actually achieved the result I wanted using entirely FileManager but it seemed to make my console really angry. I wanted to do it properly, without any warnings.


Solution

  • It’s hard to be certain, but a likely cause is

    You probably need to move your restore code inside the completion block that loadPersistentStores uses, so that you can be sure the loading has finished.