From 36386c321314cbd71b815aea038111f03fa3a761 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sun, 8 Sep 2013 10:42:28 -0400 Subject: [PATCH] iOS 7 cloud loading. --- External/UbiquityStoreManager | 2 +- MasterPassword/ObjC/MPAppDelegate_Store.m | 17 +- .../ObjC/iOS/MPLogsViewController.m | 154 +++++++++--------- .../ObjC/iOS/MPSetupViewController.m | 2 +- MasterPassword/ObjC/iOS/MPiOSAppDelegate.m | 4 +- MasterPassword/ObjC/iOS/MPiOSConfig.m | 2 +- 6 files changed, 91 insertions(+), 90 deletions(-) diff --git a/External/UbiquityStoreManager b/External/UbiquityStoreManager index 5a19df08..a2ce82ea 160000 --- a/External/UbiquityStoreManager +++ b/External/UbiquityStoreManager @@ -1 +1 @@ -Subproject commit 5a19df087f7a694ad6427708f6d23c62ad8999bb +Subproject commit a2ce82ea58d8a02237f33fdc4393259b09cb4967 diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m index 978e73fe..ba473e40 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Store.m +++ b/MasterPassword/ObjC/MPAppDelegate_Store.m @@ -263,9 +263,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, withIntermediateDirectories:YES attributes:nil error:&error]) err(@"While creating directory for new local store: %@", error); - if (![self.storeManager copyMigrateStore:oldLocalStoreURL withOptions:oldLocalStoreOptions - toStore:newLocalStoreURL withOptions:newLocalStoreOptions - error:nil cause:nil context:nil]) { + if (![self.storeManager migrateStore:oldLocalStoreURL withOptions:oldLocalStoreOptions + toStore:newLocalStoreURL withOptions:newLocalStoreOptions + strategy:self.storeManager.migrationStrategy + error:nil cause:nil context:nil]) { self.storeManager.localStoreURL = oldLocalStoreURL; return NO; } @@ -310,13 +311,11 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, if (![[NSFileManager defaultManager] createDirectoryAtPath:[self.storeManager URLForCloudStoreDirectory].path withIntermediateDirectories:YES attributes:nil error:&error]) err(@"While creating directory for new cloud store: %@", error); - if (![[NSFileManager defaultManager] createDirectoryAtPath:[self.storeManager URLForCloudContent].path - withIntermediateDirectories:YES attributes:nil error:&error]) - err(@"While creating directory for new cloud content: %@", error); - if (![self.storeManager copyMigrateStore:oldCloudStoreURL withOptions:oldCloudStoreOptions - toStore:newCloudStoreURL withOptions:newCloudStoreOptions - error:nil cause:nil context:nil]) + if (![self.storeManager migrateStore:oldCloudStoreURL withOptions:oldCloudStoreOptions + toStore:newCloudStoreURL withOptions:newCloudStoreOptions + strategy:self.storeManager.migrationStrategy + error:nil cause:nil context:nil]) return NO; inf(@"Successfully migrated to new cloud store."); diff --git a/MasterPassword/ObjC/iOS/MPLogsViewController.m b/MasterPassword/ObjC/iOS/MPLogsViewController.m index 7a2beb93..82c1f301 100644 --- a/MasterPassword/ObjC/iOS/MPLogsViewController.m +++ b/MasterPassword/ObjC/iOS/MPLogsViewController.m @@ -74,83 +74,83 @@ - (void)switchCloudStore { - NSError *error = nil; - NSURL *cloudStoreDirectory = [[MPiOSAppDelegate get].storeManager URLForCloudStoreDirectory]; - NSURL *cloudContentDirectory = [[MPiOSAppDelegate get].storeManager URLForCloudContentDirectory]; - NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:cloudContentDirectory includingPropertiesForKeys:nil - options:NSDirectoryEnumerationSkipsHiddenFiles error:&error]; - if (!contents) - err(@"While enumerating cloud contents: %@", error); - - BOOL directory; - NSMutableDictionary *stores = [NSMutableDictionary dictionaryWithCapacity:[contents count]]; - NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil]; - NSPersistentStoreCoordinator *storePSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; - NSFetchRequest *usersFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )]; - NSFetchRequest *sitesFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; - for (NSURL *content in contents) - if ([[NSFileManager defaultManager] fileExistsAtPath:content.path isDirectory:&directory] && directory) { - NSString *contentString = [content lastPathComponent]; - NSUInteger firstDash = [contentString rangeOfString:@"-" options:0].location; - NSString *storeDescription = firstDash == NSNotFound? contentString: [contentString substringToIndex:firstDash]; - NSPersistentStore *store = nil; - @try { - NSURL *storeURL = [[cloudStoreDirectory - URLByAppendingPathComponent:[content lastPathComponent] isDirectory:NO] - URLByAppendingPathExtension:@"sqlite"]; - if (!(store = [storePSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil - URL:storeURL options:@{ - NSPersistentStoreUbiquitousContentNameKey : [[MPiOSAppDelegate get].storeManager valueForKey:@"contentName"], - NSPersistentStoreUbiquitousContentURLKey : content, - NSMigratePersistentStoresAutomaticallyOption : @YES, - NSInferMappingModelAutomaticallyOption : @YES, - NSPersistentStoreFileProtectionKey : NSFileProtectionComplete - } error:&error])) { - wrn(@"Couldn't describe store opening %@: %@", [content lastPathComponent], error); - continue; - } - - NSUInteger userCount, siteCount; - NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; - moc.persistentStoreCoordinator = storePSC; - if ((userCount = [moc countForFetchRequest:usersFetchRequest error:&error]) == NSNotFound) { - wrn(@"Couldn't describe store userCount %@: %@", [content lastPathComponent], error); - continue; - } - if ((siteCount = [moc countForFetchRequest:sitesFetchRequest error:&error]) == NSNotFound) { - wrn(@"Couldn't describe store siteCount %@: %@", [content lastPathComponent], error); - continue; - } - - storeDescription = PearlString( @"%@: %dU, %dS", storeDescription, userCount, siteCount ); - } - @catch (NSException *exception) { - wrn(@"Couldn't describe store %@: exception %@", [content lastPathComponent], exception); - } - @finally { - if (store) if (![storePSC removePersistentStore:store error:&error]) - wrn(@"Couldn't remove store %@: %@", [content lastPathComponent], error); - [stores setObject:storeDescription forKey:[content lastPathComponent]]; - } - } - - NSString *storeUUID = [[MPiOSAppDelegate get].storeManager valueForKey:@"storeUUID_ThreadSafe"]; - NSUInteger firstDash = [storeUUID rangeOfString:@"-" options:0].location; - PearlArrayTVC *vc = [[PearlArrayTVC alloc] initWithStyle:UITableViewStylePlain]; - vc.title = PearlString( @"Current: %@", firstDash == NSNotFound? storeUUID: [storeUUID substringToIndex:firstDash] ); - [stores enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - [vc addRowWithName:obj style:PearlArrayTVCRowStyleLink toggled:NO toSection:@"Cloud Stores" - activationBlock:^BOOL(BOOL wasToggled) { - [[MPiOSAppDelegate get].storeManager setValue:key forKey:@"storeUUID"]; - [[MPiOSAppDelegate get].storeManager reloadStore]; - [[MPiOSAppDelegate get] signOutAnimated:YES]; - return YES; - }]; - }]; - dispatch_async( dispatch_get_main_queue(), ^{ - [switchCloudStoreProgress cancelAlertAnimated:YES]; - [self.navigationController pushViewController:vc animated:YES]; - } ); +// NSError *error = nil; +// NSURL *cloudStoreDirectory = [[MPiOSAppDelegate get].storeManager URLForCloudStoreDirectory]; +// NSURL *cloudContentDirectory = [[MPiOSAppDelegate get].storeManager URLForCloudContentDirectory]; +// NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:cloudContentDirectory includingPropertiesForKeys:nil +// options:NSDirectoryEnumerationSkipsHiddenFiles error:&error]; +// if (!contents) +// err(@"While enumerating cloud contents: %@", error); +// +// BOOL directory; +// NSMutableDictionary *stores = [NSMutableDictionary dictionaryWithCapacity:[contents count]]; +// NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil]; +// NSPersistentStoreCoordinator *storePSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; +// NSFetchRequest *usersFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPUserEntity class] )]; +// NSFetchRequest *sitesFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; +// for (NSURL *content in contents) +// if ([[NSFileManager defaultManager] fileExistsAtPath:content.path isDirectory:&directory] && directory) { +// NSString *contentString = [content lastPathComponent]; +// NSUInteger firstDash = [contentString rangeOfString:@"-" options:0].location; +// NSString *storeDescription = firstDash == NSNotFound? contentString: [contentString substringToIndex:firstDash]; +// NSPersistentStore *store = nil; +// @try { +// NSURL *storeURL = [[cloudStoreDirectory +// URLByAppendingPathComponent:[content lastPathComponent] isDirectory:NO] +// URLByAppendingPathExtension:@"sqlite"]; +// if (!(store = [storePSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil +// URL:storeURL options:@{ +// NSPersistentStoreUbiquitousContentNameKey : [[MPiOSAppDelegate get].storeManager valueForKey:@"contentName"], +// NSPersistentStoreUbiquitousContentURLKey : content, +// NSMigratePersistentStoresAutomaticallyOption : @YES, +// NSInferMappingModelAutomaticallyOption : @YES, +// NSPersistentStoreFileProtectionKey : NSFileProtectionComplete +// } error:&error])) { +// wrn(@"Couldn't describe store opening %@: %@", [content lastPathComponent], error); +// continue; +// } +// +// NSUInteger userCount, siteCount; +// NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; +// moc.persistentStoreCoordinator = storePSC; +// if ((userCount = [moc countForFetchRequest:usersFetchRequest error:&error]) == NSNotFound) { +// wrn(@"Couldn't describe store userCount %@: %@", [content lastPathComponent], error); +// continue; +// } +// if ((siteCount = [moc countForFetchRequest:sitesFetchRequest error:&error]) == NSNotFound) { +// wrn(@"Couldn't describe store siteCount %@: %@", [content lastPathComponent], error); +// continue; +// } +// +// storeDescription = PearlString( @"%@: %dU, %dS", storeDescription, userCount, siteCount ); +// } +// @catch (NSException *exception) { +// wrn(@"Couldn't describe store %@: exception %@", [content lastPathComponent], exception); +// } +// @finally { +// if (store) if (![storePSC removePersistentStore:store error:&error]) +// wrn(@"Couldn't remove store %@: %@", [content lastPathComponent], error); +// [stores setObject:storeDescription forKey:[content lastPathComponent]]; +// } +// } +// +// NSString *storeUUID = [[MPiOSAppDelegate get].storeManager valueForKey:@"storeUUID_ThreadSafe"]; +// NSUInteger firstDash = [storeUUID rangeOfString:@"-" options:0].location; +// PearlArrayTVC *vc = [[PearlArrayTVC alloc] initWithStyle:UITableViewStylePlain]; +// vc.title = PearlString( @"Current: %@", firstDash == NSNotFound? storeUUID: [storeUUID substringToIndex:firstDash] ); +// [stores enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { +// [vc addRowWithName:obj style:PearlArrayTVCRowStyleLink toggled:NO toSection:@"Cloud Stores" +// activationBlock:^BOOL(BOOL wasToggled) { +// [[MPiOSAppDelegate get].storeManager setValue:key forKey:@"storeUUID"]; +// [[MPiOSAppDelegate get].storeManager reloadStore]; +// [[MPiOSAppDelegate get] signOutAnimated:YES]; +// return YES; +// }]; +// }]; +// dispatch_async( dispatch_get_main_queue(), ^{ +// [switchCloudStoreProgress cancelAlertAnimated:YES]; +// [self.navigationController pushViewController:vc animated:YES]; +// } ); } - (IBAction)toggleLevelControl:(UISegmentedControl *)sender { diff --git a/MasterPassword/ObjC/iOS/MPSetupViewController.m b/MasterPassword/ObjC/iOS/MPSetupViewController.m index 32c9d753..34495bba 100644 --- a/MasterPassword/ObjC/iOS/MPSetupViewController.m +++ b/MasterPassword/ObjC/iOS/MPSetupViewController.m @@ -31,7 +31,7 @@ [super viewDidAppear:animated]; if (self.cloudSwitch && [[MPiOSConfig get].iCloudDecided boolValue]) - self.cloudSwitch.on = [MPiOSAppDelegate get].storeManager.cloudEnabled; + self.cloudSwitch.on = [[MPiOSConfig get].iCloudEnabled boolValue]; if (self.rememberLoginSwitch) self.rememberLoginSwitch.on = [[MPiOSConfig get].rememberLogin boolValue]; } diff --git a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m index 41605719..c972db55 100644 --- a/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m +++ b/MasterPassword/ObjC/iOS/MPiOSAppDelegate.m @@ -593,7 +593,9 @@ - (void)checkConfig { // iCloud enabled / disabled - if ([[MPiOSConfig get].iCloudEnabled boolValue] != self.storeManager.cloudEnabled) { + BOOL iCloudEnabled = [[MPiOSConfig get].iCloudEnabled boolValue]; + BOOL cloudEnabled = self.storeManager.cloudEnabled; + if (iCloudEnabled != cloudEnabled) { if ([[MPiOSConfig get].iCloudEnabled boolValue]) [self.storeManager setCloudEnabledAndOverwriteCloudWithLocalIfConfirmed:^(void (^setConfirmationAnswer)(BOOL answer)) { [PearlAlert showAlertWithTitle:@"Keep Sites?" diff --git a/MasterPassword/ObjC/iOS/MPiOSConfig.m b/MasterPassword/ObjC/iOS/MPiOSConfig.m index 9fc01315..7234b221 100644 --- a/MasterPassword/ObjC/iOS/MPiOSConfig.m +++ b/MasterPassword/ObjC/iOS/MPiOSConfig.m @@ -24,7 +24,7 @@ NSStringFromSelector( @selector(typeTipShown) ) : @(!self.firstRun), NSStringFromSelector( @selector(loginNameTipShown) ) : @NO, NSStringFromSelector( @selector(traceMode) ) : @NO, - NSStringFromSelector( @selector(iCloudEnabled) ) : @YES + NSStringFromSelector( @selector(iCloudEnabled) ) : @NO }]; return self;