3

I have a CoreData database working perfectly with my application. The database stores presets, saved by the user. I want to give the user the ability to backup the database using File Sharing via iTunes.

Basically I want to:

  1. Backup: Database -> file the user can transfer between devices

  2. Restore: file -> Database

The most straightforward way I thought of was to simply copy and replace the persistentStore. Like so..

This is how I create the database:

self.database = [[UIManagedDocument alloc] databaseURL]; 
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
    [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { }]; 

}

This is how I replace the persistentStore:

- (void)restoreBackupWithBackupURL:(NSURL *)backupURL {
// close the current document
[self.database closeWithCompletionHandler:^(BOOL success) {        
    // GET PERSISTENT STORE URL
    NSURL *databaseURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    databaseURL = [databaseURL URLByAppendingPathComponent:@"Default Database"];
    databaseURL = [databaseURL URLByAppendingPathComponent:@"StoreContent"];
    databaseURL = [databaseURL URLByAppendingPathComponent:@"persistentStore"];

    // DELETE PERSISTENT STORE
    NSError *error;
    BOOL deleted  = [[NSFileManager defaultManager] removeItemAtURL:databaseURL error:&error];
    if (!deleted) {
        NSLog(@"Error deleting file: %@", error.localizedDescription);
        return;
    }

    // COPY BACKUP PERSISTENT STORE
    BOOL copied = [[NSFileManager defaultManager] copyItemAtURL:backupURL toURL:databaseURL error:&error];
    if (!copied) {
        NSLog(@"Error copying file: %@", error.localizedDescription);
        return;
    }

    // INITIALIZE
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    url = [url URLByAppendingPathComponent:@"Default Database"];

    self.database = [[UIManagedDocument alloc] initWithFileURL:url]; 
}];    

}

I have it working, however, I am unsure if it is a safe and preferred solution (new to core-data). Any input?

Alexander
  • 91
  • 4

1 Answers1

0

That should be OK in general, if your usage is simple enough.

If you use external links for large binary data, you need to copy those files as well.

If you use file packages (or UIManagedDocument) you will need to the entire file package, not just the sql store.

If you are using iCloud, you have some other things to worry about...

Jody Hagins
  • 27,943
  • 6
  • 58
  • 87
  • 1
    Thanks for the reply. File packages cannot be transferred into the App via iTunes File Sharing, so I cannot copy the entire directory. I currently copy and replace only the persistentStore (placing it back in it's proper location in the existing file package (Default Database/StoreContent), and it seems to work fine. Do you think this is ok? If not, and I do need to copy entire file package, why is that the case? – Alexander Aug 03 '12 at 20:18