From 18657271ba30d45c487e2d11b3fa9c15490c13ad Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Tue, 15 Apr 2014 00:26:13 -0400 Subject: [PATCH] Fixed MOC hierarchy, saving and permanent object ID resolution. --- MasterPassword/ObjC/MPAppDelegate_Store.m | 31 ++++++++++++------- .../ObjC/iOS/MPPasswordElementCell.m | 8 +++-- MasterPassword/ObjC/iOS/MPPasswordTypesCell.m | 8 ++--- .../ObjC/iOS/MPUsersViewController.m | 4 +-- MasterPassword/ObjC/iOS/Storyboard.storyboard | 30 +++++++++--------- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m index de775a54..529c8926 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Store.m +++ b/MasterPassword/ObjC/MPAppDelegate_Store.m @@ -77,12 +77,12 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, + (BOOL)managedObjectContextPerformBlock:(void (^)(NSManagedObjectContext *context))mocBlock { - NSManagedObjectContext *mainManagedObjectContext = [[self get] mainManagedObjectContextIfReady]; - if (!mainManagedObjectContext) + NSManagedObjectContext *privateManagedObjectContextIfReady = [[self get] privateManagedObjectContextIfReady]; + if (!privateManagedObjectContextIfReady) return NO; NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; - moc.parentContext = mainManagedObjectContext; + moc.parentContext = privateManagedObjectContextIfReady; [moc performBlock:^{ mocBlock( moc ); }]; @@ -92,12 +92,12 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, + (BOOL)managedObjectContextPerformBlockAndWait:(void (^)(NSManagedObjectContext *context))mocBlock { - NSManagedObjectContext *mainManagedObjectContext = [[self get] mainManagedObjectContextIfReady]; - if (!mainManagedObjectContext) + NSManagedObjectContext *privateManagedObjectContextIfReady = [[self get] privateManagedObjectContextIfReady]; + if (!privateManagedObjectContextIfReady) return NO; NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; - moc.parentContext = mainManagedObjectContext; + moc.parentContext = privateManagedObjectContextIfReady; [moc performBlockAndWait:^{ mocBlock( moc ); }]; @@ -366,11 +366,18 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, if (self.saveObserver) [[NSNotificationCenter defaultCenter] removeObserver:self.saveObserver]; - self.saveObserver = [[NSNotificationCenter defaultCenter] - addObserverForName:NSManagedObjectContextDidSaveNotification object:privateManagedObjectContext queue:nil usingBlock: + self.saveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification + object:privateManagedObjectContext queue:nil usingBlock: ^(NSNotification *note) { + // When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext. [mainManagedObjectContext performBlock:^{ [mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note]; + + NSError *error = nil; + if (![mainManagedObjectContext obtainPermanentIDsForObjects: + [mainManagedObjectContext.registeredObjects allObjects] + error:&error] || error) + err(@"Failed to obtain permanent object IDs for all objects in main context: %@", error); }]; }]; @@ -448,13 +455,13 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, newElement.version = element.version; newElement.loginName = element.loginName; - [context deleteObject:element]; - [context saveToStore]; - - NSError *error; + NSError *error = nil; if (![context obtainPermanentIDsForObjects:@[ newElement ] error:&error]) err(@"Failed to obtain a permanent object ID after changing object type: %@", error); + [context deleteObject:element]; + [context saveToStore]; + [[NSNotificationCenter defaultCenter] postNotificationName:MPElementUpdatedNotification object:element.objectID]; element = newElement; } diff --git a/MasterPassword/ObjC/iOS/MPPasswordElementCell.m b/MasterPassword/ObjC/iOS/MPPasswordElementCell.m index 0a672b8b..a5db1cd4 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordElementCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordElementCell.m @@ -48,13 +48,15 @@ - (void)setElement:(MPElementEntity *)element { - if ([_elementOID isEqual:element.objectID]) + NSManagedObjectID *newElementOID = element.objectID; + NSAssert(!newElementOID.isTemporaryID, @"Element doesn't have a permanent objectID: %@", element); + if ([_elementOID isEqual:newElementOID]) return; - dbg(@"element: %@ -> %@", _elementOID, element.objectID); + dbg(@"element: %@ -> %@", _elementOID, newElementOID); _transientSite = nil; - _elementOID = element.objectID; + _elementOID = newElementOID; [self updateAnimated:YES]; [self reloadData]; diff --git a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m index f3b739ab..692b2b4e 100644 --- a/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m +++ b/MasterPassword/ObjC/iOS/MPPasswordTypesCell.m @@ -69,8 +69,8 @@ [self.contentCollectionView reloadData]; NSIndexPath *visibleIndexPath = [self contentIndexPathForType: IfElse([[MPiOSAppDelegate get] activeUserForMainThread].defaultType, MPElementTypeGeneratedLong)]; - [self.contentCollectionView scrollToItemAtIndexPath:visibleIndexPath atScrollPosition:NO - animated:UICollectionViewScrollPositionCenteredHorizontally]; + [self.contentCollectionView scrollToItemAtIndexPath:visibleIndexPath + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; } - (void)reloadWithElement:(MPElementEntity *)mainElement { @@ -81,8 +81,8 @@ [self.contentCollectionView reloadData]; NSIndexPath *visibleIndexPath = [self contentIndexPathForType:mainElement.type]; - [self.contentCollectionView scrollToItemAtIndexPath:visibleIndexPath atScrollPosition:NO - animated:UICollectionViewScrollPositionCenteredHorizontally]; + [self.contentCollectionView scrollToItemAtIndexPath:visibleIndexPath + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; } #pragma mark - UICollectionViewDataSource diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.m b/MasterPassword/ObjC/iOS/MPUsersViewController.m index 465ede41..28216e22 100644 --- a/MasterPassword/ObjC/iOS/MPUsersViewController.m +++ b/MasterPassword/ObjC/iOS/MPUsersViewController.m @@ -295,8 +295,8 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) { - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { if (collectionView == self.avatarCollectionView) { - [self.avatarCollectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally - animated:YES]; + [self.avatarCollectionView scrollToItemAtIndexPath:indexPath + atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES]; // Deselect all other cells. for (NSUInteger otherItem = 0; otherItem < [collectionView numberOfItemsInSection:indexPath.section]; ++otherItem) diff --git a/MasterPassword/ObjC/iOS/Storyboard.storyboard b/MasterPassword/ObjC/iOS/Storyboard.storyboard index f0a98fe2..fc59aed7 100644 --- a/MasterPassword/ObjC/iOS/Storyboard.storyboard +++ b/MasterPassword/ObjC/iOS/Storyboard.storyboard @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -36,7 +36,7 @@ - + @@ -147,7 +147,7 @@ - + - + - + @@ -187,23 +187,23 @@ - + - + - +