I have been having quite a time of figuring out the correct way to create a backup of a Core-Data backed .sqlite file and storing that backup, both locally and/or in iCloud (whatever the user prefers), for download, restore or sharing. Let me state up front that I am not talking about moving the persistent store to iCloud to be used by the app as its datasource. I am simply asking about creating backup files in this question.
In 2014, Apple changed their default journaling mode for Core Data SQLite stores to WAL.
https://developer.apple.com/library/content/qa/qa1809/_index.html
With that change, they recommended:
To safely back up and restore a Core Data SQLite store, you can do the following: Use the following method of NSPersistentStoreCoordinator class, rather than file system APIs, to back up and restore the Core Data store: - (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error
Note that this is the option we recommend.
Prior to this, I had been using NSFileManager to create backups. With this recommendation, I believe that the correct way to create a backup locally is to add a new persistent store and then to migrate that persistent store to the desired backup location, using
the NSPersistentStoreCoordinator methods addPersistentStoreWithType:configuration:URL:options:error
, and migratePersistentStore:toURL:options:withType:error
, respectively.
My questions are two-fold:
migratePersistentStore:toURL:options:withType:error
method, I now
end up with a .sqlite file (and its corresponding WAL file, etc) in
the desired location, but I cannot figure out how to share this file
now. If I zip the file, won't I be in danger of losing the data I
worked hard to preserve by using
migratePersistentStore:toURL:options:withType:error
in the first
place? I believe so, but I do want to enable my users to share/save their
backups vie email, etc, and I don't know how to best approach this now.migratePersistentStore:toURL:options:withType:error
can be used to
backup the file to iCloud. Much like the sharing example above, I
see that I can use
addPersistentStoreWithType:configuration:URL:options:error
, and
migratePersistentStore:toURL:options:withType:error
to get the
desired .sqlite copy locally, but if I then try to upload that local
file to iCloud, I fear I will lose the data I worked to preserve by
using migratePersistentStore:toURL:options:withType:error
in the
first place. I have been trying to see if there is a way that I
could/should use
migratePersistentStore:toURL:options:withType:error
to move the
newly created persistentStore directly to iCloud, but I haven't been
able to find any documentation on how to do that or if it should be
done at all. Is there a specific url I would need to use to indicate that the destination for the persistentStore is iCloud?I would greatly appreciate any insights that can be shared regarding the answers to these questions.
You have to be careful though regarding shared CoreData store version. Suppose two users run different versions of the app and share the CoreData store between each other. CoreData doesn't support progressive migrations out of box. https://www.objc.io/issues/4-core-data/core-data-migration/
Maybe sharing a portion of data in JSON and re-creating CoreData entities from it would be safer and easier strategy for sharing data as opposed to sharing entire graph.
setUbiquitous
that allows to move file into iCloud container.