Migration fixes.
[FIXED] Moved migration into the persistence queue by performing it on willLoadStore. [FIXED] Re-enabled cloud after migration. [UPDATED] Allow rebuilding the old cloud store if it got deleted locally.
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
# Xcode IDE
 | 
			
		||||
xcuserdata/
 | 
			
		||||
/DerivedData/
 | 
			
		||||
 | 
			
		||||
# Media
 | 
			
		||||
Press/Background.png
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								External/UbiquityStoreManager
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								External/UbiquityStoreManager
									
									
									
									
										vendored
									
									
								
							 Submodule External/UbiquityStoreManager updated: c392d8df05...f2c303cbba
									
								
							@@ -75,95 +75,128 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
 | 
			
		||||
 | 
			
		||||
- (void)migrateStoreForManager:(UbiquityStoreManager *)storeManager {
 | 
			
		||||
 | 
			
		||||
    NSNumber *cloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
 | 
			
		||||
    if (!cloudEnabled)
 | 
			
		||||
    NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
 | 
			
		||||
    dbg(@"iCloudEnabledKey: %@", oldCloudEnabled);
 | 
			
		||||
    if (!oldCloudEnabled)
 | 
			
		||||
        // No old data to migrate.
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if ([cloudEnabled boolValue]) {
 | 
			
		||||
        if ([storeManager cloudSafeForSeeding]) {
 | 
			
		||||
            NSString *uuid                      = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
 | 
			
		||||
            NSURL    *cloudContainerURL         = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"];
 | 
			
		||||
            NSURL    *newCloudStoreURL          = [storeManager URLForCloudStore];
 | 
			
		||||
            NSURL    *newCloudContentURL        = [storeManager URLForCloudContent];
 | 
			
		||||
            //NSURL  *oldCloudContentURL        = [[cloudContainerURL URLByAppendingPathComponent:@"Data" isDirectory:YES]
 | 
			
		||||
            //                                                        URLByAppendingPathComponent:uuid isDirectory:YES];
 | 
			
		||||
            NSURL    *oldCloudStoreDirectoryURL = [cloudContainerURL URLByAppendingPathComponent:@"Database.nosync" isDirectory:YES];
 | 
			
		||||
            NSURL    *oldCloudStoreURL          = [[oldCloudStoreDirectoryURL URLByAppendingPathComponent:uuid isDirectory:NO]
 | 
			
		||||
                                                                              URLByAppendingPathExtension:@"sqlite"];
 | 
			
		||||
            if (![[NSFileManager defaultManager] fileExistsAtPath:oldCloudStoreURL.path isDirectory:NO]) {
 | 
			
		||||
                // No old store to migrate from, cannot migrate.
 | 
			
		||||
                wrn(@"Cannot migrate cloud store, old store not found at: %@", oldCloudStoreURL.path);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            NSError      *error                = nil;
 | 
			
		||||
            NSDictionary *oldCloudStoreOptions = @{
 | 
			
		||||
             // This is here in an attempt to have iCloud recreate the old store file from
 | 
			
		||||
             // the baseline and transaction logs from the iCloud account.
 | 
			
		||||
             // In my tests however only the baseline was used to recreate the store which then ended up being empty.
 | 
			
		||||
             /*NSPersistentStoreUbiquitousContentNameKey    : uuid,
 | 
			
		||||
             NSPersistentStoreUbiquitousContentURLKey     : oldCloudContentURL,*/
 | 
			
		||||
             // So instead, we'll just open up the old store as read-only, if it exists.
 | 
			
		||||
             NSReadOnlyPersistentStoreOption              : @YES,
 | 
			
		||||
             NSMigratePersistentStoresAutomaticallyOption : @YES,
 | 
			
		||||
             NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
            NSDictionary *newCloudStoreOptions = @{
 | 
			
		||||
             NSPersistentStoreUbiquitousContentNameKey    : [storeManager valueForKey:@"contentName"],
 | 
			
		||||
             NSPersistentStoreUbiquitousContentURLKey     : newCloudContentURL,
 | 
			
		||||
             NSMigratePersistentStoresAutomaticallyOption : @YES,
 | 
			
		||||
             NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
 | 
			
		||||
            // Create the directory to hold the new cloud store.
 | 
			
		||||
            // This is only necessary if we want to try to rebuild the old store.  See comment above about how that failed.
 | 
			
		||||
            //if (![[NSFileManager defaultManager] createDirectoryAtPath:oldCloudStoreDirectoryURL.path
 | 
			
		||||
            //                               withIntermediateDirectories:YES attributes:nil error:&error])
 | 
			
		||||
            //err(@"While creating directory for old cloud store: %@", error);
 | 
			
		||||
            if (![[NSFileManager defaultManager] createDirectoryAtPath:[storeManager URLForCloudStoreDirectory].path
 | 
			
		||||
                                           withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
			
		||||
                err(@"While creating directory for new cloud store: %@", error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            NSManagedObjectModel         *model = [NSManagedObjectModel mergedModelFromBundles:nil];
 | 
			
		||||
            NSPersistentStoreCoordinator *psc   = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
 | 
			
		||||
 | 
			
		||||
            // Open the old cloud store.
 | 
			
		||||
            NSPersistentStore *oldStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:oldCloudStoreURL
 | 
			
		||||
                                                                  options:oldCloudStoreOptions error:&error];
 | 
			
		||||
            if (!oldStore) {
 | 
			
		||||
                err(@"While opening old store for migration %@: %@", oldCloudStoreURL.path, error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Migrate to the new cloud store.
 | 
			
		||||
            if (![psc migratePersistentStore:oldStore toURL:newCloudStoreURL options:newCloudStoreOptions withType:NSSQLiteStoreType
 | 
			
		||||
                                       error:&error]) {
 | 
			
		||||
                err(@"While migrating cloud store from %@ -> %@: %@", oldCloudStoreURL.path, newCloudStoreURL.path, error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Clean-up.
 | 
			
		||||
            if (![psc removePersistentStore:[psc.persistentStores lastObject] error:&error])
 | 
			
		||||
                err(@"While removing the migrated store from the store context: %@", error);
 | 
			
		||||
            if (![[NSFileManager defaultManager] removeItemAtURL:oldCloudStoreURL error:&error])
 | 
			
		||||
                err(@"While deleting the old cloud store: %@", error);
 | 
			
		||||
    if ([oldCloudEnabled boolValue]) {
 | 
			
		||||
        if (![storeManager cloudSafeForSeeding]) {
 | 
			
		||||
            dbg(@"Cloud store already exists, refusing to migrate.");
 | 
			
		||||
            // TODO: Make this final somehow by doing something with iCloudEnabledKey.
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NSString *uuid                      = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
 | 
			
		||||
        NSURL    *cloudContainerURL         = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"HL3Q45LX9N.com.lyndir.lhunath.MasterPassword.shared"];
 | 
			
		||||
        NSURL    *newCloudStoreURL          = [storeManager URLForCloudStore];
 | 
			
		||||
        NSURL    *newCloudContentURL        = [storeManager URLForCloudContent];
 | 
			
		||||
        NSURL    *oldCloudContentURL        = [[cloudContainerURL URLByAppendingPathComponent:@"Data" isDirectory:YES]
 | 
			
		||||
                                                                  URLByAppendingPathComponent:uuid isDirectory:YES];
 | 
			
		||||
        NSURL    *oldCloudStoreDirectoryURL = [cloudContainerURL URLByAppendingPathComponent:@"Database.nosync" isDirectory:YES];
 | 
			
		||||
        NSURL    *oldCloudStoreURL          = [[oldCloudStoreDirectoryURL URLByAppendingPathComponent:uuid isDirectory:NO]
 | 
			
		||||
                                                                          URLByAppendingPathExtension:@"sqlite"];
 | 
			
		||||
        dbg(@"Migrating cloud:\n%@ ->\n%@", oldCloudStoreURL, newCloudStoreURL);
 | 
			
		||||
        if (![[NSFileManager defaultManager] fileExistsAtPath:oldCloudStoreURL.path isDirectory:NO]) {
 | 
			
		||||
            // No old store to migrate from, cannot migrate.
 | 
			
		||||
            wrn(@"Cannot migrate cloud store, old store not found at: %@", oldCloudStoreURL.path);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NSError      *error                = nil;
 | 
			
		||||
        NSDictionary *oldCloudStoreOptions = @{
 | 
			
		||||
         // This is here in an attempt to have iCloud recreate the old store file from
 | 
			
		||||
         // the baseline and transaction logs from the iCloud account.
 | 
			
		||||
         // In my tests however only the baseline was used to recreate the store which then ended up being empty.
 | 
			
		||||
         NSPersistentStoreUbiquitousContentNameKey    : uuid,
 | 
			
		||||
         NSPersistentStoreUbiquitousContentURLKey     : oldCloudContentURL,
 | 
			
		||||
         // So instead, we'll just open up the old store as read-only, if it exists.
 | 
			
		||||
         NSReadOnlyPersistentStoreOption              : @YES,
 | 
			
		||||
         NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
        NSDictionary *newCloudStoreOptions = @{
 | 
			
		||||
         NSPersistentStoreUbiquitousContentNameKey    : [storeManager valueForKey:@"contentName"],
 | 
			
		||||
         NSPersistentStoreUbiquitousContentURLKey     : newCloudContentURL,
 | 
			
		||||
         NSMigratePersistentStoresAutomaticallyOption : @YES,
 | 
			
		||||
         NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
 | 
			
		||||
        // Create the directory to hold the new cloud store.
 | 
			
		||||
        // This is only necessary if we want to try to rebuild the old store.  See comment above about how that failed.
 | 
			
		||||
        if (![[NSFileManager defaultManager] createDirectoryAtPath:oldCloudStoreDirectoryURL.path
 | 
			
		||||
                                       withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
			
		||||
            err(@"While creating directory for old cloud store: %@", error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (![[NSFileManager defaultManager] createDirectoryAtPath:[storeManager URLForCloudStoreDirectory].path
 | 
			
		||||
                                       withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
			
		||||
            err(@"While creating directory for new cloud store: %@", error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NSManagedObjectModel         *model = [NSManagedObjectModel mergedModelFromBundles:nil];
 | 
			
		||||
        NSPersistentStoreCoordinator *psc   = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
 | 
			
		||||
 | 
			
		||||
        // Open the old cloud store.
 | 
			
		||||
        NSPersistentStore *oldStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:oldCloudStoreURL
 | 
			
		||||
                                                              options:oldCloudStoreOptions error:&error];
 | 
			
		||||
        if (!oldStore) {
 | 
			
		||||
            err(@"While opening old store for migration %@: %@", oldCloudStoreURL.path, error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dbg(@"=== Old store ===");
 | 
			
		||||
        for (NSEntityDescription *entity in model.entities) {
 | 
			
		||||
            NSFetchRequest *fetch = [NSFetchRequest new];
 | 
			
		||||
            fetch.entity = entity;
 | 
			
		||||
            NSManagedObjectContext *moc = [NSManagedObjectContext new];
 | 
			
		||||
            moc.persistentStoreCoordinator = psc;
 | 
			
		||||
            dbg(@"%@: %d", entity.name, [[moc executeFetchRequest:fetch error:&error] count]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Migrate to the new cloud store.
 | 
			
		||||
        if (![psc migratePersistentStore:oldStore toURL:newCloudStoreURL options:newCloudStoreOptions withType:NSSQLiteStoreType
 | 
			
		||||
                                   error:&error]) {
 | 
			
		||||
            err(@"While migrating cloud store from %@ -> %@: %@", oldCloudStoreURL.path, newCloudStoreURL.path, error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dbg(@"=== New store ===");
 | 
			
		||||
        for (NSEntityDescription *entity in model.entities) {
 | 
			
		||||
            NSFetchRequest *fetch = [NSFetchRequest new];
 | 
			
		||||
            fetch.entity = entity;
 | 
			
		||||
            NSManagedObjectContext *moc = [NSManagedObjectContext new];
 | 
			
		||||
            moc.persistentStoreCoordinator = psc;
 | 
			
		||||
            dbg(@"%@: %d", entity.name, [[moc executeFetchRequest:fetch error:&error] count]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Clean-up.
 | 
			
		||||
        if (![psc removePersistentStore:[psc.persistentStores lastObject] error:&error])
 | 
			
		||||
            err(@"While removing the migrated store from the store context: %@", error);
 | 
			
		||||
        if (![[NSFileManager defaultManager] removeItemAtURL:oldCloudStoreURL error:&error])
 | 
			
		||||
            err(@"While deleting the old cloud store: %@", error);
 | 
			
		||||
 | 
			
		||||
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:CloudEnabledKey];
 | 
			
		||||
        inf(@"Successfully migrated old to new cloud store.");
 | 
			
		||||
    } else {
 | 
			
		||||
        NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
 | 
			
		||||
                                                                                   inDomains:NSUserDomainMask] lastObject];
 | 
			
		||||
        NSURL *oldLocalStoreURL          = [[applicationFilesDirectory URLByAppendingPathComponent:@"MasterPassword" isDirectory:NO]
 | 
			
		||||
                                                                       URLByAppendingPathExtension:@"sqlite"];
 | 
			
		||||
                URLByAppendingPathExtension:@"sqlite"];
 | 
			
		||||
        NSURL *newLocalStoreURL          = [storeManager URLForLocalStore];
 | 
			
		||||
        dbg(@"Migrating local:\n%@ ->\n%@", oldLocalStoreURL, newLocalStoreURL);
 | 
			
		||||
        if ([[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO] &&
 | 
			
		||||
         ![[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
 | 
			
		||||
            ![[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
 | 
			
		||||
            NSError                      *error    = nil;
 | 
			
		||||
            NSDictionary                 *options  = @{
 | 
			
		||||
             NSMigratePersistentStoresAutomaticallyOption : @YES,
 | 
			
		||||
             NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
            NSDictionary *oldLocalStoreOptions = @{
 | 
			
		||||
                    NSReadOnlyPersistentStoreOption        : @YES,
 | 
			
		||||
                    NSInferMappingModelAutomaticallyOption : @YES
 | 
			
		||||
            };
 | 
			
		||||
            NSDictionary                 *newLocalStoreOptions  = @{
 | 
			
		||||
                    NSMigratePersistentStoresAutomaticallyOption : @YES,
 | 
			
		||||
                    NSInferMappingModelAutomaticallyOption       : @YES};
 | 
			
		||||
            NSManagedObjectModel         *model    = [NSManagedObjectModel mergedModelFromBundles:nil];
 | 
			
		||||
            NSPersistentStoreCoordinator *psc      = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // Create the directory to hold the new local store.
 | 
			
		||||
            if (![[NSFileManager defaultManager] createDirectoryAtPath:[storeManager URLForLocalStoreDirectory].path
 | 
			
		||||
                                           withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
			
		||||
@@ -173,28 +206,30 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
 | 
			
		||||
 | 
			
		||||
            // Open the old local store.
 | 
			
		||||
            NSPersistentStore            *oldStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
 | 
			
		||||
                                                                                 URL:oldLocalStoreURL options:options error:&error];
 | 
			
		||||
                                                                                 URL:oldLocalStoreURL options:oldLocalStoreOptions error:&error];
 | 
			
		||||
            if (!oldStore) {
 | 
			
		||||
                err(@"While opening old store for migration %@: %@", oldLocalStoreURL.path, error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // Migrate to the new local store.
 | 
			
		||||
            if (![psc migratePersistentStore:oldStore toURL:newLocalStoreURL options:options withType:NSSQLiteStoreType error:&error]) {
 | 
			
		||||
            if (![psc migratePersistentStore:oldStore toURL:newLocalStoreURL options:newLocalStoreOptions withType:NSSQLiteStoreType error:&error]) {
 | 
			
		||||
                err(@"While migrating local store from %@ -> %@: %@", oldLocalStoreURL, newLocalStoreURL, error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // Clean-up.
 | 
			
		||||
            if (![psc removePersistentStore:[psc.persistentStores lastObject] error:&error])
 | 
			
		||||
                err(@"While removing the migrated store from the store context: %@", error);
 | 
			
		||||
            err(@"While removing the migrated store from the store context: %@", error);
 | 
			
		||||
 | 
			
		||||
            if (![[NSFileManager defaultManager] removeItemAtURL:oldLocalStoreURL error:&error])
 | 
			
		||||
                err(@"While deleting the old local store: %@", error);
 | 
			
		||||
            err(@"While deleting the old local store: %@", error);
 | 
			
		||||
            inf(@"Successfully migrated old to new local store.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LocalUUIDKey"];
 | 
			
		||||
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"iCloudEnabledKey"];
 | 
			
		||||
    dbg(@"Removed old cloud keys.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (UbiquityStoreManager *)storeManager {
 | 
			
		||||
@@ -214,9 +249,6 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
 | 
			
		||||
#endif
 | 
			
		||||
                                                       delegate:self];
 | 
			
		||||
 | 
			
		||||
    // Migrate old store to new store location.
 | 
			
		||||
    [self migrateStoreForManager:storeManager];
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE
 | 
			
		||||
    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
 | 
			
		||||
                                                      object:[UIApplication sharedApplication] queue:nil
 | 
			
		||||
@@ -270,6 +302,8 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
 | 
			
		||||
 | 
			
		||||
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore {
 | 
			
		||||
 | 
			
		||||
    [self migrateStoreForManager:manager];
 | 
			
		||||
 | 
			
		||||
    dispatch_async(dispatch_get_main_queue(), ^{
 | 
			
		||||
        if (![self.storeLoading isVisible])
 | 
			
		||||
            self.storeLoading = [PearlOverlay showOverlayWithTitle:@"Loading..."];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,10 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "0460"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
   <BuildAction>
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "NO"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            buildForRunning = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
@@ -22,32 +15,9 @@
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
      <Testables>
 | 
			
		||||
      </Testables>
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      buildConfiguration = "AppStore">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
@@ -57,30 +27,5 @@
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
      <AdditionalOptions>
 | 
			
		||||
      </AdditionalOptions>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,10 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "0460"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
   <BuildAction>
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            buildForRunning = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
@@ -22,80 +15,17 @@
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
      <Testables>
 | 
			
		||||
         <TestableReference
 | 
			
		||||
            skipped = "NO">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA3EF17815A47744003ABF4E"
 | 
			
		||||
               BuildableName = "Tests.octest"
 | 
			
		||||
               BlueprintName = "Tests"
 | 
			
		||||
               ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </TestableReference>
 | 
			
		||||
      </Testables>
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
      <AdditionalOptions>
 | 
			
		||||
         <AdditionalOption
 | 
			
		||||
            key = "NSZombieEnabled"
 | 
			
		||||
            value = "YES"
 | 
			
		||||
            isEnabled = "YES">
 | 
			
		||||
         </AdditionalOption>
 | 
			
		||||
      </AdditionalOptions>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "AdHoc"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
 
 | 
			
		||||
@@ -5540,7 +5540,7 @@
 | 
			
		||||
					"$(inherit)",
 | 
			
		||||
					"\"$(SRCROOT)/../../../External\"/**",
 | 
			
		||||
				);
 | 
			
		||||
				ONLY_ACTIVE_ARCH = NO;
 | 
			
		||||
				ONLY_ACTIVE_ARCH = YES;
 | 
			
		||||
				OTHER_LDFLAGS = "-ObjC";
 | 
			
		||||
				PRODUCT_NAME = "${TARGET_NAME}";
 | 
			
		||||
				"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,10 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "0460"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
   <BuildAction>
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "NO"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            buildForRunning = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
@@ -22,32 +15,9 @@
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
      <Testables>
 | 
			
		||||
      </Testables>
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      buildConfiguration = "AppStore">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
@@ -57,30 +27,5 @@
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
      <AdditionalOptions>
 | 
			
		||||
      </AdditionalOptions>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "AppStore"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,10 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "0460"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
   <BuildAction>
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            buildForRunning = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
@@ -22,80 +15,17 @@
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
      <Testables>
 | 
			
		||||
         <TestableReference
 | 
			
		||||
            skipped = "NO">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "DA3EF17815A47744003ABF4E"
 | 
			
		||||
               BuildableName = "Tests.octest"
 | 
			
		||||
               BlueprintName = "Tests"
 | 
			
		||||
               ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </TestableReference>
 | 
			
		||||
      </Testables>
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
      <AdditionalOptions>
 | 
			
		||||
         <AdditionalOption
 | 
			
		||||
            key = "NSZombieEnabled"
 | 
			
		||||
            value = "YES"
 | 
			
		||||
            isEnabled = "YES">
 | 
			
		||||
         </AdditionalOption>
 | 
			
		||||
      </AdditionalOptions>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "AdHoc"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
      <BuildableProductRunnable>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
 | 
			
		||||
            BuildableName = "MasterPassword.app"
 | 
			
		||||
            BlueprintName = "MasterPassword"
 | 
			
		||||
            ReferencedContainer = "container:MasterPassword-iOS.xcodeproj">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user