Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // SettingsViewController+BackupRestore.m
- // SalonBook
- //
- // Created by Rolf Marsh on 1/18/15.
- // Copyright (c) 2015 Prager, Software. All rights reserved.
- //
- #import "SettingsViewController+BackupRestore.h"
- @implementation SettingsViewController (BackupRestore)
- NSURL *sqliteStoreURL;
- NSURL *backupFileURL;
- //NSManagedObjectModel *managedObjectModel;
- NSManagedObjectModel *_managedObjectModel;
- //NSManagedObjectContext *managedObjectContext;
- NSManagedObjectContext *_managedObjectContext;
- NSPersistentStoreCoordinator *persistentStoreCoordinator;
- NSPersistentStoreCoordinator *_persistentStoreCoordinator;
- NSDictionary *localStoreOptions;
- //BOOL isOpening;
- //BOOL userICloudChoice = NO;
- BOOL _import_or_save;
- BOOL _storesChanging;
- BOOL _job_counter;
- //BOOL _use_old_model;
- NSString* const OSStoreChangeNotification = @"OSCoreDataStoreChanged";
- #pragma mark - backupLocalStore
- - (NSURL *)backupLocalStore {
- NSError *error;
- // create documentsDirectoryURL
- NSURL *documentsDirectory = [[[NSFileManager defaultManager]
- URLsForDirectory:NSDocumentDirectory
- inDomains:NSUserDomainMask]
- lastObject];
- // create storeURL
- sqliteStoreURL = [documentsDirectory URLByAppendingPathComponent:@"saori.sqlite"];
- // create backupFileURL
- NSDateFormatter *dateFormatter = [NSDateFormatter new];
- dateFormatter.dateFormat = @"yyyymmddHHmmss";
- NSString *localDateString = [dateFormatter stringFromDate:[NSDate date]];
- backupFileURL = [documentsDirectory URLByAppendingPathComponent:[NSString stringWithFormat: @"saori.backup-%@",localDateString]];
- // create managedObjectModel and a PersistentStoreCoordinator
- NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"salonbook" ofType:@"momd"];
- NSURL *modelURL = [NSURL fileURLWithPath: modelPath];
- NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL];
- persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel];
- // Open the store
- localStoreOptions = @{NSSQLitePragmasOption:@{@"journal_mode":@"WAL"}};
- id sourceStore = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
- configuration:nil
- URL: sqliteStoreURL
- options: localStoreOptions
- error:&error];
- if(!sourceStore) { // if persistentStoreCoordinator was NOT created...
- NSLog(@"\n\nfailed to add old store");
- persistentStoreCoordinator = nil;
- return nil;
- }
- else {
- NSLog(@"\n\nSuccessfully added store to migrate; About to migrate the store... ");
- id successfulBackup = [persistentStoreCoordinator migratePersistentStore:sourceStore
- toURL:backupFileURL
- options:localStoreOptions
- withType:NSSQLiteStoreType
- error: &error]; // was &error
- if (successfulBackup) {
- // check for both files
- NSFileManager *fm = [[NSFileManager alloc] init];
- if( [fm fileExistsAtPath:[sqliteStoreURL path]])
- NSLog(@"\n\nsqliteStore exists");
- else
- NSLog(@"\n\nsqliteStore does NOT exist");
- if( [fm fileExistsAtPath:[backupFileURL path]])
- NSLog(@"\n\nbackupFileURL exists");
- else
- NSLog(@"\n\nbackupFile does NOT exist");
- NSLog(@"\n\nstore successfully backed up to %@",backupFileURL);
- // change file permissions (r+w)
- persistentStoreCoordinator = nil;
- // now, store it in NSUserDefaults
- NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
- NSMutableDictionary *preferencesDict = [[userDefaults dictionaryForKey:@"preferencesDictionary"] mutableCopy];
- [preferencesDict setObject: [backupFileURL absoluteString] forKey:@"backupURL"];
- [userDefaults setObject: preferencesDict forKey:@"preferencesDictionary"];
- [userDefaults synchronize];
- return backupFileURL;
- }
- else {
- NSLog(@"\n\nFailed to backup store: %@, %@", error, error.userInfo);
- persistentStoreCoordinator = nil;
- return nil;
- }
- }
- persistentStoreCoordinator = nil;
- return nil;
- }
- #pragma mark - restoreFile
- - (BOOL)restoreBackupFile:(NSURL *)backupFileURL { // @param fileURL: The URL for the file to use.
- NSError *error;
- NSURL *documentsDirectory = [[[NSFileManager defaultManager]
- URLsForDirectory:NSDocumentDirectory
- inDomains:NSUserDomainMask]
- lastObject];
- NSURL *currentCoreDataURL = [documentsDirectory URLByAppendingPathComponent:@"saori.sqlite"];
- NSLog(@"\n\n currentURL is %@", currentCoreDataURL); // current URL of saori.sqlite
- NSLog(@"\n\nbackup file URL to use is %@", backupFileURL); // backup file URL
- // Close the current store and delete it
- _persistentStoreCoordinator = nil;
- _managedObjectContext = nil;
- error = nil;
- NSFileManager *fm = [[NSFileManager alloc] init];
- #pragma mark - TODO **
- // check for both files
- if( [fm fileExistsAtPath:[currentCoreDataURL path]])
- NSLog(@"\n\ncurrentCoreData exists");
- else
- NSLog(@"\n\n-->currentCoreData does NOT exist");
- if( [fm fileExistsAtPath:[backupFileURL path]])
- NSLog(@"\n\nbackupFile exists");
- else {
- NSLog(@"\n\n-->backupFile does NOT exist"); // find out why (and automatically do a backup????) displayAlert
- return NO;
- }
- // Delete the current store file
- if ([fm fileExistsAtPath:[currentCoreDataURL path]]) {
- NSLog(@"\n\ntarget file exists");
- if (![fm removeItemAtURL:currentCoreDataURL error:&error]) { // if the current file is not there...
- NSLog(@"\n\nError unable to remove current store file");
- NSLog(@"Error removing item Error: %@, %@", error, error.userInfo);
- return FALSE;
- }
- else {
- NSLog(@" current store file removed");
- }
- }
- #pragma mark - TODO **
- BOOL copySuccess = [fm copyItemAtPath:[backupFileURL path] //simply copy the file
- toPath:[currentCoreDataURL path]
- error:&error];
- if (copySuccess) {
- NSLog(@" replaced current store file successfully"); // set msg under buttons TODO **
- [self openPersistentStore]; // Now open the store again
- return TRUE;
- }
- else {
- NSLog(@"Error copying items Error: %@, %@", error, error.userInfo); // change this to alertView
- return FALSE;
- }
- }
- #pragma mark - openPersistentStore
- - (void) openPersistentStore {
- // isOpening = YES;
- NSError *error = nil;
- NSPersistentStoreCoordinator *aPersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
- NSLog(@" store Options are %@", localStoreOptions);
- // [self registerForStoreChanges: aPersistentStoreCoordinator];
- // NSLog(@" addPersistentStoreWithType about to be called... ");
- // sleep(1); // wait a second...
- if (![aPersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL: sqliteStoreURL options: localStoreOptions error:&error]) {
- NSLog(@" addPersistentStoreWithType failed... ");
- NSLog(@" error %@, %@", error, [error userInfo]);
- return ;
- }
- NSLog(@" addPersistentStoreWithType completed successfully... ");
- _persistentStoreCoordinator = aPersistentStoreCoordinator;
- NSURL *url = [[[_persistentStoreCoordinator persistentStores] objectAtIndex:0] valueForKey:@"URL"];
- NSLog(@" STORE FILE is %@", [url path]);
- // isOpening = NO;
- }
- #pragma mark - persistentStoreCoordinator
- // Returns the persistent store coordinator for the application.
- // If the coordinator doesn't already exist, it is created and the application's store added to it.
- - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
- if (_persistentStoreCoordinator != nil) {
- return _persistentStoreCoordinator;
- }
- return _persistentStoreCoordinator;
- NSError *error = nil;
- _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
- if (sqliteStoreURL == nil) {
- NSLog(@" error storeURL is nil!");
- return nil;
- }
- NSLog(@" addPersistentStoreWithType about to be called... ");
- if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL: sqliteStoreURL options: localStoreOptions error:&error]) {
- /*
- Replace this implementation with code to handle the error appropriately.
- abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
- Typical reasons for an error here include:
- * The persistent store is not accessible;
- * The schema for the persistent store is incompatible with current managed object model.
- Check the error message to determine what the actual problem was.
- If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
- If you encounter schema incompatibility errors during development, you can reduce their frequency by:
- * Simply deleting the existing store:
- [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
- * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
- @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
- Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
- */
- NSLog(@" addPersistentStoreWithType failed... ");
- NSLog(@" error %@, %@", error, [error userInfo]);
- return nil;
- }
- NSLog(@" addPersistentStoreWithType completed successfully... ");
- [self registerForStoreChanges:_persistentStoreCoordinator];
- return _persistentStoreCoordinator;
- }
- #pragma mark - storesDidSave
- // NB - this may be called from a background thread so make sure we run on the main thread !!
- // This is when transaction logs are loaded
- - (void)storesDidSave:(NSNotification*)notification {
- // Ignore any notifications from the main thread because we only need to merge data
- // loaded from other threads.
- if ([NSThread isMainThread]) {
- NSLog(@" main thread saved context");
- return;
- }
- [[NSOperationQueue mainQueue] addOperationWithBlock:^ {
- NSLog(@"storesDidSave ");
- // Set this so that after the timer goes off we perform a save
- // - without this the deletes don't appear to trigger the fetchedResultsController delegate methods !
- _import_or_save = YES;
- // [self createTimer];
- if (self.managedObjectContext) {
- [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
- }
- }];
- }
- #pragma mark - managedObjectContext
- // Returns the managed object context for the application.
- // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- - (NSManagedObjectContext *)managedObjectContext {
- // defaultContext = [NSManagedObjectContext MR_defaultContext]; // set default NSManagedObjectContext for MagicalRecord (from AppDelegate.m)
- // if (_managedObjectContext != nil) {
- // return _managedObjectContext;
- // }
- if(defaultContext != nil)
- return defaultContext;
- NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
- if (coordinator != nil) {
- // _managedObjectContext = [[NSManagedObjectContext alloc] init];
- // Register for saves in order to merge any data from background threads
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(storesDidSave:) name: NSManagedObjectContextDidSaveNotification object: defaultContext];
- [_managedObjectContext setPersistentStoreCoordinator:coordinator];
- }
- return _managedObjectContext; // is nil? <-------------
- }
- //#pragma mark - saveContext
- //- (void)saveContext
- //{
- // if (isOpening) {
- // NSLog(@" application is still busy opening!");
- // return;
- // }
- //
- // NSError *error = nil;
- // NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; // ??????????? is this needed?
- // if (managedObjectContext != nil) {
- // if ([managedObjectContext hasChanges]) {
- //
- // if (![managedObjectContext save:&error]) {
- // NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
- //
- // }
- // // else {
- // // // if we are iCloud enabled then show the network indicator because
- // // // we expect to see log files uploaded after this
- // // if ([isCloudEnabled])
- // // [self showBackgroundTaskActive];
- // // }
- // }
- // }
- //}
- //#pragma mark - showBackgroundTaskActive
- //- (void)showBackgroundTaskActive {
- //
- // _job_counter++;
- //
- // if ([NSThread isMainThread]) {
- // [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
- // } else {
- // dispatch_async(dispatch_get_main_queue(), ^{
- // [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
- // });
- // }
- //}
- //- (void)showBackgroundTaskInactive {
- // //FLOG(@" called");
- // _job_counter--;
- // if (_job_counter < 0) _job_counter = 0;
- // //FLOG(@" _job_counter is %d", _job_counter);
- //
- // if (_job_counter == 0) {
- // if ([NSThread isMainThread]) {
- // [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
- // } else {
- // dispatch_async(dispatch_get_main_queue(), ^{
- // [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
- // });
- // }
- // }
- //}
- #pragma mark - managedObjectModel
- // Returns the managed object model for the application.
- // If the model doesn't already exist, it is created from the application's model.
- - (NSManagedObjectModel *)managedObjectModel {
- if (_managedObjectModel != nil) {
- return _managedObjectModel;
- }
- else {
- NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"salonbook" ofType:@"momd"];
- NSURL *modelURL = [NSURL fileURLWithPath: modelPath];
- _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL];
- return _managedObjectModel;
- }
- }
- //
- //#pragma mark - postStoreChangeNotification
- //- (void)postStoreChangedNotification {
- //
- // dispatch_async(dispatch_get_main_queue(), ^{
- // [[NSNotificationCenter defaultCenter] postNotificationName: OSStoreChangeNotification
- // object:self];
- // });
- //}
- @end
Advertisement
Add Comment
Please, Sign In to add comment