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 @@
-
+
-
+
-
+