Emergency generator, action pictograms.
[ADDED] Emergency Generator! [ADDED] Easier method for just using the master password algorithm bare. [UPDATED] Pictograms in action popup and centering of text.
This commit is contained in:
parent
c31df49599
commit
ac1358a0ec
Binary file not shown.
@ -2,7 +2,7 @@
|
||||
// Crashlytics.h
|
||||
// Crashlytics
|
||||
//
|
||||
// Copyright 2012 Crashlytics, Inc. All rights reserved.
|
||||
// Copyright 2013 Crashlytics, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@ -148,12 +148,27 @@ OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
|
||||
/**
|
||||
* Returns the session identifier for the crash report.
|
||||
**/
|
||||
- (NSString *)identifier;
|
||||
@property (nonatomic, readonly) NSString *identifier;
|
||||
|
||||
/**
|
||||
* Returns the custom key value data for the crash report.
|
||||
**/
|
||||
- (NSDictionary *)customKeys;
|
||||
@property (nonatomic, readonly) NSDictionary *customKeys;
|
||||
|
||||
/**
|
||||
* Returns the CFBundleVersion of the application that crashed.
|
||||
**/
|
||||
@property (nonatomic, readonly) NSString *bundleVersion;
|
||||
|
||||
/**
|
||||
* Returns the CFBundleShortVersionString of the application that crashed.
|
||||
**/
|
||||
@property (nonatomic, readonly) NSString *bundleShortVersionString;
|
||||
|
||||
/**
|
||||
* Returns the date that the application crashed at.
|
||||
**/
|
||||
@property (nonatomic, readonly) NSDate *crashedOnDate;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -15,13 +15,13 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.7</string>
|
||||
<string>2.0.8</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0200.07.00</string>
|
||||
<string>0200.08.00</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>iphoneos</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
|
BIN
External/Crashlytics.framework/run
vendored
BIN
External/Crashlytics.framework/run
vendored
Binary file not shown.
@ -38,6 +38,7 @@
|
||||
- (Class)classOfType:(MPElementType)type;
|
||||
|
||||
- (NSString *)generateContentForElement:(MPElementGeneratedEntity *)element usingKey:(MPKey *)key;
|
||||
- (NSString *)generateContentNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter usingKey:(MPKey *)key;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -205,8 +205,6 @@
|
||||
|
||||
- (NSString *)generateContentForElement:(MPElementGeneratedEntity *)element usingKey:(MPKey *)key {
|
||||
|
||||
static NSDictionary *MPTypes_ciphers = nil;
|
||||
|
||||
if (!element)
|
||||
return nil;
|
||||
|
||||
@ -223,19 +221,25 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [self generateContentNamed:element.name ofType:element.type withCounter:element.counter usingKey:key];
|
||||
}
|
||||
|
||||
- (NSString *)generateContentNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter usingKey:(MPKey *)key {
|
||||
|
||||
static NSDictionary *MPTypes_ciphers = nil;
|
||||
if (MPTypes_ciphers == nil)
|
||||
MPTypes_ciphers = [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ciphers"
|
||||
withExtension:@"plist"]];
|
||||
MPTypes_ciphers = [NSDictionary dictionaryWithContentsOfURL:
|
||||
[[NSBundle mainBundle] URLForResource:@"ciphers" withExtension:@"plist"]];
|
||||
|
||||
// Determine the seed whose bytes will be used for calculating a password
|
||||
uint32_t ncounter = htonl(element.counter), nnameLength = htonl(element.name.length);
|
||||
uint32_t ncounter = htonl(counter), nnameLength = htonl(name.length);
|
||||
NSData *counterBytes = [NSData dataWithBytes:&ncounter length:sizeof(ncounter)];
|
||||
NSData *nameLengthBytes = [NSData dataWithBytes:&nnameLength length:sizeof(nnameLength)];
|
||||
trc(@"seed from: hmac-sha256(%@, 'com.lyndir.masterpassword' | %@ | %@ | %@)", [key.keyData encodeBase64], [nameLengthBytes encodeHex], element.name, [counterBytes encodeHex]);
|
||||
trc(@"seed from: hmac-sha256(%@, 'com.lyndir.masterpassword' | %@ | %@ | %@)", [key.keyData encodeBase64], [nameLengthBytes encodeHex], name, [counterBytes encodeHex]);
|
||||
NSData *seed = [[NSData dataByConcatenatingDatas:
|
||||
[@"com.lyndir.masterpassword" dataUsingEncoding:NSUTF8StringEncoding],
|
||||
nameLengthBytes,
|
||||
[element.name dataUsingEncoding:NSUTF8StringEncoding],
|
||||
[name dataUsingEncoding:NSUTF8StringEncoding],
|
||||
counterBytes,
|
||||
nil]
|
||||
hmacWith:PearlHashSHA256 key:key.keyData];
|
||||
@ -244,10 +248,10 @@
|
||||
|
||||
// Determine the cipher from the first seed byte.
|
||||
assert([seed length]);
|
||||
NSArray *typeCiphers = [[MPTypes_ciphers valueForKey:[self classNameOfType:element.type]]
|
||||
valueForKey:[self nameOfType:element.type]];
|
||||
NSArray *typeCiphers = [[MPTypes_ciphers valueForKey:[self classNameOfType:type]]
|
||||
valueForKey:[self nameOfType:type]];
|
||||
NSString *cipher = [typeCiphers objectAtIndex:htons(seedBytes[0]) % [typeCiphers count]];
|
||||
trc(@"type %@, ciphers: %@, selected: %@", [self nameOfType:element.type], typeCiphers, cipher);
|
||||
trc(@"type %@, ciphers: %@, selected: %@", [self nameOfType:type], typeCiphers, cipher);
|
||||
|
||||
// Encode the content, character by character, using subsequent seed bytes and the cipher.
|
||||
assert([seed length] >= [cipher length] + 1);
|
||||
|
@ -46,39 +46,22 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)generateContentForElement:(MPElementGeneratedEntity *)element usingKey:(MPKey *)key {
|
||||
- (NSString *)generateContentNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter usingKey:(MPKey *)key {
|
||||
|
||||
static NSDictionary *MPTypes_ciphers = nil;
|
||||
|
||||
if (!element)
|
||||
return nil;
|
||||
|
||||
if (!(element.type & MPElementTypeClassGenerated)) {
|
||||
err(@"Incorrect type (is not MPElementTypeClassGenerated): %@, for: %@", [self nameOfType:element.type], element.name);
|
||||
return nil;
|
||||
}
|
||||
if (!element.name.length) {
|
||||
err(@"Missing name.");
|
||||
return nil;
|
||||
}
|
||||
if (!key.keyData.length) {
|
||||
err(@"Missing key.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (MPTypes_ciphers == nil)
|
||||
MPTypes_ciphers = [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ciphers"
|
||||
withExtension:@"plist"]];
|
||||
MPTypes_ciphers = [NSDictionary dictionaryWithContentsOfURL:
|
||||
[[NSBundle mainBundle] URLForResource:@"ciphers" withExtension:@"plist"]];
|
||||
|
||||
// Determine the seed whose bytes will be used for calculating a password
|
||||
uint32_t ncounter = htonl(element.counter), nnameLength = htonl(element.name.length);
|
||||
uint32_t ncounter = htonl(counter), nnameLength = htonl(name.length);
|
||||
NSData *counterBytes = [NSData dataWithBytes:&ncounter length:sizeof(ncounter)];
|
||||
NSData *nameLengthBytes = [NSData dataWithBytes:&nnameLength length:sizeof(nnameLength)];
|
||||
trc(@"seed from: hmac-sha256(%@, 'com.lyndir.masterpassword' | %@ | %@ | %@)", [key.keyData encodeBase64], [nameLengthBytes encodeHex], element.name, [counterBytes encodeHex]);
|
||||
trc(@"seed from: hmac-sha256(%@, 'com.lyndir.masterpassword' | %@ | %@ | %@)", [key.keyData encodeBase64], [nameLengthBytes encodeHex], name, [counterBytes encodeHex]);
|
||||
NSData *seed = [[NSData dataByConcatenatingDatas:
|
||||
[@"com.lyndir.masterpassword" dataUsingEncoding:NSUTF8StringEncoding],
|
||||
nameLengthBytes,
|
||||
[element.name dataUsingEncoding:NSUTF8StringEncoding],
|
||||
[name dataUsingEncoding:NSUTF8StringEncoding],
|
||||
counterBytes,
|
||||
nil]
|
||||
hmacWith:PearlHashSHA256 key:key.keyData];
|
||||
@ -87,10 +70,10 @@
|
||||
|
||||
// Determine the cipher from the first seed byte.
|
||||
assert([seed length]);
|
||||
NSArray *typeCiphers = [[MPTypes_ciphers valueForKey:[self classNameOfType:element.type]]
|
||||
valueForKey:[self nameOfType:element.type]];
|
||||
NSArray *typeCiphers = [[MPTypes_ciphers valueForKey:[self classNameOfType:type]]
|
||||
valueForKey:[self nameOfType:type]];
|
||||
NSString *cipher = [typeCiphers objectAtIndex:seedBytes[0] % [typeCiphers count]];
|
||||
trc(@"type %@, ciphers: %@, selected: %@", [self nameOfType:element.type], typeCiphers, cipher);
|
||||
trc(@"type %@, ciphers: %@, selected: %@", [self nameOfType:type], typeCiphers, cipher);
|
||||
|
||||
// Encode the content, character by character, using subsequent seed bytes and the cipher.
|
||||
assert([seed length] >= [cipher length] + 1);
|
||||
|
@ -761,11 +761,11 @@
|
||||
}
|
||||
}
|
||||
cancelTitle:[PearlStrings get].commonButtonCancel destructiveTitle:nil otherTitles:
|
||||
@"? FAQ",
|
||||
@"ℹ Quick Guide",
|
||||
@"⚙ Preferences",
|
||||
@"⬇ Other Apps",
|
||||
@"✉ Feedback",
|
||||
@"? FAQ ",
|
||||
@"ⓘ Quick Guide ",
|
||||
@"⚙ Preferences ",
|
||||
@"⚐ Other Apps ",
|
||||
@"✎ Feedback ",
|
||||
nil];
|
||||
}
|
||||
|
||||
|
@ -78,28 +78,17 @@
|
||||
if (cellType != NSNotFound && cellType & MPElementTypeClassGenerated) {
|
||||
[(UITextField *) [cell viewWithTag:2] setText:@"..."];
|
||||
|
||||
NSManagedObjectID *selectedElementOID = [selectedElement objectID];
|
||||
[MPAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
|
||||
NSError *error;
|
||||
MPElementGeneratedEntity *selectedElement_ = (MPElementGeneratedEntity *) [moc existingObjectWithID:selectedElementOID error:&error];
|
||||
if (!selectedElement_) {
|
||||
err(@"Failed to retrieve element for password preview: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *name = selectedElement.name;
|
||||
NSUInteger counter = ((MPElementGeneratedEntity *)selectedElement).counter;
|
||||
|
||||
MPElementGeneratedEntity *cellElement = [NSEntityDescription insertNewObjectForEntityForName:[MPAlgorithmDefault classNameOfType:cellType]
|
||||
inManagedObjectContext:moc];
|
||||
cellElement.type = cellType;
|
||||
cellElement.name = selectedElement_.name;
|
||||
cellElement.user = selectedElement_.user;
|
||||
cellElement.loginName = selectedElement_.loginName;
|
||||
cellElement.version = MPAlgorithmDefaultVersion;
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{
|
||||
NSString *typeContent = [MPAlgorithmDefault generateContentNamed:name ofType:cellType
|
||||
withCounter:counter usingKey:[MPAppDelegate get].key];
|
||||
|
||||
NSString *typeContent = [cellElement.algorithm generateContentForElement:cellElement usingKey:[MPAppDelegate get].key];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[(UITextField *) [[tableView cellForRowAtIndexPath:indexPath] viewWithTag:2] setText:typeContent];
|
||||
});
|
||||
}];
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
[(UITextField *)[[tableView cellForRowAtIndexPath:indexPath] viewWithTag:2] setText:typeContent];
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
return cell;
|
||||
|
@ -26,6 +26,14 @@
|
||||
@property (strong, nonatomic) IBOutlet UILongPressGestureRecognizer *targetedUserActionGesture;
|
||||
@property (weak, nonatomic) IBOutlet UIView *uiContainer;
|
||||
@property (weak, nonatomic) IBOutlet UIWebView *newsView;
|
||||
@property (weak, nonatomic) IBOutlet UIView *emergencyGeneratorContainer;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *emergencyName;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *emergencyMasterPassword;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *emergencySite;
|
||||
@property (weak, nonatomic) IBOutlet UIStepper *emergencyCounterStepper;
|
||||
@property (weak, nonatomic) IBOutlet UISegmentedControl *emergencyType;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *emergencyCounter;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *emergencyPassword;
|
||||
|
||||
@property (nonatomic, strong) UIColor *avatarShadowColor;
|
||||
|
||||
@ -35,5 +43,6 @@
|
||||
- (IBAction)google:(UIButton *)sender;
|
||||
- (IBAction)mail:(UIButton *)sender;
|
||||
- (IBAction)add:(UIButton *)sender;
|
||||
- (IBAction)closeEmergency;
|
||||
|
||||
@end
|
||||
|
@ -20,6 +20,9 @@
|
||||
@property (nonatomic) BOOL wordWallAnimating;
|
||||
@property (nonatomic, strong) NSArray *wordList;
|
||||
|
||||
@property(nonatomic, strong) NSOperationQueue *emergencyQueue;
|
||||
@property(nonatomic, strong) MPKey *emergencyKey;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPUnlockViewController {
|
||||
@ -104,12 +107,12 @@
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
|
||||
|
||||
return UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
|
||||
|
||||
[self.newsView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.masterpasswordapp.com/news.html"]]];
|
||||
|
||||
self.avatarToUserOID = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
@ -117,11 +120,24 @@
|
||||
[self.avatarsView addGestureRecognizer:self.targetedUserActionGesture];
|
||||
self.avatarsView.decelerationRate = UIScrollViewDecelerationRateFast;
|
||||
self.avatarsView.clipsToBounds = NO;
|
||||
self.tip.text = @"";
|
||||
self.nameLabel.layer.cornerRadius = 5;
|
||||
self.avatarTemplate.hidden = YES;
|
||||
self.spinner.alpha = 0;
|
||||
self.passwordTipView.hidden = NO;
|
||||
self.createPasswordTipView.hidden = NO;
|
||||
self.emergencyPassword.text = @"";
|
||||
self.emergencyGeneratorContainer.alpha = 0;
|
||||
self.emergencyGeneratorContainer.hidden = YES;
|
||||
self.emergencyQueue = [NSOperationQueue new];
|
||||
[self.emergencyCounterStepper addTargetBlock:^(id sender, UIControlEvents event) {
|
||||
self.emergencyCounter.text = PearlString( @"%d", (NSUInteger)self.emergencyCounterStepper.value);
|
||||
|
||||
[self updateEmergencyPassword];
|
||||
} forControlEvents:UIControlEventValueChanged];
|
||||
[self.emergencyType addTargetBlock:^(id sender, UIControlEvents event) {
|
||||
[self updateEmergencyPassword];
|
||||
} forControlEvents:UIControlEventValueChanged];
|
||||
|
||||
NSMutableArray *wordListLines = [NSMutableArray arrayWithCapacity:27413];
|
||||
[[[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"dictionary" withExtension:@"lst"]]
|
||||
@ -147,6 +163,7 @@
|
||||
}];
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil
|
||||
usingBlock:^(NSNotification *note) {
|
||||
[self closeEmergencyAnimated:NO];
|
||||
self.uiContainer.alpha = 0;
|
||||
}];
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil
|
||||
@ -198,6 +215,8 @@
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
|
||||
inf(@"Lock screen will disappear");
|
||||
[self closeEmergencyAnimated:animated];
|
||||
|
||||
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
[self.navigationController setNavigationBarHidden:NO animated:animated];
|
||||
@ -206,6 +225,26 @@
|
||||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder {
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
|
||||
|
||||
if (motion == UIEventSubtypeMotionShake) {
|
||||
[[self.view findFirstResponderInHierarchy] resignFirstResponder];
|
||||
|
||||
self.emergencyGeneratorContainer.alpha = 0;
|
||||
self.emergencyGeneratorContainer.hidden = NO;
|
||||
[UIView animateWithDuration:1 animations:^{
|
||||
self.emergencyGeneratorContainer.alpha = 1;
|
||||
} completion:^(BOOL finished) {
|
||||
[self.emergencyName becomeFirstResponder];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateUsers {
|
||||
|
||||
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextForThreadIfReady];
|
||||
@ -316,7 +355,7 @@
|
||||
|
||||
- (void)showNewUserNameAlertFor:(MPUserEntity *)newUser inContext:(NSManagedObjectContext *)moc
|
||||
completion:(void (^)(BOOL finished))completion {
|
||||
|
||||
|
||||
[PearlAlert showAlertWithTitle:@"Enter Your Name"
|
||||
message:nil viewStyle:UIAlertViewStylePlainTextInput
|
||||
initAlert:^(UIAlertView *alert, UITextField *firstField) {
|
||||
@ -339,7 +378,7 @@
|
||||
} cancelTitle:@"Try Again" otherTitles:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Save
|
||||
[moc performBlockAndWait:^{
|
||||
newUser.name = name;
|
||||
@ -694,41 +733,149 @@
|
||||
|
||||
[textField resignFirstResponder];
|
||||
|
||||
[self setSpinnerActive:YES];
|
||||
if (textField == self.emergencyName) {
|
||||
if (![self.emergencyMasterPassword.text length])
|
||||
[self.emergencyMasterPassword becomeFirstResponder];
|
||||
}
|
||||
|
||||
if (self.selectedUser.keyID)
|
||||
[self tryMasterPassword];
|
||||
else if (textField == self.emergencyMasterPassword) {
|
||||
if (![self.emergencySite.text length])
|
||||
[self.emergencySite becomeFirstResponder];
|
||||
}
|
||||
|
||||
else
|
||||
[PearlAlert showAlertWithTitle:@"New Master Password"
|
||||
message:@"Please confirm the spelling of this new master password."
|
||||
viewStyle:UIAlertViewStyleSecureTextInput
|
||||
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
||||
[self setSpinnerActive:NO];
|
||||
|
||||
if (buttonIndex == [alert cancelButtonIndex])
|
||||
return;
|
||||
|
||||
if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) {
|
||||
[PearlAlert showAlertWithTitle:@"Incorrect Master Password"
|
||||
message:
|
||||
@"The password you entered doesn't match with the master password you tried to use. "
|
||||
@"You've probably mistyped one of them.\n\n"
|
||||
@"Give it another try."
|
||||
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil
|
||||
cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil];
|
||||
return;
|
||||
}
|
||||
else if (textField == self.passwordField) {
|
||||
[self setSpinnerActive:YES];
|
||||
|
||||
if (self.selectedUser.keyID)
|
||||
[self tryMasterPassword];
|
||||
}
|
||||
cancelTitle:[PearlStrings get].commonButtonCancel
|
||||
otherTitles:[PearlStrings get].commonButtonContinue, nil];
|
||||
|
||||
else
|
||||
[PearlAlert showAlertWithTitle:@"New Master Password"
|
||||
message:@"Please confirm the spelling of this new master password."
|
||||
viewStyle:UIAlertViewStyleSecureTextInput
|
||||
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
||||
[self setSpinnerActive:NO];
|
||||
|
||||
if (buttonIndex == [alert cancelButtonIndex])
|
||||
return;
|
||||
|
||||
if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) {
|
||||
[PearlAlert showAlertWithTitle:@"Incorrect Master Password"
|
||||
message:
|
||||
@"The password you entered doesn't match with the master password you tried to use. "
|
||||
@"You've probably mistyped one of them.\n\n"
|
||||
@"Give it another try."
|
||||
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil
|
||||
cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
[self tryMasterPassword];
|
||||
}
|
||||
cancelTitle:[PearlStrings get].commonButtonCancel
|
||||
otherTitles:[PearlStrings get].commonButtonContinue, nil];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||
|
||||
if (textField == self.emergencyName || textField == self.emergencyMasterPassword)
|
||||
[self updateEmergencyKey];
|
||||
|
||||
if (textField == self.emergencySite)
|
||||
[self updateEmergencyPassword];
|
||||
}
|
||||
|
||||
- (void)updateEmergencyKey {
|
||||
|
||||
if (![self.emergencyMasterPassword.text length] || ![self.emergencyName.text length])
|
||||
return;
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
self.emergencyPassword.text = @"...";
|
||||
|
||||
NSString *masterPassword = self.emergencyMasterPassword.text;
|
||||
NSString *userName = self.emergencyName.text;
|
||||
|
||||
[self.emergencyQueue addOperationWithBlock:^{
|
||||
self.emergencyKey = [MPAlgorithmDefault keyForPassword:masterPassword ofUserNamed:userName];
|
||||
|
||||
[self updateEmergencyPassword];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateEmergencyPassword {
|
||||
|
||||
if (!self.emergencyKey || ![self.emergencySite.text length])
|
||||
return;
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
self.emergencyPassword.text = @"...";
|
||||
|
||||
NSString *name = self.emergencySite.text;
|
||||
NSUInteger counter = (NSUInteger)self.emergencyCounterStepper.value;
|
||||
MPElementType type;
|
||||
switch (self.emergencyType.selectedSegmentIndex) {
|
||||
case 0:
|
||||
type = MPElementTypeGeneratedMaximum;
|
||||
break;
|
||||
case 1:
|
||||
type = MPElementTypeGeneratedLong;
|
||||
break;
|
||||
case 2:
|
||||
type = MPElementTypeGeneratedMedium;
|
||||
break;
|
||||
case 3:
|
||||
type = MPElementTypeGeneratedBasic;
|
||||
break;
|
||||
case 4:
|
||||
type = MPElementTypeGeneratedShort;
|
||||
break;
|
||||
case 5:
|
||||
type = MPElementTypeGeneratedPIN;
|
||||
break;
|
||||
default:
|
||||
Throw(@"Unsupported type index: %d", self.emergencyType.selectedSegmentIndex);
|
||||
}
|
||||
|
||||
[self.emergencyQueue addOperationWithBlock:^{
|
||||
NSString *content = [MPAlgorithmDefault generateContentNamed:name ofType:type withCounter:counter usingKey:self.emergencyKey];
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
self.emergencyPassword.text = content;
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (IBAction)closeEmergency {
|
||||
|
||||
[self closeEmergencyAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)closeEmergencyAnimated:(BOOL)animated {
|
||||
|
||||
[[self.emergencyGeneratorContainer findFirstResponderInHierarchy] resignFirstResponder];
|
||||
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.5 animations:^{
|
||||
[self closeEmergencyAnimated:NO];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
self.emergencyName.text = @"";
|
||||
self.emergencyMasterPassword.text = @"";
|
||||
self.emergencySite.text = @"";
|
||||
self.emergencyCounterStepper.value = 0;
|
||||
self.emergencyPassword.text = @"";
|
||||
self.emergencyGeneratorContainer.alpha = 0;
|
||||
self.emergencyGeneratorContainer.hidden = YES;
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity
|
||||
@ -756,12 +903,12 @@
|
||||
|
||||
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
|
||||
navigationType:(UIWebViewNavigationType)navigationType {
|
||||
|
||||
|
||||
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
|
||||
[[UIApplication sharedApplication] openURL:[request URL]];
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -815,7 +962,7 @@
|
||||
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil cancelTitle:nil otherTitles:@"OK", nil];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SLComposeViewController *vc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
|
||||
[vc setInitialText:@"I've started doing passwords properly thanks to Master Password for iOS."];
|
||||
[vc addImage:[UIImage imageNamed:@"iTunesArtwork-Rounded"]];
|
||||
@ -922,7 +1069,7 @@
|
||||
MPUserEntity *selectedUser = (MPUserEntity *)[moc existingObjectWithID:_selectedUserOID error:&error];
|
||||
if (!selectedUser)
|
||||
err(@"Failed to retrieve selected user: %@", error);
|
||||
|
||||
|
||||
return selectedUser;
|
||||
}
|
||||
|
||||
|
@ -535,7 +535,7 @@ Your passwords will be AES-encrypted with your master password.</string>
|
||||
<color key="shadowColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="S3cre7^Pa$swcrD" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" id="fiX-10-fif" userLabel="Text Field - Content">
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="SadwGafy7^Sidu" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" id="fiX-10-fif" userLabel="Text Field - Content">
|
||||
<rect key="frame" x="20" y="26" width="280" height="60"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint=""/>
|
||||
@ -1092,7 +1092,7 @@ L4m3P4sSw0rD</string>
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" id="PHH-XC-9QQ">
|
||||
<view contentMode="scaleToFill" id="PHH-XC-9QQ" userLabel="View - UI Container">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
@ -1455,6 +1455,145 @@ 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>
|
||||
<view alpha="0.30000000000000016" contentMode="scaleToFill" id="KNa-Xb-RuE" userLabel="View - Emergency Generator">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" id="vdf-Kn-Sle">
|
||||
<rect key="frame" x="0.0" y="20" width="320" height="346"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_panel_display.png" id="jLf-TI-anP">
|
||||
<rect key="frame" x="11" y="0.0" width="298" height="346"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<rect key="contentStretch" x="0.050000000000000003" y="0.10000000000000001" width="0.89999999999999991" height="0.79999999999999982"/>
|
||||
</imageView>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Emergency Generator" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" id="shF-6G-WyQ">
|
||||
<rect key="frame" x="30" y="20" width="260" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="GillSans-Bold" family="Gill Sans" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Generate your password without logging in. Great for if you're borrowing a friend's device or are having trouble logging in." lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" id="cgB-L6-VbR">
|
||||
<rect key="frame" x="30" y="49" width="260" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" name="GillSans-LightItalic" family="Gill Sans" pointSize="14"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Name" minimumFontSize="17" id="esC-1q-bE7">
|
||||
<rect key="frame" x="41" y="109" width="240" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Nbn-Rv-sP1" id="yRn-2W-KeI"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Master Password" minimumFontSize="17" id="Yvd-Hm-fuw">
|
||||
<rect key="frame" x="41" y="147" width="240" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES" secureTextEntry="YES"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Nbn-Rv-sP1" id="tqK-8C-p2c"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Site Name" minimumFontSize="17" id="YeH-3J-oY4">
|
||||
<rect key="frame" x="41" y="185" width="240" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" keyboardAppearance="alert" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Nbn-Rv-sP1" id="w1h-rQ-fIF"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" id="pa9-d6-vQt">
|
||||
<rect key="frame" x="41" y="262" width="285" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<size key="shadowOffset" width="0.0" height="1"/>
|
||||
</label>
|
||||
<stepper opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" id="D49-fo-7FA">
|
||||
<rect key="frame" x="187" y="260" width="94" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
</stepper>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="0" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="TJC-xD-fjQ">
|
||||
<rect key="frame" x="79" y="263" width="100" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="TmC-YR-JKg">
|
||||
<rect key="frame" x="265" y="0.0" width="44" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint="" label="Close"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||
<state key="normal" image="icon_cancel.png">
|
||||
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="closeEmergency" destination="Nbn-Rv-sP1" eventType="touchUpInside" id="TgI-O2-XiW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="Kucy9-RimuTich" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" id="WAX-03-cSy" userLabel="Text Field - Content">
|
||||
<rect key="frame" x="20" y="292" width="280" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" hint=""/>
|
||||
<color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
|
||||
</textField>
|
||||
<view hidden="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" id="sD9-hR-UAI" userLabel="View - Content Tip">
|
||||
<rect key="frame" x="55" y="320" width="210" height="60"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" id="Lua-xm-WX6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="210" height="60"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Copied!" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" id="fXa-HL-2OW">
|
||||
<rect key="frame" x="19" y="9" width="171" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" id="LfH-XT-9Vt">
|
||||
<rect key="frame" x="41" y="223" width="240" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<segments>
|
||||
<segment title="Max"/>
|
||||
<segment title="Long"/>
|
||||
<segment title="Med"/>
|
||||
<segment title="Basic"/>
|
||||
<segment title="Short"/>
|
||||
<segment title="PIN"/>
|
||||
</segments>
|
||||
<color key="tintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
@ -1467,6 +1606,14 @@ 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="emergencyCounter" destination="TJC-xD-fjQ" id="jrf-nb-soB"/>
|
||||
<outlet property="emergencyCounterStepper" destination="D49-fo-7FA" id="hj2-CL-zxq"/>
|
||||
<outlet property="emergencyGeneratorContainer" destination="KNa-Xb-RuE" id="6jt-vU-L2Q"/>
|
||||
<outlet property="emergencyMasterPassword" destination="Yvd-Hm-fuw" id="pnx-sH-P8R"/>
|
||||
<outlet property="emergencyName" destination="esC-1q-bE7" id="ifH-bh-MhW"/>
|
||||
<outlet property="emergencyPassword" destination="WAX-03-cSy" id="lLN-BO-OQ8"/>
|
||||
<outlet property="emergencySite" destination="YeH-3J-oY4" id="h0w-om-4vd"/>
|
||||
<outlet property="emergencyType" destination="LfH-XT-9Vt" id="pku-x3-i9h"/>
|
||||
<outlet property="nameLabel" destination="0NM-NI-7UR" id="GBg-Ry-sqj"/>
|
||||
<outlet property="newsView" destination="rGU-aZ-XVm" id="p1r-Wf-YIY"/>
|
||||
<outlet property="oldNameLabel" destination="8s0-nT-Aoq" id="plu-1H-MVc"/>
|
||||
@ -2649,178 +2796,6 @@ However, it means that anyone who finds your device unlocked can do the same.</s
|
||||
<image name="ui_textfield.png" width="158" height="34"/>
|
||||
<image name="unlocked.png" width="84" height="80"/>
|
||||
</resources>
|
||||
<classes>
|
||||
<class className="MPAppViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="deblock:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="gorillas:" candidateClass="UIButton"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPAppsViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppsViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="exit"/>
|
||||
<relationship kind="outlet" name="pagePositionView" candidateClass="UIImageView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListAllViewController" superclassName="MPElementListController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListAllViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="add:"/>
|
||||
<relationship kind="action" name="close:"/>
|
||||
<relationship kind="outlet" name="navigationBar" candidateClass="UINavigationBar"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="delegate"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListSearchController" superclassName="MPElementListController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListSearchController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="searchDisplayController" candidateClass="UISearchDisplayController"/>
|
||||
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPGuideViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPGuideViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="close"/>
|
||||
<relationship kind="action" name="play"/>
|
||||
<relationship kind="action" name="toggleVolume"/>
|
||||
<relationship kind="outlet" name="content" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="contentText" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="contentTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentTipText" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="largePlayButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="progress" candidateClass="UIProgressView"/>
|
||||
<relationship kind="outlet" name="siteNameTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="smallPlayButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="toolButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="toolTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="typeTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="usernameButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="usernameTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="volumeButton" candidateClass="UIButton"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPMainViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPMainViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="action:" candidateClass="UIBarButtonItem"/>
|
||||
<relationship kind="action" name="closeAlert"/>
|
||||
<relationship kind="action" name="closeOutdatedAlert"/>
|
||||
<relationship kind="action" name="copyContent"/>
|
||||
<relationship kind="action" name="editLoginName:" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="action" name="editPassword"/>
|
||||
<relationship kind="action" name="incrementPasswordCounter"/>
|
||||
<relationship kind="action" name="infoOutdatedAlert"/>
|
||||
<relationship kind="action" name="panHelpDown:" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="action" name="panHelpUp:" candidateClass="UIPanGestureRecognizer"/>
|
||||
<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"/>
|
||||
<relationship kind="outlet" name="alertBody" candidateClass="UITextView"/>
|
||||
<relationship kind="outlet" name="alertContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="alertTitle" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="contentContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="contentTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="contentTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="displayContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="helpContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="helpView" candidateClass="UIWebView"/>
|
||||
<relationship kind="outlet" name="loginNameContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="loginNameField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="loginNameTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="loginNameTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="outdatedAlertBack" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="outdatedAlertCloseButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="outdatedAlertContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="passwordCounter" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordEdit" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordIncrementer" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordUpgrade" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordUser" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="pullDownGesture" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="pullDownView" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="pullUpGesture" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="pullUpView" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="searchDelegate" candidateClass="MPElementListSearchController"/>
|
||||
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="siteName" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="toolTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="toolTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="toolTipEditIcon" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="typeTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPPreferencesViewController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPPreferencesViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="didToggleSwitch:" candidateClass="UISwitch"/>
|
||||
<relationship kind="action" name="settings:"/>
|
||||
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
|
||||
<relationship kind="outlet" name="changeMPCell" candidateClass="UITableViewCell"/>
|
||||
<relationship kind="outlet" name="defaultTypeLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="exportCell" candidateClass="UITableViewCell"/>
|
||||
<relationship kind="outlet" name="savePasswordSwitch" candidateClass="UISwitch"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPSetupViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPSetupViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="close:" candidateClass="UIBarButtonItem"/>
|
||||
<relationship kind="outlet" name="cloudSwitch" candidateClass="UISwitch"/>
|
||||
<relationship kind="outlet" name="rememberLoginSwitch" candidateClass="UISwitch"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPTypeViewController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPTypeViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="recommendedTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPUnlockViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPUnlockViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="add:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="facebook:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="google:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="mail:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="targetedUserAction:" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="action" name="twitter:" candidateClass="UIButton"/>
|
||||
<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="nameLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="newsView" candidateClass="UIWebView"/>
|
||||
<relationship kind="outlet" name="oldNameLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="passwordFieldLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordTipLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordTipView" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="passwordView" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="spinner" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="targetedUserActionGesture" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="tip" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="uiContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="wordWall" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="PearlNavigationController" superclassName="UINavigationController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/PearlNavigationController.h"/>
|
||||
</class>
|
||||
</classes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<nil key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
|
Loading…
Reference in New Issue
Block a user