From 589d892633bf54eadccce0145adc51a523808fc8 Mon Sep 17 00:00:00 2001 From: Alexandr Barenboym Date: Sat, 10 Jan 2015 00:24:50 +0200 Subject: [PATCH 1/2] All titles and prompt strings moved from localization to config. It wasn't working from cocoapods. Also this is more intuitive when u can configure those things from code and not thinking where exactly u should add those localized strings for 3rd party bundle. Added localization files for english and russian in demo app. New method lock screen. U can call it when app goes to background and it will handle everything itself. It will check if there is pass code set, and if input is already displayed. Also lock screen doesn't have close button. Probably button for lock screen should be added in config, in case somebody whants to provide help or different action in case user is stack on lock screen. I will add it later. Also, if input is already shown while displaying lock screen it will be dismissed and replaced by lock screen. Did it to avoid situation when user entered input mode from app and screen has close button, and then u lock ur app and go back. This way u could theoretically close input and gather some info whithout entering pass. --- Example/DMPasscode.xcodeproj/project.pbxproj | 21 ++++ Example/DMPasscode/DMAppDelegate.m | 45 +++++--- .../DMPasscode/en.lproj/Localizable.strings | 17 +++ .../DMPasscode/ru.lproj/Localizable.strings | 17 +++ Pod/Classes/DMPasscode.h | 9 ++ Pod/Classes/DMPasscode.m | 102 +++++++++++++----- Pod/Classes/DMPasscodeConfig.h | 35 ++++++ Pod/Classes/DMPasscodeConfig.m | 19 ++++ .../DMPasscodeInternalViewController.h | 8 +- .../DMPasscodeInternalViewController.m | 39 ++++++- 10 files changed, 263 insertions(+), 49 deletions(-) create mode 100644 Example/DMPasscode/en.lproj/Localizable.strings create mode 100644 Example/DMPasscode/ru.lproj/Localizable.strings diff --git a/Example/DMPasscode.xcodeproj/project.pbxproj b/Example/DMPasscode.xcodeproj/project.pbxproj index fcb7dc9..1ea5683 100644 --- a/Example/DMPasscode.xcodeproj/project.pbxproj +++ b/Example/DMPasscode.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; + 8419BE1B1A606AC200880D45 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8419BE1D1A606AC200880D45 /* Localizable.strings */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -54,6 +55,10 @@ 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 6A7507787FC44B769011E24F /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 7BB550C53786F18EB50CBA9E /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; + 8419BE1C1A606AC200880D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 8419BE1E1A606ADD00880D45 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 8419BE1F1A606ADD00880D45 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 8419BE201A606ADD00880D45 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 96B51248A87F48C3A0A0A014 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 99223ECC932347BCB3D78023 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; C9218A9104BCEE3C6FA88A0C /* Pods-DMPasscode.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DMPasscode.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DMPasscode/Pods-DMPasscode.debug.xcconfig"; sourceTree = ""; }; @@ -129,6 +134,7 @@ 6003F59D195388D20070C39A /* DMAppDelegate.m */, 6003F5A8195388D20070C39A /* Images.xcassets */, 6003F594195388D20070C39A /* Supporting Files */, + 8419BE1D1A606AC200880D45 /* Localizable.strings */, ); path = DMPasscode; sourceTree = ""; @@ -248,6 +254,7 @@ knownRegions = ( en, Base, + ru, ); mainGroup = 6003F581195388D10070C39A; productRefGroup = 6003F58B195388D20070C39A /* Products */; @@ -266,6 +273,7 @@ buildActionMask = 2147483647; files = ( 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, + 8419BE1B1A606AC200880D45 /* Localizable.strings in Resources */, 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -376,6 +384,7 @@ isa = PBXVariantGroup; children = ( 6003F597195388D20070C39A /* en */, + 8419BE1E1A606ADD00880D45 /* ru */, ); name = InfoPlist.strings; sourceTree = ""; @@ -384,10 +393,20 @@ isa = PBXVariantGroup; children = ( 6003F5B9195388D20070C39A /* en */, + 8419BE201A606ADD00880D45 /* ru */, ); name = InfoPlist.strings; sourceTree = ""; }; + 8419BE1D1A606AC200880D45 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 8419BE1C1A606AC200880D45 /* en */, + 8419BE1F1A606ADD00880D45 /* ru */, + ); + name = Localizable.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -469,6 +488,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DMPasscode/DMPasscode-Prefix.pch"; INFOPLIST_FILE = "DMPasscode/DMPasscode-Info.plist"; @@ -483,6 +503,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DMPasscode/DMPasscode-Prefix.pch"; INFOPLIST_FILE = "DMPasscode/DMPasscode-Info.plist"; diff --git a/Example/DMPasscode/DMAppDelegate.m b/Example/DMPasscode/DMAppDelegate.m index 96f23c0..09ba608 100644 --- a/Example/DMPasscode/DMAppDelegate.m +++ b/Example/DMPasscode/DMAppDelegate.m @@ -14,13 +14,11 @@ @implementation DMAppDelegate { UIButton* _setupButton; UIButton* _checkButton; UIButton* _removeButton; - BOOL _showingPasscode; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; - [self.window makeKeyAndVisible]; _rootViewController = [[UIViewController alloc] init]; self.window.rootViewController = _rootViewController; [self addViews]; @@ -37,13 +35,27 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( config.statusBarStyle = UIStatusBarStyleLightContent; [DMPasscode setConfig:config]; */ - + + DMPasscodeConfig* config = [[DMPasscodeConfig alloc] init]; + config.enterNewCodeTitle = NSLocalizedString(@"dmpasscode_enter_new_code", @""); + config.enterCoodeToUnlockTitle = NSLocalizedString(@"dmpasscode_enter_to_unlock", @""); + config.repeatCodeTitle = NSLocalizedString(@"dmpasscode_repeat", @""); + config.noMatchTitle = NSLocalizedString(@"dmpasscode_not_match", @""); + config.okayTitle = NSLocalizedString(@"dmpasscode_okay", @""); + config.leftAttemptsTitle = NSLocalizedString(@"dmpasscode_n_left", @""); + config.touchIdReasonTitle = NSLocalizedString(@"dmpasscode_touchid_reason", @""); + [DMPasscode setConfig:config]; + + [self.window makeKeyAndVisible]; + + [self applicationWillResignActive:application]; + return YES; } - (void)addViews { _setupButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 50, _rootViewController.view.frame.size.width, 50)]; - [_setupButton setTitle:@"Setup" forState:UIControlStateNormal]; + [_setupButton setTitle:NSLocalizedString(@"setup", @"") forState:UIControlStateNormal]; [_setupButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [_setupButton addTarget:self action:@selector(actionSetup:) forControlEvents:UIControlEventTouchUpInside]; [_rootViewController.view addSubview:_setupButton]; @@ -92,21 +104,20 @@ - (void)updateViews { _removeButton.enabled = passcodeSet; } -- (void)applicationDidBecomeActive:(UIApplication *)application { - if ([DMPasscode isPasscodeSet] && !_showingPasscode) { - _showingPasscode = YES; - [DMPasscode showPasscodeInViewController:self.window.rootViewController completion:^(BOOL success) { - if (success) { - NSLog(@"Win"); - }else{ - NSLog(@"Loss"); - } - }]; - } +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + [self applicationWillResignActive:application]; } --(void)applicationWillEnterForeground:(UIApplication *)application{ - _showingPasscode = NO; +- (void)applicationWillResignActive:(UIApplication *)application +{ + [DMPasscode lockScreenWithCompletion:^(BOOL success) { + if (success) { + NSLog(@"Win"); + }else{ + NSLog(@"Loss"); + } + }]; } @end diff --git a/Example/DMPasscode/en.lproj/Localizable.strings b/Example/DMPasscode/en.lproj/Localizable.strings new file mode 100644 index 0000000..b884c04 --- /dev/null +++ b/Example/DMPasscode/en.lproj/Localizable.strings @@ -0,0 +1,17 @@ +/* + Localizable.strings + DMPasscode + + Created by Alex on 09.01.15. + Copyright (c) 2015 Dylan Marriott. All rights reserved. +*/ + +"dmpasscode_enter_new_code" = "Enter new code"; +"dmpasscode_enter_to_unlock" = "Enter code to unlock"; +"dmpasscode_repeat" = "Repeat code"; +"dmpasscode_not_match" = "Codes did not match, please try again."; +"dmpasscode_okay" = "Okay"; +"dmpasscode_n_left" = "%i attempts left"; +"dmpasscode_touchid_reason" = "Authenticate to access locked feature."; + +"setup" = "Setup"; diff --git a/Example/DMPasscode/ru.lproj/Localizable.strings b/Example/DMPasscode/ru.lproj/Localizable.strings new file mode 100644 index 0000000..bbbb22f --- /dev/null +++ b/Example/DMPasscode/ru.lproj/Localizable.strings @@ -0,0 +1,17 @@ +/* + Localizable.strings + DMPasscode + + Created by Alex on 09.01.15. + Copyright (c) 2015 Dylan Marriott. All rights reserved. +*/ + +"dmpasscode_enter_new_code" = "Введите новый код"; +"dmpasscode_enter_to_unlock" = "Введите код, что бы разблокировать"; +"dmpasscode_repeat" = "Повторите код"; +"dmpasscode_not_match" = "Коды не совпали, пожалуйста, попробуйте еще раз."; +"dmpasscode_okay" = "Ок"; +"dmpasscode_n_left" = "Осталось %i попыток"; +"dmpasscode_touchid_reason" = "Авторизуйтесь, что бы получить доступ"; + +"setup" = "Настройка"; diff --git a/Pod/Classes/DMPasscode.h b/Pod/Classes/DMPasscode.h index 23c6f2e..a3632f8 100644 --- a/Pod/Classes/DMPasscode.h +++ b/Pod/Classes/DMPasscode.h @@ -36,6 +36,8 @@ typedef void (^PasscodeCompletionBlock)(BOOL success); */ + (void)showPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion; ++ (void)lockScreenWithCompletion:(PasscodeCompletionBlock)completion; + /** * Remove the passcode from the keychain. */ @@ -55,4 +57,11 @@ typedef void (^PasscodeCompletionBlock)(BOOL success); */ + (void)setConfig:(DMPasscodeConfig *)config; +/** + * Check if a input is already set. + * + * @return BOOL indicating if a passcode is set + */ ++ (BOOL)isShowingPasscode; + @end diff --git a/Pod/Classes/DMPasscode.m b/Pod/Classes/DMPasscode.m index 42dda19..8488fc9 100644 --- a/Pod/Classes/DMPasscode.m +++ b/Pod/Classes/DMPasscode.m @@ -15,21 +15,20 @@ #import #endif -#undef NSLocalizedString -#define NSLocalizedString(key, comment) \ -[bundle localizedStringForKey:(key) value:@"" table:@"DMPasscodeLocalisation"] - static DMPasscode* instance; static const NSString* KEYCHAIN_NAME = @"passcode"; static NSBundle* bundle; @interface DMPasscode () + +@property BOOL showingPasscode; +@property DMPasscodeInternalViewController* passcodeViewController; + @end @implementation DMPasscode { PasscodeCompletionBlock _completion; - DMPasscodeInternalViewController* _passcodeViewController; - int _mode; // 0 = setup, 1 = input + DMPasscodeMode _mode; int _count; NSString* _prevCode; DMPasscodeConfig* _config; @@ -66,6 +65,21 @@ + (void)showPasscodeInViewController:(UIViewController *)viewController completi [instance showPasscodeInViewController:viewController completion:completion]; } ++ (void)lockScreenWithCompletion:(PasscodeCompletionBlock)completion +{ + if (![DMPasscode isPasscodeSet]) + return; + + if ([DMPasscode isShowingPasscode]) { + [instance.passcodeViewController dismissViewControllerAnimated:NO completion:Nil]; + } + + UIWindow* main_window = [[UIApplication sharedApplication] keyWindow]; + [main_window.rootViewController.view endEditing:YES]; + + [instance showPasscodeInViewController:main_window.rootViewController completion:completion animated:NO mode:DMPM_lockScreen]; +} + + (void)removePasscode { [instance removePasscode]; } @@ -78,18 +92,38 @@ + (void)setConfig:(DMPasscodeConfig *)config { [instance setConfig:config]; } ++ (BOOL)isShowingPasscode +{ + return instance.showingPasscode; +} + ++ (void)setShowingPasscode:(BOOL)showing +{ + instance.showingPasscode = showing; +} + #pragma mark - Instance methods - (void)setupPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion { _completion = completion; - [self openPasscodeWithMode:0 viewController:viewController]; + [self openPasscodeWithMode:DMPM_setup viewController:viewController]; +} + +- (void)showPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion +{ + [self showPasscodeInViewController:viewController completion:completion animated:YES]; } -- (void)showPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion { +- (void)showPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion animated:(BOOL)animated +{ + [self showPasscodeInViewController:viewController completion:completion animated:animated mode:DMPM_input]; +} + +- (void)showPasscodeInViewController:(UIViewController *)viewController completion:(PasscodeCompletionBlock)completion animated:(BOOL)animated mode:(DMPasscodeMode)mode{ NSAssert([self isPasscodeSet], @"No passcode set"); _completion = completion; LAContext* context = [[LAContext alloc] init]; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) { - [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"dmpasscode_touchid_reason", nil) reply:^(BOOL success, NSError* error) { + [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:_config.touchIdReasonTitle reply:^(BOOL success, NSError* error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { switch (error.code) { @@ -102,7 +136,7 @@ - (void)showPasscodeInViewController:(UIViewController *)viewController completi case LAErrorTouchIDNotEnrolled: case LAErrorTouchIDNotAvailable: case LAErrorUserFallback: - [self openPasscodeWithMode:1 viewController:viewController]; + [self openPasscodeWithMode:mode viewController:viewController animated:animated]; break; } } else { @@ -112,7 +146,7 @@ - (void)showPasscodeInViewController:(UIViewController *)viewController completi }]; } else { // no touch id available - [self openPasscodeWithMode:1 viewController:viewController]; + [self openPasscodeWithMode:mode viewController:viewController animated:animated]; } } @@ -130,48 +164,62 @@ - (void)setConfig:(DMPasscodeConfig *)config { } #pragma mark - Private -- (void)openPasscodeWithMode:(int)mode viewController:(UIViewController *)viewController { +- (void)openPasscodeWithMode:(DMPasscodeMode)mode viewController:(UIViewController *)viewController +{ + [self openPasscodeWithMode:mode viewController:viewController animated:YES]; +} + +- (void)openPasscodeWithMode:(DMPasscodeMode)mode viewController:(UIViewController *)viewController animated:(BOOL)animated { _mode = mode; _count = 0; - _passcodeViewController = [[DMPasscodeInternalViewController alloc] initWithDelegate:self config:_config]; - DMPasscodeInternalNavigationController* nc = [[DMPasscodeInternalNavigationController alloc] initWithRootViewController:_passcodeViewController]; - [viewController presentViewController:nc animated:YES completion:nil]; - if (_mode == 0) { - [_passcodeViewController setInstructions:NSLocalizedString(@"dmpasscode_enter_new_code", nil)]; - } else if (_mode == 1) { - [_passcodeViewController setInstructions:NSLocalizedString(@"dmpasscode_enter_to_unlock", nil)]; + + self.passcodeViewController = [[DMPasscodeInternalViewController alloc] initWithDelegate:self config:_config mode:_mode]; + DMPasscodeInternalNavigationController* nc = [[DMPasscodeInternalNavigationController alloc] initWithRootViewController:self.passcodeViewController]; + + [viewController presentViewController:nc + animated:animated + completion:^{ + }]; + if (_mode == DMPM_setup) { + [self.passcodeViewController setInstructions:_config.enterNewCodeTitle]; + } else if (_mode == DMPM_input || _mode == DMPM_lockScreen) { + [self.passcodeViewController setInstructions:_config.enterCoodeToUnlockTitle]; } } - (void)closeAndNotify:(BOOL)success { - [_passcodeViewController dismissViewControllerAnimated:YES completion:^() { + [self.passcodeViewController dismissViewControllerAnimated:YES completion:^() { _completion(success); }]; } #pragma mark - DMPasscodeInternalViewControllerDelegate - (void)enteredCode:(NSString *)code { - if (_mode == 0) { + if (_mode == DMPM_setup) { if (_count == 0) { _prevCode = code; - [_passcodeViewController setInstructions:NSLocalizedString(@"dmpasscode_repeat", nil)]; - [_passcodeViewController reset]; + [self.passcodeViewController setInstructions:_config.repeatCodeTitle]; + [self.passcodeViewController reset]; } else if (_count == 1) { if ([code isEqualToString:_prevCode]) { [[DMKeychain defaultKeychain] setObject:code forKey:KEYCHAIN_NAME]; [self closeAndNotify:YES]; } else { - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"dmpasscode_not_match", nil) message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"dmpasscode_okay", nil), nil]; + UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:_config.noMatchTitle + message:nil + delegate:nil + cancelButtonTitle:nil + otherButtonTitles:_config.okayTitle, nil]; [errorAlert show]; [self closeAndNotify:NO]; } } - } else if (_mode == 1) { + } else if (_mode == DMPM_input || _mode == DMPM_lockScreen) { if ([code isEqualToString:[[DMKeychain defaultKeychain] objectForKey:KEYCHAIN_NAME]]) { [self closeAndNotify:YES]; } else { - [_passcodeViewController setErrorMessage:[NSString stringWithFormat:NSLocalizedString(@"dmpasscode_n_left", nil), 2 - _count]]; - [_passcodeViewController reset]; + [self.passcodeViewController setErrorMessage:[NSString stringWithFormat:_config.leftAttemptsTitle, 2 - _count]]; + [self.passcodeViewController reset]; if (_count >= 2) { // max 3 attempts [self closeAndNotify:NO]; } diff --git a/Pod/Classes/DMPasscodeConfig.h b/Pod/Classes/DMPasscodeConfig.h index cfff211..6169cf0 100644 --- a/Pod/Classes/DMPasscodeConfig.h +++ b/Pod/Classes/DMPasscodeConfig.h @@ -91,4 +91,39 @@ */ @property (nonatomic, strong) UIColor * navigationBarTitleColor; +/** + * The new code Title. + */ +@property (nonatomic, strong) NSString* enterNewCodeTitle; + +/** + * The unlock code Title. + */ +@property (nonatomic, strong) NSString* enterCoodeToUnlockTitle; + +/** + * The repeat code Title. + */ +@property (nonatomic, strong) NSString* repeatCodeTitle; + +/** + * The no match Title. + */ +@property (nonatomic, strong) NSString* noMatchTitle; + +/** + * The okay Title. + */ +@property (nonatomic, strong) NSString* okayTitle; + +/** + * The n attempts left Title. + */ +@property (nonatomic, strong) NSString* leftAttemptsTitle; + +/** + * The touch id reason Title. + */ +@property (nonatomic, strong) NSString* touchIdReasonTitle; + @end diff --git a/Pod/Classes/DMPasscodeConfig.m b/Pod/Classes/DMPasscodeConfig.m index 7ed04f4..a825622 100644 --- a/Pod/Classes/DMPasscodeConfig.m +++ b/Pod/Classes/DMPasscodeConfig.m @@ -8,8 +8,20 @@ #import "DMPasscodeConfig.h" +#define NSLocalizedStringPasscode(key, comment) \ +[[DMPasscodeConfig bundleWithName:@"DMPasscode.bundle"] localizedStringForKey:(key) value:@"" table:@"DMPasscodeLocalisation"] + @implementation DMPasscodeConfig ++ (NSBundle*)bundleWithName:(NSString*)name { + NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath]; + NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:name]; + if ([[NSFileManager defaultManager] fileExistsAtPath:frameworkBundlePath]){ + return [NSBundle bundleWithPath:frameworkBundlePath]; + } + return nil; +} + - (instancetype)init { if (self = [super init]) { self.animationsEnabled = YES; @@ -28,6 +40,13 @@ - (instancetype)init { self.navigationBarTitle = @""; self.navigationBarFont = [UIFont systemFontOfSize:16]; self.navigationBarTitleColor = [UIColor darkTextColor]; + self.enterNewCodeTitle = NSLocalizedStringPasscode(@"dmpasscode_enter_new_code", @""); + self.enterCoodeToUnlockTitle = NSLocalizedStringPasscode(@"dmpasscode_enter_to_unlock", @""); + self.repeatCodeTitle = NSLocalizedStringPasscode(@"dmpasscode_repeat", @""); + self.noMatchTitle = NSLocalizedStringPasscode(@"dmpasscode_not_match", @""); + self.okayTitle = NSLocalizedStringPasscode(@"dmpasscode_okay", @""); + self.leftAttemptsTitle = NSLocalizedStringPasscode(@"dmpasscode_n_left", @""); + self.touchIdReasonTitle = NSLocalizedStringPasscode(@"dmpasscode_touchid_reason", @""); } return self; } diff --git a/Pod/Classes/DMPasscodeInternalViewController.h b/Pod/Classes/DMPasscodeInternalViewController.h index b7d0e98..3ec30b9 100644 --- a/Pod/Classes/DMPasscodeInternalViewController.h +++ b/Pod/Classes/DMPasscodeInternalViewController.h @@ -9,6 +9,12 @@ #import #import +typedef enum : NSUInteger { + DMPM_setup, + DMPM_input, + DMPM_lockScreen, +} DMPasscodeMode; + @protocol DMPasscodeInternalViewControllerDelegate - (void)enteredCode:(NSString *)code; @@ -20,7 +26,7 @@ @interface DMPasscodeInternalViewController : UIViewController -- (id)initWithDelegate:(id)delegate config:(DMPasscodeConfig *)config; +- (id)initWithDelegate:(id)delegate config:(DMPasscodeConfig *)config mode:(DMPasscodeMode)mode; - (void)reset; - (void)setErrorMessage:(NSString *)errorMessage; - (void)setInstructions:(NSString *)instructions; diff --git a/Pod/Classes/DMPasscodeInternalViewController.m b/Pod/Classes/DMPasscodeInternalViewController.m index a7be4c9..498d841 100644 --- a/Pod/Classes/DMPasscodeInternalViewController.m +++ b/Pod/Classes/DMPasscodeInternalViewController.m @@ -9,6 +9,13 @@ #import "DMPasscodeInternalViewController.h" #import "DMPasscodeInternalField.h" #import "DMPasscodeConfig.h" +#import "DMPasscode.h" + +@interface DMPasscode () + ++ (void)setShowingPasscode:(BOOL)showing; + +@end @interface DMPasscodeInternalViewController () @end @@ -20,26 +27,50 @@ @implementation DMPasscodeInternalViewController { UILabel* _instructions; UILabel* _error; DMPasscodeConfig* _config; + DMPasscodeMode _mode; } -- (id)initWithDelegate:(id)delegate config:(DMPasscodeConfig *)config { +- (id)initWithDelegate:(id)delegate config:(DMPasscodeConfig *)config mode:(DMPasscodeMode)mode { if (self = [super init]) { _delegate = delegate; _config = config; _instructions = [[UILabel alloc] init]; _error = [[UILabel alloc] init]; _textFields = [[NSMutableArray alloc] init]; + _mode = mode; } return self; } +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + if (_mode == DMPM_input || _mode == DMPM_lockScreen) { + [DMPasscode setShowingPasscode:YES]; + } +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + + if (_mode == DMPM_input || _mode == DMPM_lockScreen) { + [DMPasscode setShowingPasscode:NO]; + } +} + - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = _config.backgroundColor; self.navigationController.navigationBar.barTintColor = _config.navigationBarBackgroundColor; - UIBarButtonItem* closeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(close:)]; - closeItem.tintColor = _config.navigationBarForegroundColor; - self.navigationItem.leftBarButtonItem = closeItem; + + if (_mode != DMPM_lockScreen) { + UIBarButtonItem* closeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(close:)]; + closeItem.tintColor = _config.navigationBarForegroundColor; + self.navigationItem.leftBarButtonItem = closeItem; + } + self.navigationController.navigationBar.barStyle = (UIBarStyle)_config.statusBarStyle; self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName :_config.navigationBarFont, NSForegroundColorAttributeName: _config.navigationBarTitleColor}; From 9dd2d2253f5bc70e11e8e577221c8bc8c53d96e6 Mon Sep 17 00:00:00 2001 From: Alexandr Barenboym Date: Sat, 10 Jan 2015 00:28:18 +0200 Subject: [PATCH 2/2] in case there will be problems with missing project files... --- Example/DMPasscode/ru.lproj/InfoPlist.strings | 2 ++ Example/Tests/ru.lproj/InfoPlist.strings | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 Example/DMPasscode/ru.lproj/InfoPlist.strings create mode 100644 Example/Tests/ru.lproj/InfoPlist.strings diff --git a/Example/DMPasscode/ru.lproj/InfoPlist.strings b/Example/DMPasscode/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example/DMPasscode/ru.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Example/Tests/ru.lproj/InfoPlist.strings b/Example/Tests/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Example/Tests/ru.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ +