diff --git a/External/Pearl b/External/Pearl index ea7054e3..2ecab2a0 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit ea7054e328bd7162d1f5a56a0f64a3eed6e3fc66 +Subproject commit 2ecab2a0d29b60754ec90eaabcb1cde835dbe294 diff --git a/MasterPassword/ObjC/MPAppDelegate_Shared.m b/MasterPassword/ObjC/MPAppDelegate_Shared.m index 369c150a..ad495b2a 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Shared.m +++ b/MasterPassword/ObjC/MPAppDelegate_Shared.m @@ -17,7 +17,7 @@ + (MPAppDelegate_Shared *)get { #if TARGET_OS_IPHONE - return (MPAppDelegate_Shared *)[UIApplication sharedApplication].delegate; + return (MPAppDelegate_Shared *)UIApp.delegate; #elif defined (__MAC_OS_X_VERSION_MIN_REQUIRED) return (MPAppDelegate_Shared *)[NSApplication sharedApplication].delegate; #else diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m index 3895422d..22e07fc3 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Store.m +++ b/MasterPassword/ObjC/MPAppDelegate_Store.m @@ -103,13 +103,13 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, delegate:self]; #if TARGET_OS_IPHONE - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification object:[UIApplication sharedApplication] + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification object:UIApp queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [[self mainManagedObjectContext] saveToStore]; }]; [[NSNotificationCenter defaultCenter] - addObserverForName:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication] + addObserverForName:UIApplicationWillResignActiveNotification object:UIApp queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [[self mainManagedObjectContext] saveToStore]; diff --git a/MasterPassword/ObjC/iOS/MPAppViewController.m b/MasterPassword/ObjC/iOS/MPAppViewController.m index 45198fe9..4c7d3222 100644 --- a/MasterPassword/ObjC/iOS/MPAppViewController.m +++ b/MasterPassword/ObjC/iOS/MPAppViewController.m @@ -26,7 +26,7 @@ @"app" : @"gorillas" } ); - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/lyndir/gorillas/id302275459?mt=8"]]; + [UIApp openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/lyndir/gorillas/id302275459?mt=8"]]; } - (IBAction)deblock:(UIButton *)sender { @@ -35,7 +35,7 @@ @"app" : @"deblock" } ); - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/lyndir/deblock/id325058485?mt=8"]]; + [UIApp openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/lyndir/deblock/id325058485?mt=8"]]; } @end diff --git a/MasterPassword/ObjC/iOS/MPAppsViewController.m b/MasterPassword/ObjC/iOS/MPAppsViewController.m index d3e988d2..6415a12c 100644 --- a/MasterPassword/ObjC/iOS/MPAppsViewController.m +++ b/MasterPassword/ObjC/iOS/MPAppsViewController.m @@ -61,7 +61,7 @@ - (void)viewWillAppear:(BOOL)animated { - [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; + [UIApp setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; MPCheckpoint( MPCheckpointApps, nil ); [self.pageViewController setViewControllers:@[ [self.pageVCs objectAtIndex:1] ] direction:UIPageViewControllerNavigationDirectionForward @@ -84,7 +84,7 @@ - (void)viewWillDisappear:(BOOL)animated { - [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; + [UIApp setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; [super viewWillDisappear:animated]; } diff --git a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m index 51739c9a..e75c1d72 100644 --- a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m +++ b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m @@ -24,6 +24,16 @@ @implementation MPElementListAllViewController +- (BOOL)prefersStatusBarHidden { + + return NO; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + + return UIStatusBarStyleLightContent; +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; diff --git a/MasterPassword/ObjC/iOS/MPGuideViewController.h b/MasterPassword/ObjC/iOS/MPGuideViewController.h index 1e32afac..c55481b0 100644 --- a/MasterPassword/ObjC/iOS/MPGuideViewController.h +++ b/MasterPassword/ObjC/iOS/MPGuideViewController.h @@ -25,6 +25,7 @@ @property(weak, nonatomic) IBOutlet UITextField *contentText; @property(weak, nonatomic) IBOutlet UIButton *largePlayButton; @property(weak, nonatomic) IBOutlet UIButton *smallPlayButton; +@property(weak, nonatomic) IBOutlet UIView *alertTip; - (IBAction)play; - (IBAction)close; diff --git a/MasterPassword/ObjC/iOS/MPGuideViewController.m b/MasterPassword/ObjC/iOS/MPGuideViewController.m index a5942d33..4eeeeec3 100644 --- a/MasterPassword/ObjC/iOS/MPGuideViewController.m +++ b/MasterPassword/ObjC/iOS/MPGuideViewController.m @@ -24,16 +24,21 @@ return NO; } -- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { - - return UIInterfaceOrientationPortrait; -} - - (BOOL)prefersStatusBarHidden { return NO; } +- (UIStatusBarStyle)preferredStatusBarStyle { + + return UIStatusBarStyleLightContent; +} + +- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { + + return UIInterfaceOrientationPortrait; +} + - (void)viewDidLoad { [super viewDidLoad]; @@ -43,6 +48,7 @@ self.usernameTip.hidden = NO; self.typeTip.hidden = NO; self.toolTip.hidden = NO; + self.alertTip.hidden = NO; self.tickCount = 30; } @@ -50,27 +56,44 @@ - (void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:animated]; - if (![super respondsToSelector:@selector(prefersStatusBarHidden)]) - [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; inf(@"Guide will appear."); [super viewWillAppear:animated]; if (self.navigationController) { // Via setup - [self.navigationController setNavigationBarHidden:YES animated:animated]; self.smallPlayButton.hidden = YES; + self.siteNameTip.alpha = 0; self.content.alpha = 0; self.content.frame = CGRectSetHeight( self.content.frame, 180 ); self.contentTip.alpha = 0; + self.contentButton.highlighted = NO; self.usernameTip.alpha = 0; + self.usernameButton.highlighted = NO; self.typeTip.alpha = 0; + self.typeButton.highlighted = NO; self.toolTip.alpha = 0; + self.toolButton.highlighted = NO; + self.alertTip.alpha = 0; } else { // Via segue self.largePlayButton.hidden = YES; + + self.siteNameTip.alpha = 1; + self.content.alpha = 1; + self.content.frame = CGRectSetHeight( self.content.frame, 231 ); + self.contentTip.alpha = 1; + self.contentTipText.text = @"Tap to copy"; + self.contentButton.highlighted = NO; + self.usernameTip.alpha = 1; + self.usernameButton.highlighted = NO; + self.typeTip.alpha = 1; + self.typeButton.highlighted = NO; + self.toolTip.alpha = 0; + self.toolButton.highlighted = NO; + self.alertTip.alpha = 1; } } @@ -86,7 +109,6 @@ - (void)viewWillDisappear:(BOOL)animated { inf(@"Guide will disappear."); - [self.navigationController setNavigationBarHidden:NO animated:animated]; [super viewWillDisappear:animated]; } @@ -132,6 +154,7 @@ self.usernameTip.alpha = 0; self.typeTip.alpha = 0; self.toolTip.alpha = 0; + self.alertTip.alpha = 0; }]; } else if (self.currentTick < 10) { @@ -139,9 +162,11 @@ self.siteNameTip.alpha = 0; self.content.alpha = 1; self.contentTip.alpha = 1; + self.contentTipText.text = @"Your password"; self.usernameTip.alpha = 0; self.typeTip.alpha = 0; self.toolTip.alpha = 0; + self.alertTip.alpha = 0; }]; } else if (self.currentTick < 15) { @@ -149,12 +174,13 @@ self.siteNameTip.alpha = 0; self.content.alpha = 1; self.contentTip.alpha = 1; - self.contentButton.highlighted = YES; self.contentTipText.text = @"Tap to copy"; + self.contentButton.highlighted = YES; self.usernameTip.alpha = 0; self.typeTip.alpha = 0; self.toolButton.highlighted = NO; self.toolTip.alpha = 0; + self.alertTip.alpha = 0; }]; } else if (self.currentTick < 20) { @@ -164,11 +190,11 @@ self.content.frame = CGRectSetHeight( self.content.frame, 231 ); self.contentTip.alpha = 0; self.contentButton.highlighted = NO; - self.contentTipText.text = @"Use this password"; self.usernameButton.highlighted = YES; self.usernameTip.alpha = 1; self.typeTip.alpha = 0; self.toolTip.alpha = 0; + self.alertTip.alpha = 0; }]; } else if (self.currentTick < 25) { @@ -181,6 +207,7 @@ self.typeTip.alpha = 1; self.typeButton.highlighted = YES; self.toolTip.alpha = 0; + self.alertTip.alpha = 0; }]; } else if (self.currentTick < 30) { @@ -193,6 +220,7 @@ self.typeButton.highlighted = NO; self.toolButton.highlighted = YES; self.toolTip.alpha = 1; + self.alertTip.alpha = 0; self.contentText.text = @"XupuMajf4'Hafh"; }]; } @@ -209,6 +237,7 @@ self.typeTip.alpha = 1; self.toolButton.highlighted = NO; self.toolTip.alpha = 0; + self.alertTip.alpha = 1; }]; } } diff --git a/MasterPassword/ObjC/iOS/MPMainViewController.m b/MasterPassword/ObjC/iOS/MPMainViewController.m index c3d06146..2d8582da 100644 --- a/MasterPassword/ObjC/iOS/MPMainViewController.m +++ b/MasterPassword/ObjC/iOS/MPMainViewController.m @@ -122,9 +122,9 @@ - (void)viewWillAppear:(BOOL)animated { - [self.navigationController setNavigationBarHidden:NO animated:animated]; if (![super respondsToSelector:@selector(prefersStatusBarHidden)]) - [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; + [UIApp setStatusBarHidden:NO withAnimation:animated? UIStatusBarAnimationSlide: UIStatusBarAnimationNone]; + [self.navigationController setNavigationBarHidden:NO animated:animated]; MPElementEntity *activeElement = [self activeElementForMainThread]; if (activeElement.user != [[MPiOSAppDelegate get] activeUserForMainThread]) @@ -149,11 +149,6 @@ inf(@"Main will appear"); - // Sometimes, the search bar gets stuck in some sort of first-responder mode that it can't get out of... - [[self.view.window findFirstResponderInHierarchy] resignFirstResponder]; - - // Needed for when we appear after a modal VC dismisses: - // We can't present until the other modal VC has been fully dismissed and presenting in -viewWillAppear: will fail. [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) { MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:moc]; if ([MPAlgorithmDefault migrateUser:activeUser inContext:moc] && !self.suppressOutdatedAlert) @@ -908,7 +903,7 @@ return NO; } - [[UIApplication sharedApplication] openURL:[request URL]]; + [UIApp openURL:[request URL]]; return NO; } diff --git a/MasterPassword/ObjC/iOS/MPUnlockViewController.m b/MasterPassword/ObjC/iOS/MPUnlockViewController.m index 4162b040..4b542cce 100644 --- a/MasterPassword/ObjC/iOS/MPUnlockViewController.m +++ b/MasterPassword/ObjC/iOS/MPUnlockViewController.m @@ -207,9 +207,9 @@ - (void)viewWillAppear:(BOOL)animated { inf(@"Lock screen will appear"); - [self.navigationController setNavigationBarHidden:YES animated:animated]; if (![super respondsToSelector:@selector(prefersStatusBarHidden)]) - [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; + [UIApp setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; + [self.navigationController setNavigationBarHidden:YES animated:animated]; [[MPiOSAppDelegate get] signOutAnimated:NO]; @@ -1031,7 +1031,7 @@ navigationType:(UIWebViewNavigationType)navigationType { if (navigationType == UIWebViewNavigationTypeLinkClicked) { - [[UIApplication sharedApplication] openURL:[request URL]]; + [UIApp openURL:[request URL]]; return NO; } @@ -1130,17 +1130,17 @@ if (buttonIndex == [sheet firstOtherButtonIndex]) { // Google+ - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://plus.google.com/116256327773442623984/about"]]; + [UIApp openURL:[NSURL URLWithString:@"https://plus.google.com/116256327773442623984/about"]]; return; } if (buttonIndex == [sheet firstOtherButtonIndex] + 1) { // Facebook - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.facebook.com/masterpasswordapp"]]; + [UIApp openURL:[NSURL URLWithString:@"https://www.facebook.com/masterpasswordapp"]]; return; } if (buttonIndex == [sheet firstOtherButtonIndex] + 2) { // Twitter - UIApplication *application = [UIApplication sharedApplication]; + UIApplication *application = UIApp; for (NSString *candidate in @[ @"twitter://user?screen_name=%@", // Twitter @"tweetbot:///user_profile/%@", // TweetBot @@ -1172,7 +1172,7 @@ } if (buttonIndex == [sheet firstOtherButtonIndex] + 4) { // GitHub - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://github.com/Lyndir/MasterPassword"]]; + [UIApp openURL:[NSURL URLWithString:@"https://github.com/Lyndir/MasterPassword"]]; return; } } cancelTitle:[PearlStrings get].commonButtonCancel diff --git a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard index b9639c7a..b0d0b3fa 100644 --- a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard +++ b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard @@ -1855,29 +1855,36 @@ If you set a custom password, it will be encrypted before it is saved to the clo - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2515,309 +2522,356 @@ You can make passwords for anything, like email addresses, sites or real-world t - + - + - - + + - - - - - - + + - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + • Use the short site name (eg. apple.com), don't include the prefix (eg. www). + • Use generated passwords. If you ever lose your user or phone, recreating the user will resurrect them from thin air. + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -2945,6 +2999,7 @@ However, it means that anyone who finds your device unlocked can do the same. + diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 3eb52f76..4c08f7f0 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -256,6 +256,7 @@ DAD3127215528CD200A3F9ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DAD312BF1552A1BD00A3F9ED /* libLocalytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD3127115528CD200A3F9ED /* libLocalytics.a */; }; DAD312C21552A22700A3F9ED /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD312C01552A20800A3F9ED /* libsqlite3.dylib */; }; + DAE1EF2217E942DE00BC0086 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DAE1EF2417E942DE00BC0086 /* Localizable.strings */; }; DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; }; DAFC5656172C573B00CB5CC5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DAFC5683172C57EC00CB5CC5 /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAFC5665172C57EC00CB5CC5 /* IASKAppSettingsViewController.m */; }; @@ -1173,6 +1174,7 @@ DACA29BB1705E2DE002C6C22 /* UIColor+HSV.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+HSV.m"; sourceTree = ""; }; DAD3127115528CD200A3F9ED /* libLocalytics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLocalytics.a; sourceTree = BUILT_PRODUCTS_DIR; }; DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + DAE1EF2317E942DE00BC0086 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; DAEBC45214F6364500987BF6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; DAFC5655172C573B00CB5CC5 /* libInAppSettingsKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInAppSettingsKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; DAFC5659172C573B00CB5CC5 /* InAppSettingsKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "InAppSettingsKit-Prefix.pch"; sourceTree = ""; }; @@ -2356,6 +2358,7 @@ DACA26971705DF81002C6C22 /* Google+ */, DACA26951705DF81002C6C22 /* Localytics */, DACA26931705DF81002C6C22 /* TestFlight */, + DAE1EF2417E942DE00BC0086 /* Localizable.strings */, ); name = Resources; path = ../../Resources; @@ -3200,6 +3203,7 @@ DABD3FCB1712446200CF925C /* cloud@2x.png in Resources */, DABD3FCE1714F45C00CF925C /* identity.png in Resources */, DABD3FCF1714F45C00CF925C /* identity@2x.png in Resources */, + DAE1EF2217E942DE00BC0086 /* Localizable.strings in Resources */, DA5A09DF171A70E4005284AB /* play.png in Resources */, DA5A09E0171A70E4005284AB /* play@2x.png in Resources */, DA5A09EA171BB0F7005284AB /* unlocked.png in Resources */, @@ -3439,6 +3443,14 @@ name = InfoPlist.strings; sourceTree = ""; }; + DAE1EF2417E942DE00BC0086 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + DAE1EF2317E942DE00BC0086 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; DAFE45FA15039823003ABA7C /* Pearl.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/MasterPassword/Resources/en.lproj/Localizable.strings b/MasterPassword/Resources/en.lproj/Localizable.strings new file mode 100644 index 00000000..d7dfa97d --- /dev/null +++ b/MasterPassword/Resources/en.lproj/Localizable.strings @@ -0,0 +1,11 @@ +/* + MasterPassword.strings + MasterPassword-iOS + + Created by Maarten Billemont on 2013-09-17. + Copyright (c) 2013 Lyndir. All rights reserved. +*/ +"review.message" = +"Has %@ been useful to you?\ +\ +It would mean a lot if you could review this version and tell your friends about its benefits."; \ No newline at end of file