Backup core data locally, and restore from backup - Swift

孤街醉人 提交于 2020-01-10 06:49:07

问题


I'm struggling to find any information about creating backups of core data. My ultimate goal is to allow the user to create multiple backups, and restore from a selected backup.

I've found a sample project that allows you backup/restore locally or via iCloud in Objective-C, but nothing in swift.

Can anyone help? Or point me in the right direction. I don't even know where to start with this one.


回答1:


I've never needed to do this but if I did this is what I'd do.

To make backups

At any time, use the following steps:

  1. Create a new, second Core Data stack. Use either NSPersistentContainer or the older (but still supported) method of creating an NSPersistentStoreCoordinator.
  2. Use NSPersistentStoreCoordinator's function migratePersistentStore(_:to:options:withType:) to create the backup. Make the destination URL include something unique, using a UUID or a timestamp. Put the backups in the documents folder.
  3. Keep a list of backups by date. You could put this in UserDefaults or create a new property list file to save backup info.

Step #2 will remove the original store from the Core Data stack-- which is why you create a second stack in step #1. This way you can use the second stack to make the backup without affecting the one your app is using.

If you're using NSPersistentContainer, use its persistentStoreCoordinator property to carry out step #2.

To restore from backups

This is a little bit tricky because your app may be using its persistent store, but now you want to replace that with an older version. Before restoring from a backup, make sure you're not currently using any managed objects from the persistent store. Deallocate your NSPersistentContainer. Unload any UI that makes use of managed objects. Get your app into a state where all it can do is either restore from a backup or go back to using the current data, but where it's not showing any data except the backup list.

Now that you've done that,

  1. Display the backup list and let the user select one.
  2. Create an NSPersistentStoreCoordinator using your data model.
  3. Use the replacePersistentStore(at:destinationOptions:withPersistentStoreFrom:sourceOptions:ofType:) method to copy the backup data to the normal app location. The starting location is the backup location, the destination is where the app normally saves its data.
  4. (optional) Use NSPersistentStoreCoordinator's function destroyPersistentStore(at:ofType:options:) to delete the backup.
  5. Load an NSPersistentContainer as usual and reload the regular app UI.

Don't use direct file-related APIs like FileManager for any of this. The Core Data methods will cover all of the Core Data-related files and do other nice things like avoid causing data corruption and respecting file locks.




回答2:


Just my two cents for more valuable thoughts: to tackle the problem, I would try to use CloudKit to create different customer zones to store different backups in the App user’s private database in iCloud from core data.




回答3:


I created the following method with the help of Tom's answer and the Apple sample code. This will take a backup of core data files and place it to the path that you want.

Swift 5

    /// Backing up store type to a new and unique location
    /// The method is illustrated in the following code fragment, which shows how you can use migratePersistentStore to take a back up of a store and save it from one location to another.
    /// If the old store type is XML, the example also converts the store to SQLite.
    /// - Parameters:
    ///   - path: Where you want the backup to be done, please create a new unique directory with timestamp or the guid
    ///   - completion: Passes error in case of error or pass nil in case of success
     class func backUpCoreDataFiles(path : URL, completion : @escaping (_ error : String?) -> ())
        {

            // Every time new container is a must as migratePersistentStore method will loose the reference to the container on migration
            let container = NSPersistentContainer(name : "<YourDataModelName>")
            container.loadPersistentStores
                { (storeDescription, error) in
                    if let error = error
                    {
                        fatalError("Failed to load store: \(error)")
                    }
            }
            let coordinator = container.persistentStoreCoordinator
            let store = coordinator.persistentStores[0]
            do
            {
                try coordinator.migratePersistentStore(store, to : path, options : nil, withType : NSSQLiteStoreType)
                completion(nil)
            }
            catch
            {
                completion("\(Errors.coredataBackupError)\(error.localizedDescription)")
            }
        }


来源:https://stackoverflow.com/questions/48613271/backup-core-data-locally-and-restore-from-backup-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!