diff --git a/External/Mac/Crashlytics.framework/Modules b/External/Mac/Crashlytics.framework/Modules
new file mode 120000
index 00000000..5736f318
--- /dev/null
+++ b/External/Mac/Crashlytics.framework/Modules
@@ -0,0 +1 @@
+Versions/Current/Modules
\ No newline at end of file
diff --git a/External/Mac/Crashlytics.framework/Versions/A/Crashlytics b/External/Mac/Crashlytics.framework/Versions/A/Crashlytics
index 41884f03..65733602 100644
Binary files a/External/Mac/Crashlytics.framework/Versions/A/Crashlytics and b/External/Mac/Crashlytics.framework/Versions/A/Crashlytics differ
diff --git a/External/Mac/Crashlytics.framework/Versions/A/Headers/Crashlytics.h b/External/Mac/Crashlytics.framework/Versions/A/Headers/Crashlytics.h
index 59addeff..7102c5c1 100644
--- a/External/Mac/Crashlytics.framework/Versions/A/Headers/Crashlytics.h
+++ b/External/Mac/Crashlytics.framework/Versions/A/Headers/Crashlytics.h
@@ -38,6 +38,7 @@
*
**/
OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
+OBJC_EXTERN void CLSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
/**
*
@@ -46,6 +47,8 @@ OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
*
**/
OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
+OBJC_EXTERN void CLSNSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
+
@protocol CrashlyticsDelegate;
diff --git a/External/Mac/Crashlytics.framework/Versions/A/Modules/module.modulemap b/External/Mac/Crashlytics.framework/Versions/A/Modules/module.modulemap
new file mode 100644
index 00000000..e552e9ca
--- /dev/null
+++ b/External/Mac/Crashlytics.framework/Versions/A/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module Crashlytics {
+ umbrella header "Crashlytics.h"
+
+ export *
+ module * { export * }
+}
diff --git a/External/Mac/Crashlytics.framework/Versions/A/Resources/Info.plist b/External/Mac/Crashlytics.framework/Versions/A/Resources/Info.plist
index bf21197c..0fa9b7bd 100644
--- a/External/Mac/Crashlytics.framework/Versions/A/Resources/Info.plist
+++ b/External/Mac/Crashlytics.framework/Versions/A/Resources/Info.plist
@@ -15,13 +15,13 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.1.2
+ 2.2.5
CFBundleSupportedPlatforms
macosx
CFBundleVersion
- 9
+ 39
DTPlatformName
macosx
MinimumOSVersion
diff --git a/External/Mac/Crashlytics.framework/run b/External/Mac/Crashlytics.framework/run
index a43a84fe..b34d4f75 100755
Binary files a/External/Mac/Crashlytics.framework/run and b/External/Mac/Crashlytics.framework/run differ
diff --git a/MasterPassword/ObjC/MPAppDelegate_Shared.h b/MasterPassword/ObjC/MPAppDelegate_Shared.h
index 24213eba..9827758c 100644
--- a/MasterPassword/ObjC/MPAppDelegate_Shared.h
+++ b/MasterPassword/ObjC/MPAppDelegate_Shared.h
@@ -16,6 +16,7 @@
@property(strong, nonatomic, readonly) MPKey *key;
@property(strong, nonatomic, readonly) NSManagedObjectID *activeUserOID;
+@property(strong, nonatomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
+ (instancetype)get;
diff --git a/MasterPassword/ObjC/MPAppDelegate_Shared.m b/MasterPassword/ObjC/MPAppDelegate_Shared.m
index 1d72f074..be65cb0c 100644
--- a/MasterPassword/ObjC/MPAppDelegate_Shared.m
+++ b/MasterPassword/ObjC/MPAppDelegate_Shared.m
@@ -6,15 +6,16 @@
// Copyright (c) 2011 Lyndir. All rights reserved.
//
-#import
#import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Store.h"
#import "MPAppDelegate_Key.h"
+#import "NSManagedObjectModel+KCOrderedAccessorFix.h"
@interface MPAppDelegate_Shared ()
@property(strong, nonatomic) MPKey *key;
@property(strong, nonatomic) NSManagedObjectID *activeUserOID;
+@property(strong, nonatomic) NSPersistentStoreCoordinator *storeCoordinator;
@end
@@ -31,6 +32,18 @@
#endif
}
+- (instancetype)init {
+
+ if (!(self = [super init]))
+ return nil;
+
+ NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
+ [model kc_generateOrderedSetAccessors];
+ self.storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
+
+ return self;
+}
+
- (MPUserEntity *)activeUserForMainThread {
return [self activeUserInContext:[MPAppDelegate_Shared managedObjectContextForMainThreadIfReady]];
diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m
index 65c1aa5c..36172722 100644
--- a/MasterPassword/ObjC/MPAppDelegate_Store.m
+++ b/MasterPassword/ObjC/MPAppDelegate_Store.m
@@ -7,8 +7,6 @@
//
#import "MPAppDelegate_Store.h"
-#import "MPGeneratedSiteEntity.h"
-#import "NSManagedObjectModel+KCOrderedAccessorFix.h"
#if TARGET_OS_IPHONE
#define STORE_OPTIONS NSPersistentStoreFileProtectionKey : NSFileProtectionComplete,
@@ -27,9 +25,7 @@ typedef NS_ENUM( NSInteger, MPStoreMigrationLevel ) {
@implementation MPAppDelegate_Shared(Store)
-PearlAssociatedObjectProperty( id, SaveObserver, saveObserver );
-
-PearlAssociatedObjectProperty( NSPersistentStoreCoordinator*, PersistentStoreCoordinator, persistentStoreCoordinator );
+PearlAssociatedObjectProperty( NSOperationQueue *, StoreQueue, storeQueue );
PearlAssociatedObjectProperty( NSManagedObjectContext*, PrivateManagedObjectContext, privateManagedObjectContext );
@@ -58,7 +54,8 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
[mainManagedObjectContext performBlock:^{
@try {
mocBlock( mainManagedObjectContext );
- } @catch (NSException *exception) {
+ }
+ @catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
@@ -148,14 +145,22 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
- (void)loadStore {
- @synchronized (self) {
+ static dispatch_once_t once = 0;
+ dispatch_once( &once, ^{
+ (self.storeQueue = [NSOperationQueue new]).maxConcurrentOperationCount = 1;
+ } );
+
+ // Do nothing if already fully set up, otherwise (re-)load the store.
+ if (self.storeCoordinator && self.mainManagedObjectContext && self.privateManagedObjectContext)
+ return;
+
+ [self.storeQueue addOperationWithBlock:^{
// Do nothing if already fully set up, otherwise (re-)load the store.
- if (self.persistentStoreCoordinator && self.saveObserver && self.mainManagedObjectContext && self.privateManagedObjectContext)
+ if (self.storeCoordinator && self.mainManagedObjectContext && self.privateManagedObjectContext)
return;
// Unregister any existing observers and contexts.
- if (self.saveObserver)
- [[NSNotificationCenter defaultCenter] removeObserver:self.saveObserver];
+ PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
[self.mainManagedObjectContext performBlockAndWait:^{
[self.mainManagedObjectContext reset];
self.mainManagedObjectContext = nil;
@@ -172,13 +177,31 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
// Check if migration is necessary.
[self migrateStore];
- // Create a new store coordinator.
- if (!self.persistentStoreCoordinator) {
- NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
- [model kc_generateOrderedSetAccessors];
- self.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
- }
+ // Install managed object contexts and observers.
+ self.privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
+ [self.privateManagedObjectContext performBlockAndWait:^{
+ self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
+ self.privateManagedObjectContext.persistentStoreCoordinator = self.storeCoordinator;
+ }];
+ self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
+ self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
+
+ // When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
+ PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
+ self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainManagedObjectContext, NSNotification *note) {
+ [mainManagedObjectContext performBlock:^{
+ @try {
+ [mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
+ }
+ @catch (NSException *exception) {
+ err( @"While merging changes:\n%@",[exception fullDescription] );
+ }
+ }];
+ } );
+
+
+ // Create a new store coordinator.
NSError *error = nil;
NSURL *localStoreURL = [self localStoreURL];
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
@@ -186,12 +209,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
err( @"Couldn't create our application support directory: %@", [error fullDescription] );
return;
}
- if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
- options:@{
- NSMigratePersistentStoresAutomaticallyOption : @YES,
- NSInferMappingModelAutomaticallyOption : @YES,
- STORE_OPTIONS
- } error:&error]) {
+ if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
+ options:@{
+ NSMigratePersistentStoresAutomaticallyOption : @YES,
+ NSInferMappingModelAutomaticallyOption : @YES,
+ STORE_OPTIONS
+ } error:&error]) {
err( @"Failed to open store: %@", [error fullDescription] );
self.storeCorrupted = @YES;
[self handleCoordinatorError:error];
@@ -199,30 +222,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
}
self.storeCorrupted = @NO;
- // Create our contexts and observer.
- self.privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
- [self.privateManagedObjectContext performBlockAndWait:^{
- self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
- self.privateManagedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
- }];
-
- self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
- self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
-
- self.saveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
- object:self.privateManagedObjectContext queue:nil usingBlock:
- ^(NSNotification *note) {
- // When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
- [self.mainManagedObjectContext performBlock:^{
- @try {
- [self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
- }
- @catch (NSException *exception) {
- err( @"While merging changes:\n%@", [exception fullDescription] );
- }
- }];
- }];
-
#if TARGET_OS_IPHONE
PearlAddNotificationObserver( UIApplicationWillTerminateNotification, UIApp, [NSOperationQueue mainQueue],
^(MPAppDelegate_Shared *self, NSNotification *note) {
@@ -244,15 +243,14 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
[MPAppDelegate_Shared managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
[self findAndFixInconsistenciesSaveInContext:context];
}];
- }
+ }];
}
- (void)deleteAndResetStore {
@synchronized (self) {
// Unregister any existing observers and contexts.
- if (self.saveObserver)
- [[NSNotificationCenter defaultCenter] removeObserver:self.saveObserver];
+ PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
[self.mainManagedObjectContext performBlockAndWait:^{
[self.mainManagedObjectContext reset];
self.mainManagedObjectContext = nil;
@@ -262,11 +260,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
self.privateManagedObjectContext = nil;
}];
NSError *error = nil;
- for (NSPersistentStore *store in self.persistentStoreCoordinator.persistentStores) {
- if (![self.persistentStoreCoordinator removePersistentStore:store error:&error])
+ for (NSPersistentStore *store in self.storeCoordinator.persistentStores) {
+ if (![self.storeCoordinator removePersistentStore:store error:&error])
err( @"Couldn't remove persistence store from coordinator: %@", [error fullDescription] );
}
- self.persistentStoreCoordinator = nil;
if (![[NSFileManager defaultManager] removeItemAtURL:self.localStoreURL error:&error])
err( @"Couldn't remove persistence store at URL %@: %@", self.localStoreURL, [error fullDescription] );
diff --git a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
index 0e2294e6..97c4e95e 100644
--- a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
+++ b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
@@ -80,18 +80,30 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
self.statusView.target = self;
self.statusView.action = @selector( showMenu );
- [[NSNotificationCenter defaultCenter] addObserverForName:NSPersistentStoreCoordinatorStoresDidChangeNotification object:nil
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
- [self updateUsers];
- }];
- [[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
- NSString *key = note.object;
- if (!key || [key isEqualToString:NSStringFromSelector( @selector( hidePasswords ) )])
- self.hidePasswordsItem.state = [[MPConfig get].hidePasswords boolValue]? NSOnState: NSOffState;
- if (!key || [key isEqualToString:NSStringFromSelector( @selector( rememberLogin ) )])
- self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
- }];
+ PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, self.storeCoordinator, nil,
+ ^(id self, NSNotification *note) {
+ PearlMainQueue( ^{
+ [self updateUsers];
+ } );
+ } );
+ PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, self.storeCoordinator, nil,
+ ^(id self, NSNotification *note) {
+ PearlMainQueue( ^{
+ [self updateUsers];
+ } );
+ } );
+ PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
+ ^(MPMacAppDelegate *self, NSNotification *note) {
+ PearlMainQueue( ^{
+ NSString *key = note.object;
+ if (!key || [key isEqualToString:NSStringFromSelector( @
+ selector( hidePasswords ) )])
+ self.hidePasswordsItem.state = [[MPConfig get].hidePasswords boolValue]? NSOnState: NSOffState;
+ if (!key || [key isEqualToString:NSStringFromSelector( @
+ selector( rememberLogin ) )])
+ self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
+ } );
+ } );
[self updateUsers];
// Global hotkey.
@@ -172,12 +184,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
NSArray *jobs = (__bridge_transfer NSArray *)SMCopyAllJobDictionaries( kSMDomainUserLaunchd );
for (NSDictionary *job in jobs)
- if ([LOGIN_HELPER_BUNDLE_ID isEqualToString:job[@"Label"]]) {
- dbg( @"loginItemEnabled: %@", @([job[@"OnDemand"] boolValue]) );
+ if ([LOGIN_HELPER_BUNDLE_ID isEqualToString:job[@"Label"]])
return [job[@"OnDemand"] boolValue];
- }
- dbg( @"loginItemEnabled: not found" );
return NO;
}
@@ -454,12 +463,14 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
NSString *exportedSites = [self exportSitesRevealPasswords:revealPasswords];
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError
byAccessor:^(NSURL *newURL) {
- NSError *writeError = nil;
- if (![exportedSites writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
- PearlMainQueue( ^{
- [[NSAlert alertWithError:writeError] runModal];
- } );
- }];
+ NSError *writeError = nil;
+ if (![exportedSites writeToURL:newURL atomically:NO
+ encoding:NSUTF8StringEncoding
+ error:&writeError])
+ PearlMainQueue( ^{
+ [[NSAlert alertWithError:writeError] runModal];
+ } );
+ }];
if (coordinateError)
PearlMainQueue( ^{
[[NSAlert alertWithError:coordinateError] runModal];
diff --git a/MasterPassword/ObjC/Mac/MPNoStateButton.h b/MasterPassword/ObjC/Mac/MPNoStateButton.h
new file mode 100644
index 00000000..d347e5d2
--- /dev/null
+++ b/MasterPassword/ObjC/Mac/MPNoStateButton.h
@@ -0,0 +1,23 @@
+/**
+ * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
+ *
+ * See the enclosed file LICENSE for license information (LGPLv3). If you did
+ * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * @author Maarten Billemont
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+
+//
+// MPNoStateButton.h
+// MPNoStateButton
+//
+// Created by lhunath on 14-10-27.
+// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
+//
+
+#import
+
+
+@interface MPNoStateButtonCell : NSButtonCell
+@end
diff --git a/MasterPassword/ObjC/Mac/MPNoStateButton.m b/MasterPassword/ObjC/Mac/MPNoStateButton.m
new file mode 100644
index 00000000..7c06e6a2
--- /dev/null
+++ b/MasterPassword/ObjC/Mac/MPNoStateButton.m
@@ -0,0 +1,31 @@
+/**
+ * Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
+ *
+ * See the enclosed file LICENSE for license information (LGPLv3). If you did
+ * not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * @author Maarten Billemont
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+
+//
+// MPNoStateButton.h
+// MPNoStateButton
+//
+// Created by lhunath on 14-10-27.
+// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
+//
+
+#import "MPNoStateButton.h"
+
+
+@implementation MPNoStateButtonCell {
+
+}
+
+- (void)setState:(NSInteger)state {
+
+ [super setState:NSOnState];
+}
+
+@end
diff --git a/MasterPassword/ObjC/Mac/MPPasswordWindowController.h b/MasterPassword/ObjC/Mac/MPPasswordWindowController.h
index 2bc790f6..ee4fdcbd 100644
--- a/MasterPassword/ObjC/Mac/MPPasswordWindowController.h
+++ b/MasterPassword/ObjC/Mac/MPPasswordWindowController.h
@@ -29,6 +29,7 @@
@property(nonatomic) BOOL alternatePressed;
@property(nonatomic) BOOL locked;
@property(nonatomic) BOOL newUser;
+@property(nonatomic) BOOL alwaysYes;
@property(nonatomic, weak) IBOutlet NSArrayController *sitesController;
@property(nonatomic, weak) IBOutlet NSImageView *blurView;
diff --git a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
index 6c18217e..04340736 100644
--- a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
+++ b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
@@ -116,7 +116,6 @@
- (void)doCommandBySelector:(SEL)commandSelector {
- dbg( @"doCommandBySelector: %@", NSStringFromSelector( commandSelector ) );
[self handleCommand:commandSelector];
}
@@ -124,19 +123,18 @@
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector {
- dbg( @"@control:%@ textView:%@ doCommandBySelector:%@", control, fieldEditor, NSStringFromSelector( commandSelector ) );
if (control == self.siteField) {
if ([NSStringFromSelector( commandSelector ) rangeOfString:@"delete"].location == 0) {
_skipTextChange = YES;
- return NO;
+ dbg_return_tr( NO, @, control, NSStringFromSelector( commandSelector ) );
}
}
if (control == self.securePasswordField || control == self.revealPasswordField) {
if (commandSelector == @selector( insertNewline: ))
- return NO;
+ dbg_return_tr( NO, @, control, NSStringFromSelector( commandSelector ) );
}
- return [self handleCommand:commandSelector];
+ dbg_return_tr( [self handleCommand:commandSelector], @, control, NSStringFromSelector( commandSelector ) );
}
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
@@ -312,6 +310,14 @@
return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""]?: @"";
}
+- (BOOL)alwaysYes {
+
+ return YES;
+}
+
+- (void)setAlwaysYes:(BOOL)alwaysYes {
+}
+
- (void)insertObject:(MPSiteModel *)model inSitesAtIndex:(NSUInteger)index {
[self.sites insertObject:model atIndex:index];
diff --git a/MasterPassword/ObjC/Mac/MPPasswordWindowController.xib b/MasterPassword/ObjC/Mac/MPPasswordWindowController.xib
index 47793877..5fb22575 100644
--- a/MasterPassword/ObjC/Mac/MPPasswordWindowController.xib
+++ b/MasterPassword/ObjC/Mac/MPPasswordWindowController.xib
@@ -1,14 +1,13 @@
-
+
-
-
+
+
-
@@ -17,33 +16,42 @@
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
@@ -51,13 +59,13 @@
-
+
-
+
NSAllRomanInputSourcesLocaleIdentifier
@@ -86,13 +94,13 @@
-
+
-
+
NSAllRomanInputSourcesLocaleIdentifier
@@ -123,11 +131,11 @@
-
+
diff --git a/MasterPassword/ObjC/Mac/MPSiteModel.m b/MasterPassword/ObjC/Mac/MPSiteModel.m
index a6299611..c7dd6ed7 100644
--- a/MasterPassword/ObjC/Mac/MPSiteModel.m
+++ b/MasterPassword/ObjC/Mac/MPSiteModel.m
@@ -48,7 +48,6 @@
self.algorithm = entity.algorithm;
self.siteName = entity.name;
self.lastUsed = entity.lastUsed;
- self.loginName = entity.loginName;
self.type = entity.type;
self.typeName = entity.typeName;
self.uses = entity.uses_;
@@ -127,6 +126,11 @@
self.contentDisplay = displayResult;
} );
}];
+ [entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
+ PearlMainQueue( ^{
+ self.loginName = result;
+ } );
+ }];
}
@end
diff --git a/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj b/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
index 27f10711..035f2cd7 100644
--- a/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
+++ b/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
@@ -10,6 +10,7 @@
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; };
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */; };
+ 93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */; };
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
@@ -55,13 +56,14 @@
DA3B8456190FC89700246EEA /* MPFixable.m in Sources */ = {isa = PBXBuildFile; fileRef = DA3B8454190FC89700246EEA /* MPFixable.m */; };
DA3BCFCD19BD09E0006B2681 /* SourceCodePro-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA3BCFCC19BD09E0006B2681 /* SourceCodePro-Regular.otf */; };
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6326C148680650075AEA5 /* libjrswizzle.a */; };
+ DA5180CA19FF2F9200A587E9 /* MPAlgorithmV2.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */; };
+ DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */; };
DA5E5C9417248AA1003798D8 /* libscryptenc-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5E5C8717248AA1003798D8 /* libscryptenc-osx.a */; };
DA5E5CF61724A667003798D8 /* MPAlgorithm.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C981724A667003798D8 /* MPAlgorithm.m */; };
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9A1724A667003798D8 /* MPAlgorithmV0.m */; };
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9C1724A667003798D8 /* MPAlgorithmV1.m */; };
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */; };
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */; };
- DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */; };
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA41724A667003798D8 /* MPConfig.m */; };
DA5E5D001724A667003798D8 /* MPEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAC1724A667003798D8 /* MPEntities.m */; };
DA5E5D011724A667003798D8 /* MPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAE1724A667003798D8 /* MPKey.m */; };
@@ -238,11 +240,13 @@
/* Begin PBXFileReference section */
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = ""; };
93D39240B5143E01F0B75E96 /* MPSiteModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteModel.h; sourceTree = ""; };
+ 93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNoStateButton.h; sourceTree = ""; };
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = ""; };
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = ""; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = ""; };
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesTableView.m; sourceTree = ""; };
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = ""; };
+ 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNoStateButton.m; sourceTree = ""; };
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = ""; };
93D3977484534E99F9BA579D /* MPPasswordWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindow.h; sourceTree = ""; };
93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindowController.m; sourceTree = ""; };
@@ -301,6 +305,10 @@
DA3B8454190FC89700246EEA /* MPFixable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFixable.m; sourceTree = ""; };
DA3B8455190FC89700246EEA /* MPFixable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFixable.h; sourceTree = ""; };
DA3BCFCC19BD09E0006B2681 /* SourceCodePro-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceCodePro-Regular.otf"; sourceTree = ""; };
+ DA5180C619FF2F9200A587E9 /* MPAlgorithmV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAlgorithmV2.h; sourceTree = ""; };
+ DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV2.m; sourceTree = ""; };
+ DA5180CC19FF307E00A587E9 /* MPAppDelegate_Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Store.h; sourceTree = ""; };
+ DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = ""; };
DA5BFA44147E415C00F98B1E /* Master Password.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Master Password.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DA5BFA4A147E415C00F98B1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
DA5BFA4C147E415C00F98B1E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@@ -316,8 +324,6 @@
DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Key.m; sourceTree = ""; };
DA5E5C9F1724A667003798D8 /* MPAppDelegate_Shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Shared.h; sourceTree = ""; };
DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Shared.m; sourceTree = ""; };
- DA5E5CA11724A667003798D8 /* MPAppDelegate_Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Store.h; sourceTree = ""; };
- DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = ""; };
DA5E5CA31724A667003798D8 /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = ""; };
DA5E5CA41724A667003798D8 /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = ""; };
DA5E5CAB1724A667003798D8 /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = ""; };
@@ -1016,39 +1022,41 @@
DA5E5C961724A667003798D8 /* ObjC */ = {
isa = PBXGroup;
children = (
- DA32CFE319CF1C71004F3F0E /* MPUserEntity.h */,
- DA32CFE419CF1C71004F3F0E /* MPUserEntity.m */,
- DA32CFE019CF1C71004F3F0E /* MPSiteQuestionEntity.h */,
- DA32CFE119CF1C71004F3F0E /* MPSiteQuestionEntity.m */,
- DA32CFDD19CF1C70004F3F0E /* MPSiteEntity.h */,
- DA32CFDE19CF1C70004F3F0E /* MPSiteEntity.m */,
- DA32CFDA19CF1C70004F3F0E /* MPStoredSiteEntity.h */,
- DA32CFDB19CF1C70004F3F0E /* MPStoredSiteEntity.m */,
- DA32CFD719CF1C70004F3F0E /* MPGeneratedSiteEntity.h */,
- DA32CFD819CF1C70004F3F0E /* MPGeneratedSiteEntity.m */,
- DA3B8454190FC89700246EEA /* MPFixable.m */,
- DA3B8455190FC89700246EEA /* MPFixable.h */,
DA5E5CB21724A667003798D8 /* Mac */,
+ DA29992619C6A89900AF7DF1 /* MasterPassword.xcdatamodeld */,
DA5E5C971724A667003798D8 /* MPAlgorithm.h */,
DA5E5C981724A667003798D8 /* MPAlgorithm.m */,
DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */,
DA5E5C9A1724A667003798D8 /* MPAlgorithmV0.m */,
DA5E5C9B1724A667003798D8 /* MPAlgorithmV1.h */,
DA5E5C9C1724A667003798D8 /* MPAlgorithmV1.m */,
+ DA5180C619FF2F9200A587E9 /* MPAlgorithmV2.h */,
+ DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */,
DA5E5C9D1724A667003798D8 /* MPAppDelegate_Key.h */,
DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */,
DA5E5C9F1724A667003798D8 /* MPAppDelegate_Shared.h */,
DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */,
- DA5E5CA11724A667003798D8 /* MPAppDelegate_Store.h */,
- DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */,
+ DA5180CC19FF307E00A587E9 /* MPAppDelegate_Store.h */,
+ DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */,
DA5E5CA31724A667003798D8 /* MPConfig.h */,
DA5E5CA41724A667003798D8 /* MPConfig.m */,
DA5E5CAB1724A667003798D8 /* MPEntities.h */,
DA5E5CAC1724A667003798D8 /* MPEntities.m */,
+ DA3B8455190FC89700246EEA /* MPFixable.h */,
+ DA3B8454190FC89700246EEA /* MPFixable.m */,
+ DA32CFD719CF1C70004F3F0E /* MPGeneratedSiteEntity.h */,
+ DA32CFD819CF1C70004F3F0E /* MPGeneratedSiteEntity.m */,
DA5E5CAD1724A667003798D8 /* MPKey.h */,
DA5E5CAE1724A667003798D8 /* MPKey.m */,
+ DA32CFDD19CF1C70004F3F0E /* MPSiteEntity.h */,
+ DA32CFDE19CF1C70004F3F0E /* MPSiteEntity.m */,
+ DA32CFE019CF1C71004F3F0E /* MPSiteQuestionEntity.h */,
+ DA32CFE119CF1C71004F3F0E /* MPSiteQuestionEntity.m */,
+ DA32CFDA19CF1C70004F3F0E /* MPStoredSiteEntity.h */,
+ DA32CFDB19CF1C70004F3F0E /* MPStoredSiteEntity.m */,
DA5E5CAF1724A667003798D8 /* MPTypes.h */,
- DA29992619C6A89900AF7DF1 /* MasterPassword.xcdatamodeld */,
+ DA32CFE319CF1C71004F3F0E /* MPUserEntity.h */,
+ DA32CFE419CF1C71004F3F0E /* MPUserEntity.m */,
);
name = ObjC;
path = ..;
@@ -1080,6 +1088,8 @@
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */,
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */,
93D39AC6360DDC16AEAA4119 /* MPSitesTableView.h */,
+ 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */,
+ 93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */,
);
path = Mac;
sourceTree = "";
@@ -2182,8 +2192,8 @@
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */,
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */,
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */,
+ DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */,
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */,
- DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */,
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */,
DA29992C19C6A89900AF7DF1 /* MasterPassword.xcdatamodeld in Sources */,
DA3B8456190FC89700246EEA /* MPFixable.m in Sources */,
@@ -2194,12 +2204,14 @@
DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */,
DA5E5D0C1724A667003798D8 /* main.m in Sources */,
93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */,
+ DA5180CA19FF2F9200A587E9 /* MPAlgorithmV2.m in Sources */,
93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */,
DA32CFD919CF1C70004F3F0E /* MPGeneratedSiteEntity.m in Sources */,
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */,
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
+ 93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2488,7 +2500,7 @@
DA5BFA6E147E415C00F98B1E /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
@@ -2512,7 +2524,7 @@
DA5BFA6F147E415C00F98B1E /* AdHoc-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "Developer ID Application";
@@ -2612,7 +2624,7 @@
DA95D60A14DF3F3B008D1B94 /* AppStore-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
diff --git a/MasterPassword/ObjC/iOS/MPPasswordsViewController.m b/MasterPassword/ObjC/iOS/MPPasswordsViewController.m
index 9b33266c..fee25fcd 100644
--- a/MasterPassword/ObjC/iOS/MPPasswordsViewController.m
+++ b/MasterPassword/ObjC/iOS/MPPasswordsViewController.m
@@ -316,25 +316,33 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
self.passwordSelectionContainer.alpha = 1;
}];
} );
- PearlAddNotificationObserver( MPSignedOutNotification, nil, [NSOperationQueue mainQueue],
+ PearlAddNotificationObserver( MPSignedOutNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
- _fetchedResultsController = nil;
- self.passwordsSearchBar.text = nil;
- [self.passwordCollectionView reloadData];
+ PearlMainQueue( ^{
+ _fetchedResultsController = nil;
+ self.passwordsSearchBar.text = nil;
+ [self.passwordCollectionView reloadData];
+ } );
} );
- PearlAddNotificationObserver( MPCheckConfigNotification, nil, [NSOperationQueue mainQueue],
+ PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
- [self updateConfigKey:note.object];
+ PearlMainQueue( ^{
+ [self updateConfigKey:note.object];
+ } );
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
self->_fetchedResultsController = nil;
- [self.passwordCollectionView reloadData];
+ PearlMainQueue( ^{
+ [self.passwordCollectionView reloadData];
+ } );
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
- [self updatePasswords];
- [self registerObservers];
+ PearlMainQueue( ^{
+ [self updatePasswords];
+ [self registerObservers];
+ } );
} );
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.m b/MasterPassword/ObjC/iOS/MPUsersViewController.m
index c6cf6069..c64d76eb 100644
--- a/MasterPassword/ObjC/iOS/MPUsersViewController.m
+++ b/MasterPassword/ObjC/iOS/MPUsersViewController.m
@@ -666,7 +666,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
[self.storeLoadingActivity startAnimating];
if (mainContext)
- PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, [NSOperationQueue mainQueue],
+ PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, nil,
^(MPUsersViewController *self, NSNotification *note) {
NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey];
NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey];
@@ -676,11 +676,11 @@ referenceSizeForFooterInSection:(NSInteger)section {
}]] count])
[self reloadUsers];
} );
- PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, [NSOperationQueue mainQueue],
+ PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
^(MPUsersViewController *self, NSNotification *note) {
self.userIDs = nil;
} );
- PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, [NSOperationQueue mainQueue],
+ PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
^(MPUsersViewController *self, NSNotification *note) {
[self registerObservers];
[self reloadUsers];