diff --git a/External/Pearl b/External/Pearl
index f81514bf..cc97c1be 160000
--- a/External/Pearl
+++ b/External/Pearl
@@ -1 +1 @@
-Subproject commit f81514bfd87773c6b1ea202520d75841c159ce9f
+Subproject commit cc97c1be4c0f2ee0080af417940244ac8f3e5f47
diff --git a/MasterPassword/MPAlgorithmV0.m b/MasterPassword/MPAlgorithmV0.m
index dd77a21d..40763c7f 100644
--- a/MasterPassword/MPAlgorithmV0.m
+++ b/MasterPassword/MPAlgorithmV0.m
@@ -192,7 +192,7 @@
return nil;
if (!(element.type & MPElementTypeClassGenerated)) {
- err(@"Incorrect type (is not MPElementTypeClassGenerated): %d, for: %@", [self nameOfType:element.type], element.name);
+ err(@"Incorrect type (is not MPElementTypeClassGenerated): %@, for: %@", [self nameOfType:element.type], element.name);
return nil;
}
if (!element.name.length) {
diff --git a/MasterPassword/MPAlgorithmV1.m b/MasterPassword/MPAlgorithmV1.m
index a650298b..e379a717 100644
--- a/MasterPassword/MPAlgorithmV1.m
+++ b/MasterPassword/MPAlgorithmV1.m
@@ -54,7 +54,7 @@
return nil;
if (!(element.type & MPElementTypeClassGenerated)) {
- err(@"Incorrect type (is not MPElementTypeClassGenerated): %d, for: %@", [self nameOfType:element.type], element.name);
+ err(@"Incorrect type (is not MPElementTypeClassGenerated): %@, for: %@", [self nameOfType:element.type], element.name);
return nil;
}
if (!element.name.length) {
diff --git a/MasterPassword/iOS/MPAppDelegate.m b/MasterPassword/iOS/MPAppDelegate.m
index 540e8b7f..8298de6d 100644
--- a/MasterPassword/iOS/MPAppDelegate.m
+++ b/MasterPassword/iOS/MPAppDelegate.m
@@ -34,7 +34,7 @@
[MPiOSConfig get];
#ifdef DEBUG
- [PearlLogger get].autoprintLevel = PearlLogLevelDebug;
+ [PearlLogger get].printLevel = PearlLogLevelDebug;
//[NSClassFromString(@"WebView") performSelector:NSSelectorFromString(@"_enableRemoteInspector")];
#endif
}
@@ -49,16 +49,14 @@
[[[NSBundle mainBundle] mutableInfoDictionary] setObject:@"Master Password" forKey:@"CFBundleDisplayName"];
[[[NSBundle mainBundle] mutableLocalizedInfoDictionary] setObject:@"Master Password" forKey:@"CFBundleDisplayName"];
+#ifdef ADHOC
@try {
NSString *testFlightToken = [self testFlightToken];
if ([testFlightToken length]) {
inf(@"Initializing TestFlight");
[TestFlight addCustomEnvironmentInformation:@"Anonymous" forKey:@"username"];
-#ifdef ADHOC
[TestFlight setDeviceIdentifier:[(id)[UIDevice currentDevice] uniqueIdentifier]];
-#else
- [TestFlight setDeviceIdentifier:[PearlKeyChain deviceIdentifier]];
-#endif
+// [TestFlight setDeviceIdentifier:[PearlKeyChain deviceIdentifier]];
[TestFlight setOptions:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], @"logToConsole",
[NSNumber numberWithBool:NO], @"logToSTDERR",
@@ -81,6 +79,7 @@
@catch (id exception) {
err(@"TestFlight: %@", exception);
}
+#endif
@try {
NSString *crashlyticsAPIKey = [self crashlyticsAPIKey];
if ([crashlyticsAPIKey length]) {
@@ -115,13 +114,13 @@
[[LocalyticsSession sharedLocalyticsSession] startSession:localyticsKey];
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
if (message.level >= PearlLogLevelWarn)
- [[LocalyticsSession sharedLocalyticsSession] tagEvent:@"Problem" attributes:
- [NSDictionary dictionaryWithObjectsAndKeys:
- [message levelDescription],
- @"level",
- message.message,
- @"message",
- nil]];
+ [[LocalyticsSession sharedLocalyticsSession] tagEvent:@"Problem"
+ attributes:[NSDictionary
+ dictionaryWithObjectsAndKeys:
+ [NSString stringWithCString:PearlLogLevelStr(message.level)
+ encoding:NSASCIIStringEncoding], @"level",
+ message.message, @"message",
+ nil]];
return YES;
}];
@@ -155,7 +154,7 @@
[NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAttributeTextShadowOffset,
[UIFont fontWithName:@"Helvetica-Neue" size:0.0f], UITextAttributeFont,
nil]
- forState:UIControlStateNormal];
+ forState:UIControlStateNormal];
UIImage *toolBarImage = [[UIImage imageNamed:@"ui_toolbar_container"] resizableImageWithCapInsets:UIEdgeInsetsMake(25, 5, 5, 5)];
[[UISearchBar appearance] setBackgroundImage:toolBarImage];
@@ -190,7 +189,7 @@
[self.navigationController performSegueWithIdentifier:@"MP_Unlock" sender:nil];
else
[self.navigationController presentViewController:[self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"MPUnlockViewController"]
- animated:NO completion:nil];
+ animated:NO completion:nil];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:kIASKAppSettingChanged object:nil queue:nil
usingBlock:^(NSNotification *note) {
@@ -224,7 +223,7 @@
__autoreleasing NSError *error;
__autoreleasing NSURLResponse *response;
NSData *importedSitesData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url]
- returningResponse:&response error:&error];
+ returningResponse:&response error:&error];
if (error)
err(@"While reading imported sites from %@: %@", url, error);
if (!importedSitesData)
@@ -237,33 +236,33 @@
^(UIAlertView *alert, NSInteger buttonIndex) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
MPImportResult result = [self importSites:importedSitesString withPassword:[alert textFieldAtIndex:0].text
- askConfirmation:^BOOL(NSUInteger importCount, NSUInteger deleteCount) {
- __block BOOL confirmation = NO;
+ askConfirmation:^BOOL(NSUInteger importCount, NSUInteger deleteCount) {
+ __block BOOL confirmation = NO;
- dispatch_group_t confirmationGroup = dispatch_group_create();
- dispatch_group_enter(confirmationGroup);
- dispatch_async(dispatch_get_main_queue(), ^{
- [PearlAlert showAlertWithTitle:@"Import Sites?"
- message:PearlString(
- @"Import %d sites, overwriting %d existing sites?",
- importCount, deleteCount)
- viewStyle:UIAlertViewStyleDefault
- initAlert:nil
- tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
- if (buttonIndex_
- != [alert_ cancelButtonIndex])
- confirmation = YES;
+ dispatch_group_t confirmationGroup = dispatch_group_create();
+ dispatch_group_enter(confirmationGroup);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [PearlAlert showAlertWithTitle:@"Import Sites?"
+ message:PearlString(
+ @"Import %d sites, overwriting %d existing sites?",
+ importCount, deleteCount)
+ viewStyle:UIAlertViewStyleDefault
+ initAlert:nil
+ tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
+ if (buttonIndex_
+ != [alert_ cancelButtonIndex])
+ confirmation = YES;
- dispatch_group_leave(confirmationGroup);
- }
- cancelTitle:[PearlStrings get].commonButtonCancel
- otherTitles:@"Import", nil];
- });
- dispatch_group_wait(
- confirmationGroup, DISPATCH_TIME_FOREVER);
+ dispatch_group_leave(confirmationGroup);
+ }
+ cancelTitle:[PearlStrings get].commonButtonCancel
+ otherTitles:@"Import", nil];
+ });
+ dispatch_group_wait(
+ confirmationGroup, DISPATCH_TIME_FOREVER);
- return confirmation;
- }];
+ return confirmation;
+ }];
switch (result) {
case MPImportResultSuccess:
@@ -281,15 +280,15 @@
}
});
}
- cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Unlock File", nil];
+ cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Unlock File", nil];
return YES;
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
-
+
wrn(@"Received memory warning.");
-
+
[super applicationDidReceiveMemoryWarning:application];
}
@@ -352,8 +351,8 @@
if ([[MPConfig get].iCloud boolValue] != [self.storeManager iCloudEnabled])
[self.storeManager useiCloudStore:[[MPConfig get].iCloud boolValue] alertUser:YES];
if ([[MPiOSConfig get].sendInfo boolValue]) {
- if ([PearlLogger get].autoprintLevel > PearlLogLevelInfo)
- [PearlLogger get].autoprintLevel = PearlLogLevelInfo;
+ if ([PearlLogger get].printLevel > PearlLogLevelInfo)
+ [PearlLogger get].printLevel = PearlLogLevelInfo;
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].rememberLogin boolValue] forKey:@"rememberLogin"];
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].iCloud boolValue] forKey:@"iCloud"];
@@ -396,11 +395,14 @@
? @"YES": @"NO", @"showQuickStart",
[[PearlConfig get].firstRun boolValue]
? @"YES": @"NO", @"firstRun",
- [[PearlConfig get].launchCount description], @"launchCount",
+ [[PearlConfig get].launchCount description],
+ @"launchCount",
[[PearlConfig get].askForReviews boolValue]
? @"YES": @"NO", @"askForReviews",
- [[PearlConfig get].reviewAfterLaunches description], @"reviewAfterLaunches",
- [PearlConfig get].reviewedVersion, @"reviewedVersion",
+ [[PearlConfig get].reviewAfterLaunches description],
+ @"reviewAfterLaunches",
+ [PearlConfig get].reviewedVersion,
+ @"reviewedVersion",
nil]];
}
}
@@ -433,8 +435,8 @@
if (buttonIndex_ == [alert_ firstOtherButtonIndex] + 1)
// Show Passwords
[self exportShowPasswords:YES];
- } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Safe Export", @"Show Passwords", nil];
- } otherTitles:nil];
+ } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Safe Export", @"Show Passwords", nil];
+ } otherTitles:nil];
}
- (void)exportShowPasswords:(BOOL)showPasswords {
@@ -442,11 +444,10 @@
if (![MFMailComposeViewController canSendMail]) {
[PearlAlert showAlertWithTitle:@"Cannot Send Mail"
message:
- @"Your device is not yet set up for sending mail.\n"
- @"Close Master Password, go into Settings and add a Mail account."
+ @"Your device is not yet set up for sending mail.\n"
+ @"Close Master Password, go into Settings and add a Mail account."
viewStyle:UIAlertViewStyleDefault
- initAlert:nil tappedButtonBlock:nil
- cancelTitle:[PearlStrings get].commonButtonOkay
+ initAlert:nil tappedButtonBlock:nil cancelTitle:[PearlStrings get].commonButtonOkay
otherTitles:nil];
return;
}
@@ -456,18 +457,18 @@
if (showPasswords)
message = PearlString(@"Export of Master Password sites with passwords included.\n"
- @"REMINDER: Make sure nobody else sees this file! Passwords are visible!\n\n\n"
- @"--\n"
- @"%@\n"
- @"Master Password %@, build %@",
+ @"REMINDER: Make sure nobody else sees this file! Passwords are visible!\n\n\n"
+ @"--\n"
+ @"%@\n"
+ @"Master Password %@, build %@",
self.activeUser.name,
[PearlInfoPlist get].CFBundleShortVersionString,
[PearlInfoPlist get].CFBundleVersion);
else
message = PearlString(@"Backup of Master Password sites.\n\n\n"
- @"--\n"
- @"%@\n"
- @"Master Password %@, build %@",
+ @"--\n"
+ @"%@\n"
+ @"Master Password %@, build %@",
self.activeUser.name,
[PearlInfoPlist get].CFBundleShortVersionString,
[PearlInfoPlist get].CFBundleVersion);
@@ -481,13 +482,13 @@
[composer setMessageBody:message isHTML:NO];
[composer addAttachmentData:
[exportedSites dataUsingEncoding:NSUTF8StringEncoding] mimeType:@"text/plain"
- fileName:PearlString(@"%@ (%@).mpsites",
- self.activeUser.name,
- [exportDateFormatter stringFromDate:[NSDate date]])];
+ fileName:PearlString(@"%@ (%@).mpsites",
+ self.activeUser.name,
+ [exportDateFormatter stringFromDate:[NSDate date]])];
[self.window.rootViewController presentModalViewController:composer animated:YES];
}
-- (void)changeMasterPasswordFor:(MPUserEntity *)user didResetBlock:(void(^)(void))didReset {
+- (void)changeMasterPasswordFor:(MPUserEntity *)user didResetBlock:(void (^)(void))didReset {
[PearlAlert showAlertWithTitle:@"Changing Master Password"
message:
@@ -508,11 +509,10 @@
didReset();
[TestFlight passCheckpoint:MPCheckpointChangeMP];
- [[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointChangeMP
- attributes:nil];
+ [[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointChangeMP attributes:nil];
}
- cancelTitle:[PearlStrings get].commonButtonAbort
- otherTitles:[PearlStrings get].commonButtonContinue, nil];
+ cancelTitle:[PearlStrings get].commonButtonAbort
+ otherTitles:[PearlStrings get].commonButtonContinue, nil];
}
#pragma mark - PearlConfigDelegate
@@ -540,7 +540,7 @@
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert firstOtherButtonIndex])
return;
- } otherTitles:@"Retry", nil];
+ } otherTitles:@"Retry", nil];
return;
case MFMailComposeResultCancelled:
break;
@@ -581,7 +581,7 @@
initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
[self ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
}
- cancelTitle:[PearlStrings get].commonButtonThanks otherTitles:nil];
+ cancelTitle:[PearlStrings get].commonButtonThanks otherTitles:nil];
return;
}
@@ -590,7 +590,7 @@
return;
if (buttonIndex == [alert firstOtherButtonIndex] + 1)
[manager useiCloudStore:YES alertUser:NO];
- } cancelTitle:@"Leave iCloud Off" otherTitles:@"Explain?", @"Enable iCloud", nil];
+ } cancelTitle:@"Leave iCloud Off" otherTitles:@"Explain?", @"Enable iCloud", nil];
}
}
}
diff --git a/MasterPassword/iOS/MPUnlockViewController.h b/MasterPassword/iOS/MPUnlockViewController.h
index b4cb6693..ad57d1c4 100644
--- a/MasterPassword/iOS/MPUnlockViewController.h
+++ b/MasterPassword/iOS/MPUnlockViewController.h
@@ -19,11 +19,12 @@
@property (weak, nonatomic) IBOutlet UILabel *oldNameLabel;
@property (weak, nonatomic) IBOutlet UIButton *avatarTemplate;
@property (weak, nonatomic) IBOutlet UIView *createPasswordTipView;
-@property (weak, nonatomic) IBOutlet UILabel *deleteTip;
+@property (weak, nonatomic) IBOutlet UILabel *tip;
@property (weak, nonatomic) IBOutlet UIView *passwordTipView;
@property (weak, nonatomic) IBOutlet UILabel *passwordTipLabel;
@property (weak, nonatomic) IBOutlet UIView *wordWall;
@property (strong, nonatomic) IBOutlet UILongPressGestureRecognizer *targetedUserActionGesture;
+@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *loadingUsersIndicator;
@property (nonatomic, strong) UIColor *avatarShadowColor;
diff --git a/MasterPassword/iOS/MPUnlockViewController.m b/MasterPassword/iOS/MPUnlockViewController.m
index b81dc5da..715ecc9a 100644
--- a/MasterPassword/iOS/MPUnlockViewController.m
+++ b/MasterPassword/iOS/MPUnlockViewController.m
@@ -34,11 +34,12 @@
@synthesize nameLabel, oldNameLabel;
@synthesize avatarTemplate;
@synthesize createPasswordTipView;
-@synthesize deleteTip;
+@synthesize tip;
@synthesize passwordTipView;
@synthesize passwordTipLabel;
@synthesize wordWall;
@synthesize targetedUserActionGesture;
+@synthesize loadingUsersIndicator;
@synthesize avatarShadowColor = _avatarShadowColor;
@synthesize wordWallAnimating = _wordWallAnimating;
@synthesize wordList = _wordList;
@@ -154,6 +155,8 @@
[self updateUsers];
}];
+ [self updateLayoutAnimated:NO allowScroll:YES completion:nil];
+
[super viewDidLoad];
}
@@ -165,13 +168,14 @@
[self setAvatarsView:nil];
[self setNameLabel:nil];
[self setAvatarTemplate:nil];
- [self setDeleteTip:nil];
+ [self setTip:nil];
[self setPasswordTipView:nil];
[self setPasswordTipLabel:nil];
[self setTargetedUserActionGesture:nil];
[self setWordWall:nil];
[self setCreatePasswordTipView:nil];
[self setPasswordFieldLabel:nil];
+ [self setLoadingUsersIndicator:nil];
[super viewDidUnload];
}
@@ -202,9 +206,19 @@
- (void)updateUsers {
+ NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextIfReady];
+ if (!moc) {
+ self.tip.text = @"Loading...";
+ [self.loadingUsersIndicator startAnimating];
+ return;
+ }
+
+ self.tip.text = @"Tap and hold to delete or reset.";
+ [self.loadingUsersIndicator stopAnimating];
+
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPUserEntity class])];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO]];
- NSArray *users = [[MPAppDelegate managedObjectContextIfReady] executeFetchRequest:fetchRequest error:nil];
+ NSArray *users = [moc executeFetchRequest:fetchRequest error:nil];
// Clean up avatars.
for (UIView *subview in [self.avatarsView subviews])
@@ -390,7 +404,6 @@
self.nameLabel.backgroundColor = [UIColor blackColor];
self.oldNameLabel.center = self.nameLabel.center;
self.avatarShadowColor = [UIColor whiteColor];
- self.deleteTip.alpha = 0;
} else
if (!self.selectedUser && self.passwordView.alpha == 1) {
// User was just deselected.
@@ -402,7 +415,6 @@
self.nameLabel.backgroundColor = [UIColor clearColor];
self.oldNameLabel.center = self.nameLabel.center;
self.avatarShadowColor = [UIColor lightGrayColor];
- self.deleteTip.alpha = 0.5;
}
// Lay out the word wall.
@@ -463,7 +475,7 @@
}
// Lay out user name label.
- self.nameLabel.text = targetedUser? targetedUser.name: @"New User";
+ self.nameLabel.text = targetedAvatar? targetedUser? targetedUser.name: @"New User": nil;
self.nameLabel.bounds = CGRectSetHeight(self.nameLabel.bounds,
[self.nameLabel.text sizeWithFont:self.nameLabel.font
constrainedToSize:CGSizeMake(self.nameLabel.bounds.size.width - 10, 100)
diff --git a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard
index 40915bb3..9c69f411 100644
--- a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard
+++ b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard
@@ -1414,6 +1414,10 @@ You could use the word wall for inspiration in finding a memorable master passw
+
+
+
+
@@ -1422,7 +1426,8 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
+
@@ -1853,6 +1858,7 @@ You could use the word wall for inspiration in finding a memorable master passw
+
@@ -1922,7 +1928,8 @@ You could use the word wall for inspiration in finding a memorable master passw
-
+
+
@@ -1944,4 +1951,4 @@ You could use the word wall for inspiration in finding a memorable master passw
-
\ No newline at end of file
+
diff --git a/Tests/Tests.m b/Tests/Tests.m
index e2e243e7..e2b0d02c 100644
--- a/Tests/Tests.m
+++ b/Tests/Tests.m
@@ -13,7 +13,7 @@
- (void)setUp
{
dbg(@"======================= TEST SET-UP ======================");
- [PearlLogger get].autoprintLevel = PearlLogLevelTrace;
+ [PearlLogger get].printLevel = PearlLogLevelTrace;
[super setUp];