Fix unlock screen when MOC unavailable.
[REMOVED] Disable TestFlight for release, it doesn't work anyway. [FIXED] Properly handle unlock screen when there is no MOC yet. [FIXED] Some log statements format strings & arguments.
This commit is contained in:
		
							
								
								
									
										2
									
								
								External/Pearl
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								External/Pearl
									
									
									
									
										vendored
									
									
								
							 Submodule External/Pearl updated: f81514bfd8...cc97c1be4c
									
								
							@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -1414,6 +1414,10 @@ You could use the word wall for  inspiration in finding a memorable master passw
 | 
			
		||||
                                </subviews>
 | 
			
		||||
                                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
 | 
			
		||||
                            </view>
 | 
			
		||||
                            <activityIndicatorView opaque="NO" contentMode="scaleToFill" hidesWhenStopped="YES" animating="YES" style="whiteLarge" id="XuP-pi-ygN">
 | 
			
		||||
                                <rect key="frame" x="142" y="415" width="37" height="37"/>
 | 
			
		||||
                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
 | 
			
		||||
                            </activityIndicatorView>
 | 
			
		||||
                        </subviews>
 | 
			
		||||
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
 | 
			
		||||
                    </view>
 | 
			
		||||
@@ -1422,7 +1426,8 @@ You could use the word wall for  inspiration in finding a memorable master passw
 | 
			
		||||
                        <outlet property="avatarTemplate" destination="Ten-ig-gog" id="0ZZ-z5-d5m"/>
 | 
			
		||||
                        <outlet property="avatarsView" destination="Blg-F1-9NA" id="2NL-jU-IMI"/>
 | 
			
		||||
                        <outlet property="createPasswordTipView" destination="xWL-xQ-KjX" id="Pa1-Bk-pW2"/>
 | 
			
		||||
                        <outlet property="deleteTip" destination="DBJ-Qi-ZcF" id="VXD-Zc-UYi"/>
 | 
			
		||||
                        <outlet property="tip" destination="DBJ-Qi-ZcF" id="VXD-Zc-UYi"/>
 | 
			
		||||
                        <outlet property="loadingUsersIndicator" destination="XuP-pi-ygN" id="idh-aH-sDL"/>
 | 
			
		||||
                        <outlet property="nameLabel" destination="0NM-NI-7UR" id="GBg-Ry-sqj"/>
 | 
			
		||||
                        <outlet property="oldNameLabel" destination="8s0-nT-Aoq" id="plu-1H-MVc"/>
 | 
			
		||||
                        <outlet property="passwordField" destination="rTR-7Q-X8o" id="Vsn-uO-4lO"/>
 | 
			
		||||
@@ -1853,6 +1858,7 @@ You could use the word wall for  inspiration in finding a memorable master passw
 | 
			
		||||
                <relationship kind="action" name="incrementPasswordCounter"/>
 | 
			
		||||
                <relationship kind="action" name="infoOutdatedAlert"/>
 | 
			
		||||
                <relationship kind="action" name="resetPasswordCounter:" candidateClass="UILongPressGestureRecognizer"/>
 | 
			
		||||
                <relationship kind="action" name="searchOutdatedElements"/>
 | 
			
		||||
                <relationship kind="action" name="toggleUser"/>
 | 
			
		||||
                <relationship kind="action" name="upgradePassword"/>
 | 
			
		||||
                <relationship kind="outlet" name="actionsTipContainer" candidateClass="UIView"/>
 | 
			
		||||
@@ -1922,7 +1928,8 @@ You could use the word wall for  inspiration in finding a memorable master passw
 | 
			
		||||
                <relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
 | 
			
		||||
                <relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
 | 
			
		||||
                <relationship kind="outlet" name="createPasswordTipView" candidateClass="UIView"/>
 | 
			
		||||
                <relationship kind="outlet" name="deleteTip" candidateClass="UILabel"/>
 | 
			
		||||
                <relationship kind="outlet" name="tip" candidateClass="UILabel"/>
 | 
			
		||||
                <relationship kind="outlet" name="loadingUsersIndicator" candidateClass="UIActivityIndicatorView"/>
 | 
			
		||||
                <relationship kind="outlet" name="nameLabel" candidateClass="UILabel"/>
 | 
			
		||||
                <relationship kind="outlet" name="oldNameLabel" candidateClass="UILabel"/>
 | 
			
		||||
                <relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
 | 
			
		||||
@@ -1944,4 +1951,4 @@ You could use the word wall for  inspiration in finding a memorable master passw
 | 
			
		||||
    <inferredMetricsTieBreakers>
 | 
			
		||||
        <segue reference="9Bs-cD-ddF"/>
 | 
			
		||||
    </inferredMetricsTieBreakers>
 | 
			
		||||
</document>
 | 
			
		||||
</document>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
- (void)setUp
 | 
			
		||||
{
 | 
			
		||||
    dbg(@"======================= TEST SET-UP ======================");
 | 
			
		||||
    [PearlLogger get].autoprintLevel = PearlLogLevelTrace;
 | 
			
		||||
    [PearlLogger get].printLevel = PearlLogLevelTrace;
 | 
			
		||||
 | 
			
		||||
    [super setUp];
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user