LateNate
LateNate

Reputation: 891

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.

Upvotes: 1

Views: 969

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70936

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

  • loadPersistentStores is an async operation, which is why it has a completion block

  • You’re attempting to restore immediately after calling that method instead of waiting for it to finish.

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.

Upvotes: 3

Related Questions