diff --git a/KKPasscodeLock.podspec b/KKPasscodeLock.podspec
new file mode 100644
index 0000000..5ddff98
--- /dev/null
+++ b/KKPasscodeLock.podspec
@@ -0,0 +1,14 @@
+Pod::Spec.new do |s|
+ s.name = 'KKPasscodeLock'
+ s.version = '0.1.5'
+ s.license = 'Apache 2.0'
+ s.summary = 'KKPasscodeLock is an iOS toolkit for adding a passcode view controller and passcode settings in ios apps'
+ s.homepage = 'https://github.com/aporat/KKPasscodeLock.git'
+ s.author = { 'Adar Porat' => 'adar.porat@gmail.com' }
+ s.source = { :git => 'https://github.com/aporat/KKPasscodeLock.git' }
+ s.platform = :ios
+ s.source_files = 'src/*.{h,m}'
+ s.resources = "src/KKPasscodeLock.bundle"
+ s.frameworks = 'QuartzCore', 'AudioToolbox', 'Security'
+ s.requires_arc = true
+end
diff --git a/README.mdown b/README.mdown
index 223fca1..5c7b108 100644
--- a/README.mdown
+++ b/README.mdown
@@ -1,17 +1,33 @@
What is KKPasscodeLock?
+
+ 
+
+
KKPasscodeLock is an iOS toolkit for adding a passcode view controller and passcode settings in ios apps.

+

+

Main Features in KKPasscodeLock
-- Either a simple 4 digit passcode (using a numeric keyboard) or a free-text passcode
+- Either a simple 4 digit passcode (using a numeric keyboard) or a free-text passcode (in development)
- Supports universal apps (both iPhone and iPad)
- Advanced passcode settings controller: set & change passcode, turn off/on passcode and passcode tries allowed
- Passcode is saved securly in the device keychain
+
+Using KKPasscodeLock
+
+Using this framework is really easy.
+
+- Add all the source files under the src folder, including KKPasscodeLock.bundle
+- `#import "KKPasscodeLock.h"` where you need it.
+- Add the `AudioToolbox.framework`, `Security.framework` and the `QuartzCore.framework` into your project
+- See the usage of the passcode lock from the sample app
+
Terms of Use
- Provided under the Apache 2.0 License
diff --git a/example/Default-568h@2x.png b/example/Default-568h@2x.png
new file mode 100644
index 0000000..0891b7a
Binary files /dev/null and b/example/Default-568h@2x.png differ
diff --git a/example/Default.png b/example/Default.png
new file mode 100644
index 0000000..4c8ca6f
Binary files /dev/null and b/example/Default.png differ
diff --git a/example/Default@2x.png b/example/Default@2x.png
new file mode 100644
index 0000000..35b84cf
Binary files /dev/null and b/example/Default@2x.png differ
diff --git a/example/KKPasscodeLock/AppDelegate.h b/example/KKPasscodeLock/AppDelegate.h
index 235e555..d304cc1 100644
--- a/example/KKPasscodeLock/AppDelegate.h
+++ b/example/KKPasscodeLock/AppDelegate.h
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,10 +16,11 @@
//
#import
+#import "KKPasscodeLock.h"
-@interface AppDelegate : UIResponder
+@interface AppDelegate : UIResponder
@property (strong, nonatomic) UIWindow *window;
-@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
+@property (nonatomic) IBOutlet UINavigationController *navigationController;
@end
diff --git a/example/KKPasscodeLock/AppDelegate.m b/example/KKPasscodeLock/AppDelegate.m
index bed143f..13d992e 100644
--- a/example/KKPasscodeLock/AppDelegate.m
+++ b/example/KKPasscodeLock/AppDelegate.m
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,36 +24,64 @@ @implementation AppDelegate
@synthesize window = _window;
@synthesize navigationController=_navigationController;
-- (void)dealloc
-{
- [_window release];
- [super dealloc];
-}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
-
- [[KKPasscodeLock sharedLock] setDefaultSettings];
-
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
- self.window.backgroundColor = [UIColor whiteColor];
-
- RootViewController* vc = [[[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil] autorelease];
-
- _navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
- [self.window addSubview:_navigationController.view];
-
-
- [self.window makeKeyAndVisible];
-
-
- return YES;
+
+ [[KKPasscodeLock sharedLock] setDefaultSettings];
+ [KKPasscodeLock sharedLock].eraseOption = NO;
+
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.window.backgroundColor = [UIColor whiteColor];
+
+ RootViewController* vc = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
+
+ _navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
+ [self.window setRootViewController:_navigationController];
+ [self.window makeKeyAndVisible];
+
+ return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
- [[KKPasscodeLock sharedLock] showPasscodeController:self.navigationController];
+ if ([[KKPasscodeLock sharedLock] isPasscodeRequired]) {
+ KKPasscodeViewController *vc = [[KKPasscodeViewController alloc] initWithNibName:nil bundle:nil];
+ vc.mode = KKPasscodeModeEnter;
+ vc.delegate = self;
+
+ dispatch_async(dispatch_get_main_queue(),^ {
+ UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
+
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ nav.modalPresentationStyle = UIModalPresentationFormSheet;
+ nav.navigationBar.barStyle = UIBarStyleBlack;
+ nav.navigationBar.opaque = NO;
+ } else {
+ nav.navigationBar.tintColor = _navigationController.navigationBar.tintColor;
+ nav.navigationBar.translucent = _navigationController.navigationBar.translucent;
+ nav.navigationBar.opaque = _navigationController.navigationBar.opaque;
+ nav.navigationBar.barStyle = _navigationController.navigationBar.barStyle;
+ }
+
+ [_navigationController presentModalViewController:nav animated:NO];
+ });
+
+ }
+}
+
+- (void)shouldEraseApplicationData:(KKPasscodeViewController*)viewController
+{
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"You have entered an incorrect passcode too many times. All account data in this app has been deleted." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
+ [alert show];
}
+- (void)didPasscodeEnteredIncorrectly:(KKPasscodeViewController*)viewController
+{
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"You have entered an incorrect passcode too many times." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
+ [alert show];
+}
+
+
@end
diff --git a/example/KKPasscodeLock/KKPasscodeLock-Info.plist b/example/KKPasscodeLock/KKPasscodeLockDemo-Info.plist
similarity index 94%
rename from example/KKPasscodeLock/KKPasscodeLock-Info.plist
rename to example/KKPasscodeLock/KKPasscodeLockDemo-Info.plist
index 4c95cff..e476ef1 100644
--- a/example/KKPasscodeLock/KKPasscodeLock-Info.plist
+++ b/example/KKPasscodeLock/KKPasscodeLockDemo-Info.plist
@@ -11,7 +11,7 @@
CFBundleIconFiles
CFBundleIdentifier
- com.kosherpenguin.kosherkit.demo.${PRODUCT_NAME:rfc1034identifier}
+ com.kosherpenguin.passcode.demo.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
diff --git a/example/KKPasscodeLock/KKPasscodeLock-Prefix.pch b/example/KKPasscodeLock/KKPasscodeLockDemo-Prefix.pch
similarity index 69%
rename from example/KKPasscodeLock/KKPasscodeLock-Prefix.pch
rename to example/KKPasscodeLock/KKPasscodeLockDemo-Prefix.pch
index 26bc5cb..c2949e1 100644
--- a/example/KKPasscodeLock/KKPasscodeLock-Prefix.pch
+++ b/example/KKPasscodeLock/KKPasscodeLockDemo-Prefix.pch
@@ -1,5 +1,5 @@
//
-// Prefix header for all source files of the 'APPasscodeLock' target in the 'APPasscodeLock' project
+// Prefix header for all source files of the 'KKPasscodeLock' target in the 'KKPasscodeLock' project
//
#import
diff --git a/example/KKPasscodeLock/RootViewController.h b/example/KKPasscodeLock/RootViewController.h
index 567ba9e..08ca127 100755
--- a/example/KKPasscodeLock/RootViewController.h
+++ b/example/KKPasscodeLock/RootViewController.h
@@ -16,11 +16,9 @@
//
#import
+#import "KKPasscodeViewController.h"
-
-@interface RootViewController : UIViewController {
-
-}
+@interface RootViewController : UIViewController
- (IBAction)showPasscode:(id)sender;
diff --git a/example/KKPasscodeLock/RootViewController.m b/example/KKPasscodeLock/RootViewController.m
index 885486e..005771f 100755
--- a/example/KKPasscodeLock/RootViewController.m
+++ b/example/KKPasscodeLock/RootViewController.m
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,19 +21,15 @@
@implementation RootViewController
- (IBAction)showPasscode:(id)sender {
-
- SettingsViewController* settingsViewController = [[[SettingsViewController alloc]
- initWithNibName:@"SettingsViewController" bundle:nil] autorelease];
-
- UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:settingsViewController] autorelease];
-
- [self presentModalViewController:navController animated:YES];
-
+
+ SettingsViewController* settingsViewController = [[SettingsViewController alloc]
+ initWithNibName:@"SettingsViewController" bundle:nil];
+
+ UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:settingsViewController];
+
+ [self presentModalViewController:navController animated:YES];
+
}
-- (void)dealloc
-{
- [super dealloc];
-}
@end
diff --git a/example/KKPasscodeLock/RootViewController.xib b/example/KKPasscodeLock/RootViewController.xib
index 114be7c..401cc80 100755
--- a/example/KKPasscodeLock/RootViewController.xib
+++ b/example/KKPasscodeLock/RootViewController.xib
@@ -1,21 +1,21 @@
- 1280
- 11C74
- 1938
- 1138.23
- 567.00
+ 1536
+ 12C3006
+ 2844
+ 1187.34
+ 625.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- 933
+ 1930
YES
+ IBProxyObject
IBUIButton
- IBUIView
IBUILabel
- IBProxyObject
+ IBUIView
YES
@@ -46,14 +46,13 @@
{{53, 132}, {215, 37}}
-
NO
IBCocoaTouchFramework
0
0
1
Show Settings Controller
-
+
3
MQA
@@ -155,70 +154,14 @@
14
16
+ 280
{{0, 20}, {320, 460}}
-
- 10
-
- 549453824
- {512, 1}
-
- YES
-
- YES
-
-
-
- TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA
-AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA
-AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI
-AAgACAAIAAEAAQABAAE
-
-
-
-
-
-
- groupTableViewBackgroundColor
-
+
IBCocoaTouchFramework
@@ -307,7 +250,7 @@ AAgACAAIAAEAAQABAAE
8.IBPluginDependency
9.IBPluginDependency
-
+
YES
RootViewController
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
@@ -361,7 +304,7 @@ AAgACAAIAAEAAQABAAE
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
-
+
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
@@ -369,6 +312,6 @@ AAgACAAIAAEAAQABAAE
YES
3
- 933
+ 1930
diff --git a/example/KKPasscodeLock/SettingsViewController.h b/example/KKPasscodeLock/SettingsViewController.h
index d6db093..ce2bdbd 100755
--- a/example/KKPasscodeLock/SettingsViewController.h
+++ b/example/KKPasscodeLock/SettingsViewController.h
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,8 @@
//
#import
+#import "KKPasscodeSettingsViewController.h"
-@interface SettingsViewController : UITableViewController
+@interface SettingsViewController : UITableViewController
@end
diff --git a/example/KKPasscodeLock/SettingsViewController.m b/example/KKPasscodeLock/SettingsViewController.m
index 36a6c86..87494eb 100755
--- a/example/KKPasscodeLock/SettingsViewController.m
+++ b/example/KKPasscodeLock/SettingsViewController.m
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,69 +22,73 @@
@implementation SettingsViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
+ return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)doneButtonPressed:(id)sender {
- [self dismissModalViewControllerAnimated:YES];
+ [self dismissModalViewControllerAnimated:YES];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
- [super viewDidLoad];
- self.navigationItem.title = @"Settings";
-
-
- UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)];
-
- self.navigationItem.rightBarButtonItem = doneButton;
- [doneButton release];
+ [super viewDidLoad];
+ self.navigationItem.title = NSLocalizedString(@"Settings", nil);
+
+
+ UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)];
+
+ self.navigationItem.rightBarButtonItem = doneButton;
}
#pragma mark - Table view data source
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
- return @"";
+ return @"";
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return 1;
+ return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return 1;
+ return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
- static NSString *CellIdentifier = @"Cell";
-
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
- }
-
- if (indexPath.section == 0) {
- cell.textLabel.text = @"Passcode Lock";
- if ([[KKPasscodeLock sharedLock] isPasscodeRequired]) {
- cell.detailTextLabel.text = @"On";
- } else {
- cell.detailTextLabel.text = @"Off";
+
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
- cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
- }
- return cell;
+
+ if (indexPath.section == 0) {
+ cell.textLabel.text = NSLocalizedString(@"Passcode Lock", nil);
+ if ([[KKPasscodeLock sharedLock] isPasscodeRequired]) {
+ cell.detailTextLabel.text = NSLocalizedString(@"On", nil);
+ } else {
+ cell.detailTextLabel.text = NSLocalizedString(@"Off", nil);
+ }
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+ }
+ return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- if (indexPath.section == 0) {
- KKPasscodeSettingsViewController *vc = [[KKPasscodeSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
- [self.navigationController pushViewController:vc animated:YES];
- [vc release];
- }
+ if (indexPath.section == 0) {
+ KKPasscodeSettingsViewController *vc = [[KKPasscodeSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ vc.delegate = self;
+ [self.navigationController pushViewController:vc animated:YES];
+ }
+}
+
+- (void)didSettingsChanged:(KKPasscodeSettingsViewController*)viewController
+{
+ [self.tableView reloadData];
}
@end
diff --git a/example/KKPasscodeLock/de.lproj/InfoPlist.strings b/example/KKPasscodeLock/de.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/example/KKPasscodeLock/de.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/example/KKPasscodeLock/de.lproj/Localizable.strings b/example/KKPasscodeLock/de.lproj/Localizable.strings
new file mode 100644
index 0000000..e1feb6e
--- /dev/null
+++ b/example/KKPasscodeLock/de.lproj/Localizable.strings
@@ -0,0 +1,11 @@
+"Passcode Lock" = "Code-Sperre";
+
+/* No comment provided by engineer. */
+"Off" = "Aus";
+
+/* No comment provided by engineer. */
+"On" = "An";
+
+/* No comment provided by engineer. */
+"Settings" = "Einstellungen";
+
diff --git a/example/KKPasscodeLock/en.lproj/Localizable.strings b/example/KKPasscodeLock/en.lproj/Localizable.strings
new file mode 100644
index 0000000..14fa401
--- /dev/null
+++ b/example/KKPasscodeLock/en.lproj/Localizable.strings
@@ -0,0 +1,11 @@
+"Passcode Lock" = "Passcode Lock";
+
+/* No comment provided by engineer. */
+"Off" = "Off";
+
+/* No comment provided by engineer. */
+"On" = "On";
+
+/* No comment provided by engineer. */
+"Settings" = "Settings";
+
diff --git a/example/KKPasscodeLock/he.lproj/InfoPlist.strings b/example/KKPasscodeLock/he.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/example/KKPasscodeLock/he.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/example/KKPasscodeLock/main.m b/example/KKPasscodeLock/main.m
index fd8f9b4..6cfc991 100644
--- a/example/KKPasscodeLock/main.m
+++ b/example/KKPasscodeLock/main.m
@@ -1,9 +1,18 @@
//
-// main.m
-// APPasscodeLock
+// Copyright 2011-2012 Kosher Penguin LLC
+// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
-// Created by Adar Porat on 1/16/12.
-// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
//
#import
diff --git a/example/KKPasscodeLock/nl.lproj/InfoPlist.strings b/example/KKPasscodeLock/nl.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/example/KKPasscodeLock/nl.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/example/KKPasscodeLock.xcodeproj/project.pbxproj b/example/KKPasscodeLockDemo.xcodeproj/project.pbxproj
similarity index 76%
rename from example/KKPasscodeLock.xcodeproj/project.pbxproj
rename to example/KKPasscodeLockDemo.xcodeproj/project.pbxproj
index e7e3005..8362a85 100644
--- a/example/KKPasscodeLock.xcodeproj/project.pbxproj
+++ b/example/KKPasscodeLockDemo.xcodeproj/project.pbxproj
@@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
+ 5303095F16611BF90004810F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5303095E16611BF90004810F /* Default-568h@2x.png */; };
+ 53DD2F8816A79FDB002582A0 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 53DD2F8616A79FDB002582A0 /* Default.png */; };
+ 53DD2F8916A79FDB002582A0 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53DD2F8716A79FDB002582A0 /* Default@2x.png */; };
6D3E345214C4F54E0003B72B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D3E345114C4F54E0003B72B /* UIKit.framework */; };
6D3E345414C4F54E0003B72B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D3E345314C4F54E0003B72B /* Foundation.framework */; };
6D3E345614C4F54E0003B72B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D3E345514C4F54E0003B72B /* CoreGraphics.framework */; };
@@ -23,21 +26,25 @@
6DF13A6A14C6870B0069BBA5 /* KKPasscodeLock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DF13A6014C6870B0069BBA5 /* KKPasscodeLock.m */; };
6DF13A6B14C6870B0069BBA5 /* KKPasscodeSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DF13A6214C6870B0069BBA5 /* KKPasscodeSettingsViewController.m */; };
6DF13A6C14C6870B0069BBA5 /* KKPasscodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DF13A6414C6870B0069BBA5 /* KKPasscodeViewController.m */; };
- 6DF13A6D14C6870B0069BBA5 /* passcode_square_empty.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DF13A6514C6870B0069BBA5 /* passcode_square_empty.png */; };
- 6DF13A6E14C6870B0069BBA5 /* passcode_square_empty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DF13A6614C6870B0069BBA5 /* passcode_square_empty@2x.png */; };
- 6DF13A6F14C6870B0069BBA5 /* passcode_square_filled.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DF13A6714C6870B0069BBA5 /* passcode_square_filled.png */; };
- 6DF13A7014C6870B0069BBA5 /* passcode_square_filled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DF13A6814C6870B0069BBA5 /* passcode_square_filled@2x.png */; };
+ 6DFE33F714CF879E00E6EEA4 /* KKPasscodeLock.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6DFE33F614CF879E00E6EEA4 /* KKPasscodeLock.bundle */; };
+ 6DFE344414CFBE8400E6EEA4 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DFE344314CFBE8400E6EEA4 /* AudioToolbox.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
- 6D3E344D14C4F54E0003B72B /* KKPasscodeLock.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KKPasscodeLock.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5303095E16611BF90004810F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
+ 5303097E16611F510004810F /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; };
+ 5303097F16611F580004810F /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; };
+ 5303098816612A310004810F /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = ""; };
+ 53DD2F8616A79FDB002582A0 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
+ 53DD2F8716A79FDB002582A0 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
+ 6D3E344D14C4F54E0003B72B /* KKPasscodeLockDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KKPasscodeLockDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
6D3E345114C4F54E0003B72B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
6D3E345314C4F54E0003B72B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
6D3E345514C4F54E0003B72B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
- 6D3E345914C4F54E0003B72B /* KKPasscodeLock-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KKPasscodeLock-Info.plist"; sourceTree = ""; };
+ 6D3E345914C4F54E0003B72B /* KKPasscodeLockDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KKPasscodeLockDemo-Info.plist"; sourceTree = ""; };
6D3E345B14C4F54E0003B72B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
6D3E345D14C4F54E0003B72B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
- 6D3E345F14C4F54E0003B72B /* KKPasscodeLock-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KKPasscodeLock-Prefix.pch"; sourceTree = ""; };
+ 6D3E345F14C4F54E0003B72B /* KKPasscodeLockDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KKPasscodeLockDemo-Prefix.pch"; sourceTree = ""; };
6D3E346014C4F54E0003B72B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
6D3E346114C4F54E0003B72B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
6D3E34BA14C4F90B0003B72B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
@@ -51,15 +58,13 @@
6DF13A5D14C6870B0069BBA5 /* KKKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKKeychain.h; path = ../../src/KKKeychain.h; sourceTree = ""; };
6DF13A5E14C6870B0069BBA5 /* KKKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKKeychain.m; path = ../../src/KKKeychain.m; sourceTree = ""; };
6DF13A5F14C6870B0069BBA5 /* KKPasscodeLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeLock.h; path = ../../src/KKPasscodeLock.h; sourceTree = ""; };
- 6DF13A6014C6870B0069BBA5 /* KKPasscodeLock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeLock.m; path = ../../src/KKPasscodeLock.m; sourceTree = ""; };
+ 6DF13A6014C6870B0069BBA5 /* KKPasscodeLock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = KKPasscodeLock.m; path = ../../src/KKPasscodeLock.m; sourceTree = ""; };
6DF13A6114C6870B0069BBA5 /* KKPasscodeSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeSettingsViewController.h; path = ../../src/KKPasscodeSettingsViewController.h; sourceTree = ""; };
- 6DF13A6214C6870B0069BBA5 /* KKPasscodeSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeSettingsViewController.m; path = ../../src/KKPasscodeSettingsViewController.m; sourceTree = ""; };
+ 6DF13A6214C6870B0069BBA5 /* KKPasscodeSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = KKPasscodeSettingsViewController.m; path = ../../src/KKPasscodeSettingsViewController.m; sourceTree = ""; };
6DF13A6314C6870B0069BBA5 /* KKPasscodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeViewController.h; path = ../../src/KKPasscodeViewController.h; sourceTree = ""; };
- 6DF13A6414C6870B0069BBA5 /* KKPasscodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeViewController.m; path = ../../src/KKPasscodeViewController.m; sourceTree = ""; };
- 6DF13A6514C6870B0069BBA5 /* passcode_square_empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = passcode_square_empty.png; path = ../../src/passcode_square_empty.png; sourceTree = ""; };
- 6DF13A6614C6870B0069BBA5 /* passcode_square_empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "passcode_square_empty@2x.png"; path = "../../src/passcode_square_empty@2x.png"; sourceTree = ""; };
- 6DF13A6714C6870B0069BBA5 /* passcode_square_filled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = passcode_square_filled.png; path = ../../src/passcode_square_filled.png; sourceTree = ""; };
- 6DF13A6814C6870B0069BBA5 /* passcode_square_filled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "passcode_square_filled@2x.png"; path = "../../src/passcode_square_filled@2x.png"; sourceTree = ""; };
+ 6DF13A6414C6870B0069BBA5 /* KKPasscodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = KKPasscodeViewController.m; path = ../../src/KKPasscodeViewController.m; sourceTree = ""; };
+ 6DFE33F614CF879E00E6EEA4 /* KKPasscodeLock.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = KKPasscodeLock.bundle; path = ../../src/KKPasscodeLock.bundle; sourceTree = ""; };
+ 6DFE344314CFBE8400E6EEA4 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -72,6 +77,7 @@
6D3E345614C4F54E0003B72B /* CoreGraphics.framework in Frameworks */,
6D3E34BC14C4F90B0003B72B /* Security.framework in Frameworks */,
6D3E34BD14C4F90B0003B72B /* QuartzCore.framework in Frameworks */,
+ 6DFE344414CFBE8400E6EEA4 /* AudioToolbox.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -93,10 +99,10 @@
6D2F0BD614C51D0300C1862D /* Supporting Files */ = {
isa = PBXGroup;
children = (
- 6D3E345914C4F54E0003B72B /* KKPasscodeLock-Info.plist */,
+ 6D3E345914C4F54E0003B72B /* KKPasscodeLockDemo-Info.plist */,
6D3E345A14C4F54E0003B72B /* InfoPlist.strings */,
6D3E345D14C4F54E0003B72B /* main.m */,
- 6D3E345F14C4F54E0003B72B /* KKPasscodeLock-Prefix.pch */,
+ 6D3E345F14C4F54E0003B72B /* KKPasscodeLockDemo-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "";
@@ -104,6 +110,9 @@
6D3E344214C4F54D0003B72B = {
isa = PBXGroup;
children = (
+ 53DD2F8616A79FDB002582A0 /* Default.png */,
+ 53DD2F8716A79FDB002582A0 /* Default@2x.png */,
+ 5303095E16611BF90004810F /* Default-568h@2x.png */,
6D3E345714C4F54E0003B72B /* KKPasscodeLock */,
6D2F0BD414C51CCA00C1862D /* Demo App */,
6D3E345014C4F54E0003B72B /* Frameworks */,
@@ -114,7 +123,7 @@
6D3E344E14C4F54E0003B72B /* Products */ = {
isa = PBXGroup;
children = (
- 6D3E344D14C4F54E0003B72B /* KKPasscodeLock.app */,
+ 6D3E344D14C4F54E0003B72B /* KKPasscodeLockDemo.app */,
);
name = Products;
sourceTree = "";
@@ -122,6 +131,7 @@
6D3E345014C4F54E0003B72B /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 6DFE344314CFBE8400E6EEA4 /* AudioToolbox.framework */,
6D3E34BA14C4F90B0003B72B /* Security.framework */,
6D3E34BB14C4F90B0003B72B /* QuartzCore.framework */,
6D3E345114C4F54E0003B72B /* UIKit.framework */,
@@ -134,6 +144,7 @@
6D3E345714C4F54E0003B72B /* KKPasscodeLock */ = {
isa = PBXGroup;
children = (
+ 6DFE33F614CF879E00E6EEA4 /* KKPasscodeLock.bundle */,
6DF13A5D14C6870B0069BBA5 /* KKKeychain.h */,
6DF13A5E14C6870B0069BBA5 /* KKKeychain.m */,
6DF13A5F14C6870B0069BBA5 /* KKPasscodeLock.h */,
@@ -142,10 +153,6 @@
6DF13A6214C6870B0069BBA5 /* KKPasscodeSettingsViewController.m */,
6DF13A6314C6870B0069BBA5 /* KKPasscodeViewController.h */,
6DF13A6414C6870B0069BBA5 /* KKPasscodeViewController.m */,
- 6DF13A6514C6870B0069BBA5 /* passcode_square_empty.png */,
- 6DF13A6614C6870B0069BBA5 /* passcode_square_empty@2x.png */,
- 6DF13A6714C6870B0069BBA5 /* passcode_square_filled.png */,
- 6DF13A6814C6870B0069BBA5 /* passcode_square_filled@2x.png */,
);
path = KKPasscodeLock;
sourceTree = "";
@@ -182,9 +189,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- 6D3E344C14C4F54D0003B72B /* KKPasscodeLock */ = {
+ 6D3E344C14C4F54D0003B72B /* KKPasscodeLockDemo */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 6D3E346514C4F54E0003B72B /* Build configuration list for PBXNativeTarget "KKPasscodeLock" */;
+ buildConfigurationList = 6D3E346514C4F54E0003B72B /* Build configuration list for PBXNativeTarget "KKPasscodeLockDemo" */;
buildPhases = (
6D3E344914C4F54D0003B72B /* Sources */,
6D3E344A14C4F54D0003B72B /* Frameworks */,
@@ -194,9 +201,9 @@
);
dependencies = (
);
- name = KKPasscodeLock;
+ name = KKPasscodeLockDemo;
productName = KKPasscodeLock;
- productReference = 6D3E344D14C4F54E0003B72B /* KKPasscodeLock.app */;
+ productReference = 6D3E344D14C4F54E0003B72B /* KKPasscodeLockDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -205,21 +212,25 @@
6D3E344414C4F54D0003B72B /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0420;
+ LastUpgradeCheck = 0430;
+ ORGANIZATIONNAME = "Kosher Penguin LLC";
};
- buildConfigurationList = 6D3E344714C4F54D0003B72B /* Build configuration list for PBXProject "KKPasscodeLock" */;
+ buildConfigurationList = 6D3E344714C4F54D0003B72B /* Build configuration list for PBXProject "KKPasscodeLockDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
+ nl,
+ de,
+ he,
);
mainGroup = 6D3E344214C4F54D0003B72B;
productRefGroup = 6D3E344E14C4F54E0003B72B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
- 6D3E344C14C4F54D0003B72B /* KKPasscodeLock */,
+ 6D3E344C14C4F54D0003B72B /* KKPasscodeLockDemo */,
);
};
/* End PBXProject section */
@@ -232,10 +243,10 @@
6D3E345C14C4F54E0003B72B /* InfoPlist.strings in Resources */,
6D3E34D014C4F9910003B72B /* RootViewController.xib in Resources */,
6DF13A5C14C686FC0069BBA5 /* SettingsViewController.xib in Resources */,
- 6DF13A6D14C6870B0069BBA5 /* passcode_square_empty.png in Resources */,
- 6DF13A6E14C6870B0069BBA5 /* passcode_square_empty@2x.png in Resources */,
- 6DF13A6F14C6870B0069BBA5 /* passcode_square_filled.png in Resources */,
- 6DF13A7014C6870B0069BBA5 /* passcode_square_filled@2x.png in Resources */,
+ 6DFE33F714CF879E00E6EEA4 /* KKPasscodeLock.bundle in Resources */,
+ 5303095F16611BF90004810F /* Default-568h@2x.png in Resources */,
+ 53DD2F8816A79FDB002582A0 /* Default.png in Resources */,
+ 53DD2F8916A79FDB002582A0 /* Default@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -264,6 +275,9 @@
isa = PBXVariantGroup;
children = (
6D3E345B14C4F54E0003B72B /* en */,
+ 5303097E16611F510004810F /* nl */,
+ 5303097F16611F580004810F /* de */,
+ 5303098816612A310004810F /* he */,
);
name = InfoPlist.strings;
sourceTree = "";
@@ -319,11 +333,12 @@
6D3E346614C4F54E0003B72B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLock-Prefix.pch";
- INFOPLIST_FILE = "KKPasscodeLock/KKPasscodeLock-Info.plist";
+ GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLockDemo-Prefix.pch";
+ INFOPLIST_FILE = "KKPasscodeLock/KKPasscodeLockDemo-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
- PRODUCT_NAME = KKPasscodeLock;
+ PRODUCT_NAME = KKPasscodeLockDemo;
WRAPPER_EXTENSION = app;
};
name = Debug;
@@ -331,11 +346,12 @@
6D3E346714C4F54E0003B72B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLock-Prefix.pch";
- INFOPLIST_FILE = "KKPasscodeLock/KKPasscodeLock-Info.plist";
+ GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLockDemo-Prefix.pch";
+ INFOPLIST_FILE = "KKPasscodeLock/KKPasscodeLockDemo-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
- PRODUCT_NAME = KKPasscodeLock;
+ PRODUCT_NAME = KKPasscodeLockDemo;
WRAPPER_EXTENSION = app;
};
name = Release;
@@ -343,7 +359,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 6D3E344714C4F54D0003B72B /* Build configuration list for PBXProject "KKPasscodeLock" */ = {
+ 6D3E344714C4F54D0003B72B /* Build configuration list for PBXProject "KKPasscodeLockDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6D3E346314C4F54E0003B72B /* Debug */,
@@ -352,7 +368,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 6D3E346514C4F54E0003B72B /* Build configuration list for PBXNativeTarget "KKPasscodeLock" */ = {
+ 6D3E346514C4F54E0003B72B /* Build configuration list for PBXNativeTarget "KKPasscodeLockDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6D3E346614C4F54E0003B72B /* Debug */,
diff --git a/src/KKKeychain.h b/src/KKKeychain.h
index a3638b1..98fbdf7 100755
--- a/src/KKKeychain.h
+++ b/src/KKKeychain.h
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,10 +17,10 @@
#import
-@interface KKKeychain : NSObject {
-}
+@interface KKKeychain : NSObject
+ (BOOL)setString:(NSString*)string forKey:(NSString*)key;
+
+ (NSString*)getStringForKey:(NSString*)key;
@end
diff --git a/src/KKKeychain.m b/src/KKKeychain.m
index 15d2011..5d54618 100755
--- a/src/KKKeychain.m
+++ b/src/KKKeychain.m
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,99 +18,86 @@
#import "KKKeychain.h"
#import
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation KKKeychain
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-+ (NSString*)appName {
++ (NSString*)appName
+{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
-
NSString *appName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
if (!appName) {
- appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
+ appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
}
- return appName;
+ return appName;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-+ (BOOL)setString:(NSString*)string forKey:(NSString*)key {
++ (BOOL)setString:(NSString*)string forKey:(NSString*)key
+{
if (string == nil || key == nil) {
return NO;
}
-
- key = [NSString stringWithFormat:@"%@ - %@", [KKKeychain appName], key];
-
- // First check if it already exists, by creating a search dictionary and requesting that
- // nothing be returned, and performing the search anyway.
+
+ key = [NSString stringWithFormat:@"%@ - %@", [KKKeychain appName], key];
+
+ // First check if it already exists, by creating a search dictionary and requesting that
+ // nothing be returned, and performing the search anyway.
NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
- [existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+ [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
// Add the keys to the search dict
- [existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
- [existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];
-
- OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, NULL);
+ [existsQueryDictionary setObject:@"service" forKey:(__bridge id)kSecAttrService];
+ [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount];
+
+ OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef) existsQueryDictionary, NULL);
+
if (res == errSecItemNotFound) {
if (string != nil) {
NSMutableDictionary *addDict = existsQueryDictionary;
- [addDict setObject:data forKey:(id)kSecValueData];
-
- res = SecItemAdd((CFDictionaryRef)addDict, NULL);
- NSAssert1(res == errSecSuccess, @"Recieved %d from SecItemAdd!", res);
+ [addDict setObject:data forKey:(__bridge id)kSecValueData];
+
+ res = SecItemAdd((__bridge CFDictionaryRef)addDict, NULL);
+ NSAssert1(res == errSecSuccess, @"Recieved %ld from SecItemAdd!", (long) res);
}
} else if (res == errSecSuccess) {
// Modify an existing one
// Actually pull it now of the keychain at this point.
- NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(id)kSecValueData];
-
- res = SecItemUpdate((CFDictionaryRef)existsQueryDictionary, (CFDictionaryRef)attributeDict);
- NSAssert1(res == errSecSuccess, @"SecItemUpdated returned %d!", res);
-
+ NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(__bridge id)kSecValueData];
+ res = SecItemUpdate((__bridge CFDictionaryRef)existsQueryDictionary, (__bridge CFDictionaryRef)attributeDict);
+ NSAssert1(res == errSecSuccess, @"SecItemUpdated returned %ld!", (long) res);
} else {
- NSAssert1(NO, @"Received %d from SecItemCopyMatching!", res);
+ NSAssert1(NO, @"Received %ld from SecItemCopyMatching!", (long) res);
}
-
return YES;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-+ (NSString*)getStringForKey:(NSString*)key {
-
- key = [NSString stringWithFormat:@"%@ - %@", [KKKeychain appName], key];
-
++ (NSString*)getStringForKey:(NSString*)key
+{
+ key = [NSString stringWithFormat:@"%@ - %@", [KKKeychain appName], key];
NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
-
- [existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+ [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
// Add the keys to the search dict
- [existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
- [existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];
+ [existsQueryDictionary setObject:@"service" forKey:(__bridge id)kSecAttrService];
+ [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount];
// We want the data back!
- NSData *data = nil;
+ CFTypeRef data = nil;
- [existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
-
- OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, (CFTypeRef *)&data);
- [data autorelease];
+ [existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
+
+ OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, &data);
+
if (res == errSecSuccess) {
- NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+ NSString *string = [[NSString alloc] initWithData:(__bridge NSData*)data encoding:NSUTF8StringEncoding];
return string;
} else {
- NSAssert1(res == errSecItemNotFound, @"SecItemCopyMatching returned %d!", res);
- }
+ NSAssert1(res == errSecItemNotFound, @"SecItemCopyMatching returned %ld!", (long) res);
+ }
return nil;
}
-
@end
diff --git a/src/KKPasscodeLock.bundle/box_empty.png b/src/KKPasscodeLock.bundle/box_empty.png
new file mode 100644
index 0000000..09744d0
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_empty.png differ
diff --git a/src/KKPasscodeLock.bundle/box_empty@2x.png b/src/KKPasscodeLock.bundle/box_empty@2x.png
new file mode 100644
index 0000000..515072e
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_empty@2x.png differ
diff --git a/src/KKPasscodeLock.bundle/box_empty_ios7.png b/src/KKPasscodeLock.bundle/box_empty_ios7.png
new file mode 100644
index 0000000..5f927ec
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_empty_ios7.png differ
diff --git a/src/KKPasscodeLock.bundle/box_empty_ios7@2x.png b/src/KKPasscodeLock.bundle/box_empty_ios7@2x.png
new file mode 100644
index 0000000..ce79453
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_empty_ios7@2x.png differ
diff --git a/src/KKPasscodeLock.bundle/box_filled.png b/src/KKPasscodeLock.bundle/box_filled.png
new file mode 100644
index 0000000..e53fba4
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_filled.png differ
diff --git a/src/KKPasscodeLock.bundle/box_filled@2x.png b/src/KKPasscodeLock.bundle/box_filled@2x.png
new file mode 100644
index 0000000..dc0b683
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_filled@2x.png differ
diff --git a/src/KKPasscodeLock.bundle/box_filled_ios7.png b/src/KKPasscodeLock.bundle/box_filled_ios7.png
new file mode 100644
index 0000000..1ec3732
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_filled_ios7.png differ
diff --git a/src/KKPasscodeLock.bundle/box_filled_ios7@2x.png b/src/KKPasscodeLock.bundle/box_filled_ios7@2x.png
new file mode 100644
index 0000000..92b0732
Binary files /dev/null and b/src/KKPasscodeLock.bundle/box_filled_ios7@2x.png differ
diff --git a/src/KKPasscodeLock.bundle/de.lproj/Localizable.strings b/src/KKPasscodeLock.bundle/de.lproj/Localizable.strings
new file mode 100644
index 0000000..c9b03b2
Binary files /dev/null and b/src/KKPasscodeLock.bundle/de.lproj/Localizable.strings differ
diff --git a/src/KKPasscodeLock.bundle/en.lproj/Localizable.strings b/src/KKPasscodeLock.bundle/en.lproj/Localizable.strings
new file mode 100644
index 0000000..6d3ee10
Binary files /dev/null and b/src/KKPasscodeLock.bundle/en.lproj/Localizable.strings differ
diff --git a/src/KKPasscodeLock.bundle/he.lproj/Localizable.strings b/src/KKPasscodeLock.bundle/he.lproj/Localizable.strings
new file mode 100644
index 0000000..362f668
Binary files /dev/null and b/src/KKPasscodeLock.bundle/he.lproj/Localizable.strings differ
diff --git a/src/KKPasscodeLock.bundle/nl.lproj/Localizable.strings b/src/KKPasscodeLock.bundle/nl.lproj/Localizable.strings
new file mode 100644
index 0000000..712cea1
Binary files /dev/null and b/src/KKPasscodeLock.bundle/nl.lproj/Localizable.strings differ
diff --git a/src/KKPasscodeLock.h b/src/KKPasscodeLock.h
index 3c4397a..a14e0b8 100644
--- a/src/KKPasscodeLock.h
+++ b/src/KKPasscodeLock.h
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,15 +15,66 @@
// limitations under the License.
//
+#define KKPasscodeLockLocalizedString(key, comment) [[KKPasscodeLock sharedLock] localizedStringForKey:(key) value:@""]
+
#import
+#import "KKPasscodeViewController.h"
+
+extern CGFloat const kPasscodeBlockDisabled;
-@interface KKPasscodeLock : NSObject
+@interface KKPasscodeLock : NSObject {
+
+ // whatever the erase option is enabled in the passcode settings
+ BOOL _eraseOption;
+
+ // how many attemepts is user is allowed to have before the screen is locked
+ NSUInteger _attemptsAllowed;
+
+ // the minimum time interval (in seconds) that has to pass before isPasscodeBlocked return FALSE again
+ NSTimeInterval _passcodeBlockInterval;
+}
+/**
+ * a shared object which can change the passcode settings and perform generic actions
+ */
+ (KKPasscodeLock*)sharedLock;
+/**
+ * checks if a passcode has to be displayed
+ */
+- (BOOL)isPasscodeRequired;
+
+/**
+ * checks if the passcode has been blocked due to too many failed attempts
+ */
+- (BOOL)isPasscodeBlocked;
+
+/**
+ * return an interval <= 0 if the passcode is not blocked or a value > 0 indicating the time remaining until the passcode can be unlocked
+ */
+- (NSTimeInterval)passcodeBlockedRemainingTime;
+
+/**
+ * returns a localized string from the framework's bundle
+ */
+- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value NS_FORMAT_ARGUMENT(1);
+/**
+ * set the initial settings of the passcode settings
+ */
- (void)setDefaultSettings;
-- (BOOL)isPasscodeRequired;
-- (void)showPasscodeController:(UINavigationController*)navController;
+
+/**
+ * reset the passcode settings
+ */
+- (void)resetSettings;
+
+@property (nonatomic,assign) BOOL eraseOption;
+
+@property (nonatomic,assign) NSUInteger attemptsAllowed;
+
+@property (nonatomic,assign) NSTimeInterval passcodeBlockInterval;
+
+@property (nonatomic, strong, readonly) NSDateFormatter *dateFormatter;
@end
diff --git a/src/KKPasscodeLock.m b/src/KKPasscodeLock.m
index 376d4ea..40e3dcc 100644
--- a/src/KKPasscodeLock.m
+++ b/src/KKPasscodeLock.m
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,122 +19,121 @@
#import "KKKeychain.h"
#import "KKPasscodeViewController.h"
+CGFloat const kPasscodeBlockDisabled = MAXFLOAT;
+
static KKPasscodeLock *sharedLock = nil;
+@interface KKPasscodeLock ()
+
+@property (nonatomic, strong, readwrite) NSDateFormatter *dateFormatter;
+
+@end
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation KKPasscodeLock
+@synthesize eraseOption = _eraseOption;
+@synthesize attemptsAllowed = _attemptsAllowed;
+@synthesize passcodeBlockInterval = _passcodeBlockInterval;
-///////////////////////////////////////////////////////////////////////////////////////////////////
+ (KKPasscodeLock*)sharedLock
{
- @synchronized(self) {
- if (sharedLock == nil) {
- sharedLock = [[self alloc] init];
- }
- }
- return sharedLock;
+ @synchronized(self) {
+ if (sharedLock == nil) {
+ sharedLock = [[self alloc] init];
+ sharedLock.eraseOption = YES;
+ sharedLock.attemptsAllowed = 5;
+ sharedLock.passcodeBlockInterval = 600.0f; // 10 minutes default, kPasscodeBlockDisabled means disabled
+ }
+ }
+ return sharedLock;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)setDefaultSettings
+- (void)setPasscodeBlockInterval:(NSTimeInterval)passcodeBlockInterval
{
- if (![KKKeychain getStringForKey:@"passcode_lock_passcode_on"]) {
- [KKKeychain setString:@"NO" forKey:@"passcode_lock_passcode_on"];
- }
-
- if (![KKKeychain getStringForKey:@"passcode_lock_simple_passcode_on"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_simple_passcode_on"];
- }
-
- if (![KKKeychain getStringForKey:@"passcode_lock_erase_data_on"]) {
- [KKKeychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
- }
+ _passcodeBlockInterval = passcodeBlockInterval;
+ if (_passcodeBlockInterval == kPasscodeBlockDisabled) {
+ [KKKeychain setString:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:0]] forKey:@"incorrect_passcode_datetime"];
+ }
}
+- (NSDateFormatter *)dateFormatter
+{
+ if (!_dateFormatter) {
+ _dateFormatter = [[NSDateFormatter alloc] init];
+ _dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'";
+ _dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
+ _dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
+ }
+ return _dateFormatter;
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)isPasscodeRequired
{
- return [[KKKeychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"];
+ return [[KKKeychain getStringForKey:@"passcode_on"] isEqualToString:@"YES"];
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)presentAndRelease:(NSTimer *)timer
+- (BOOL)isPasscodeBlocked
{
- UIViewController *vc = [timer.userInfo objectForKey:@"vc"];
- UINavigationController *navController = [timer.userInfo objectForKey:@"nav"];
-
- UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- nav.modalPresentationStyle = UIModalPresentationFormSheet;
- nav.navigationBar.barStyle = UIBarStyleBlack;
- nav.navigationBar.opaque = NO;
- } else {
- nav.navigationBar.tintColor = navController.navigationBar.tintColor;
- nav.navigationBar.translucent = navController.navigationBar.translucent;
- nav.navigationBar.opaque = navController.navigationBar.opaque;
- nav.navigationBar.barStyle = navController.navigationBar.barStyle;
- }
-
- [navController presentModalViewController:nav animated:YES];
- [nav release];
-
-
- [vc release];
+ return [self passcodeBlockedRemainingTime] > 0.0f;
}
+- (NSTimeInterval)passcodeBlockedRemainingTime
+{
+ if (self.passcodeBlockInterval == kPasscodeBlockDisabled) {
+ return 0.0f; // Disabled, we don't need to check
+ } else {
+ NSString *lastPasscodeLock = [KKKeychain getStringForKey:@"incorrect_passcode_datetime"];
+
+ NSDate *lastPasscodeLockDate = lastPasscodeLock.length ? [self.dateFormatter dateFromString:lastPasscodeLock] : nil;
+
+ if (lastPasscodeLockDate) {
+ return self.passcodeBlockInterval - [[NSDate date] timeIntervalSinceDate:lastPasscodeLockDate];
+ } else {
+ return 0.0f; // Passcode is not blocked
+ }
+ }
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)showPasscodeController:(UINavigationController*)navController
+- (void)setDefaultSettings
{
- if ([[KKPasscodeLock sharedLock] isPasscodeRequired]) {
- KKPasscodeViewController *vc = [[KKPasscodeViewController alloc] initWithNibName:nil bundle:nil];
- vc.mode = KKPasscodeModeEnter;
- //vc.rootViewController = self;
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- vc.modalPresentationStyle = UIModalPresentationFullScreen;
- }
+ if (![KKKeychain getStringForKey:@"passcode_on"]) {
+ [KKKeychain setString:@"NO" forKey:@"passcode_on"];
+ }
+
+ if (![KKKeychain getStringForKey:@"erase_data_on"]) {
+ [KKKeychain setString:@"NO" forKey:@"erase_data_on"];
+ }
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- for (UIViewController *svc in navController.viewControllers) {
- svc.view.alpha = 0.0;
- }
-
- NSDictionary* userinfo = [NSDictionary dictionaryWithObjectsAndKeys:
- @"vc", vc,
- @"nav", navController, nil];
-
- [NSTimer scheduledTimerWithTimeInterval:0.3 target:self
- selector:@selector(presentAndRelease:) userInfo:
- userinfo repeats:NO];
-
- } else {
- UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- nav.modalPresentationStyle = UIModalPresentationFormSheet;
- nav.navigationBar.barStyle = UIBarStyleBlack;
- nav.navigationBar.opaque = NO;
- } else {
- nav.navigationBar.tintColor = navController.navigationBar.tintColor;
- nav.navigationBar.translucent = navController.navigationBar.translucent;
- nav.navigationBar.opaque = navController.navigationBar.opaque;
- nav.navigationBar.barStyle = navController.navigationBar.barStyle;
- }
-
- [navController presentModalViewController:nav animated:NO];
- [nav release];
- [vc release];
+ if (![KKKeychain getStringForKey:@"failedAttemptsCount"]) {
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+ }
+
+ if (![KKKeychain getStringForKey:@"incorrect_passcode_datetime"]) {
+ [KKKeychain setString:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:0]] forKey:@"incorrect_passcode_datetime"];
+ }
+}
+
+- (void)resetSettings
+{
+ [KKKeychain setString:@"NO" forKey:@"passcode_on"];
+ [KKKeychain setString:@"NO" forKey:@"erase_data_on"];
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+ [KKKeychain setString:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:0]] forKey:@"incorrect_passcode_datetime"];
+}
+
+- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value
+{
+ static NSBundle *bundle = nil;
+ if (bundle == nil)
+ {
+ NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"KKPasscodeLock" ofType:@"bundle"];
+ bundle = [NSBundle bundleWithPath:bundlePath] ?: [NSBundle mainBundle];
}
- }
+
+ value = [bundle localizedStringForKey:key value:value table:nil];
+ return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil];
}
+
@end
diff --git a/src/KKPasscodeSettingsViewController.h b/src/KKPasscodeSettingsViewController.h
index 684760d..8677acb 100755
--- a/src/KKPasscodeSettingsViewController.h
+++ b/src/KKPasscodeSettingsViewController.h
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,14 +16,38 @@
//
#import
+#import "KKPasscodeViewController.h"
-@interface KKPasscodeSettingsViewController : UITableViewController {
- UISwitch* _simplePasscodeSwitch;
- UISwitch* _eraseDataSwitch;
-
- BOOL _passcodeLockOn;
- BOOL _simplePasscodeOn;
- BOOL _eraseDataOn;
+@class KKPasscodeSettingsViewController;
+
+@protocol KKPasscodeSettingsViewControllerDelegate
+
+@optional
+
+/**
+ * called when the passcode settings (either turned on/off) is changed
+ */
+- (void)didSettingsChanged:(KKPasscodeSettingsViewController*)viewController;
+
+@end
+
+@interface KKPasscodeSettingsViewController : UITableViewController {
+
+ // delegate which notified then the passcode is turned on/off
+ id __unsafe_unretained _delegate;
+
+ // the erase content switch.
+ UISwitch* _eraseDataSwitch;
+
+ // whatever the passcode lock is turned on or off
+ BOOL _passcodeLockOn;
+
+ // whatever the erase data option is turned on or off
+ BOOL _eraseDataOn;
}
+@property (nonatomic) Class passcodeViewControllerClass;
+
+@property (nonatomic, unsafe_unretained) id delegate;
+@property (nonatomic, unsafe_unretained) id passcodeViewControllerDelegate;
@end
diff --git a/src/KKPasscodeSettingsViewController.m b/src/KKPasscodeSettingsViewController.m
index c7a7912..9eb6fa1 100755
--- a/src/KKPasscodeSettingsViewController.m
+++ b/src/KKPasscodeSettingsViewController.m
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,287 +18,359 @@
#import "KKPasscodeSettingsViewController.h"
#import "KKKeychain.h"
#import "KKPasscodeViewController.h"
-#import "SettingsViewController.h"
+#import "KKPasscodeLock.h"
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation KKPasscodeSettingsViewController
+@synthesize delegate = _delegate;
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark UIViewController
+#pragma mark Properties
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)viewDidLoad
+- (void)setPasscodeViewControllerClass:(Class)passcodeViewControllerClass
{
- [super viewDidLoad];
- self.navigationItem.title = @"Passcode Lock";
-
- _simplePasscodeSwitch = [[UISwitch alloc] init];
- [_simplePasscodeSwitch addTarget:self action:@selector(simplePasscodeSwitchChanged:) forControlEvents:UIControlEventValueChanged];
-
- _eraseDataSwitch = [[UISwitch alloc] init];
- [_eraseDataSwitch addTarget:self action:@selector(eraseDataSwitchChanged:) forControlEvents:UIControlEventValueChanged];
+ if ([passcodeViewControllerClass isSubclassOfClass:[KKPasscodeViewController class]]) {
+ _passcodeViewControllerClass = passcodeViewControllerClass;
+ }
}
+#pragma mark -
+#pragma mark Initialization
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)viewWillAppear:(BOOL)animated
+- (id)init
{
- [super viewWillAppear:animated];
- _passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"];
- _simplePasscodeOn = [[KKKeychain getStringForKey:@"passcode_lock_simple_passcode_on"] isEqualToString:@"YES"];
- _eraseDataOn = [[KKKeychain getStringForKey:@"passcode_lock_erase_data_on"] isEqualToString:@"YES"];
- _simplePasscodeSwitch.on = _simplePasscodeOn;
- _eraseDataSwitch.on = _eraseDataOn;
+ if (self = [super init]) {
+ self.passcodeViewControllerClass = [KKPasscodeViewController class];
+ }
+ return self;
}
+- (id)initWithStyle:(UITableViewStyle)style
+{
+ if (self = [super initWithStyle:style]) {
+ self.passcodeViewControllerClass = [KKPasscodeViewController class];
+ }
+ return self;
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
+ if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
+ self.passcodeViewControllerClass = [KKPasscodeViewController class];
+ }
+ return self;
}
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ if (self = [super initWithCoder:aDecoder]) {
+ self.passcodeViewControllerClass = [KKPasscodeViewController class];
+ }
+ return self;
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark UISwitch
+#pragma mark UIViewController methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)simplePasscodeSwitchChanged:(id)sender
+- (void)viewDidLoad
{
- _simplePasscodeOn = _simplePasscodeSwitch.on;
- if (_simplePasscodeOn) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_simple_passcode_on"];
- } else {
- [KKKeychain setString:@"NO" forKey:@"passcode_lock_simple_passcode_on"];
- }
+ [super viewDidLoad];
+ self.navigationItem.title = KKPasscodeLockLocalizedString(@"Passcode Lock", @"");
+
+ _eraseDataSwitch = [[UISwitch alloc] init];
+ [_eraseDataSwitch addTarget:self action:@selector(eraseDataSwitchChanged:) forControlEvents:UIControlEventValueChanged];
}
+- (void)viewDidUnload
+{
+ _eraseDataSwitch = nil;
+
+ [super viewDidUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ _passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_on"] isEqualToString:@"YES"];
+ _eraseDataOn = [[KKKeychain getStringForKey:@"erase_data_on"] isEqualToString:@"YES"];
+ _eraseDataSwitch.on = _eraseDataOn;
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+{
+ return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark UIActionSheetDelegate
+#pragma mark UIActionSheetDelegate methods
+- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if (buttonIndex == 0) {
+ [self enableEraseDataHandler];
+ } else {
+ [self disableEraseDataHandler];
+ }
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+- (void)eraseDataSwitchChanged:(id)sender
{
- if (buttonIndex == 0) {
- _eraseDataOn = YES;
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_erase_data_on"];
- } else {
- _eraseDataOn = NO;
- [KKKeychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
- }
- [_eraseDataSwitch setOn:_eraseDataOn animated:YES];
+ if (_eraseDataSwitch.on) {
+ NSString* title = [NSString stringWithFormat:KKPasscodeLockLocalizedString(@"All data in this app will be erased after %d failed passcode attempts.", @""), [[KKPasscodeLock sharedLock] attemptsAllowed]];
+
+ if ((floor(NSFoundationVersionNumber) <= 1047.25)) {
+ UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:KKPasscodeLockLocalizedString(@"Cancel", @"") destructiveButtonTitle:KKPasscodeLockLocalizedString(@"Enable", @"") otherButtonTitles:nil];
+ [sheet showInView:self.view];
+ } else {
+
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
+ message:nil
+ preferredStyle:UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet];
+
+ [alertController addAction:[UIAlertAction actionWithTitle:KKPasscodeLockLocalizedString(@"Enable", @"") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
+ [self enableEraseDataHandler];
+ }]];
+
+ [alertController addAction:[UIAlertAction actionWithTitle:KKPasscodeLockLocalizedString(@"Cancel", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
+ [self disableEraseDataHandler];
+ }]];
+
+ [self presentViewController:alertController animated:YES completion:nil];
+ }
+
+ } else {
+ _eraseDataOn = NO;
+ [KKKeychain setString:@"NO" forKey:@"erase_data_on"];
+ }
}
+- (void)enableEraseDataHandler
+{
+ _eraseDataOn = YES;
+ [KKKeychain setString:@"YES" forKey:@"erase_data_on"];
+ [_eraseDataSwitch setOn:_eraseDataOn animated:YES];
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)eraseDataSwitchChanged:(id)sender {
- if (_eraseDataSwitch.on) {
- UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"All data in this app will be erased after 10 failed passcode attempts." delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Enable" otherButtonTitles:nil];
- [sheet showInView:self.view];
- [sheet release];
- } else {
+- (void)disableEraseDataHandler
+{
_eraseDataOn = NO;
- [KKKeychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
- }
+ [KKKeychain setString:@"NO" forKey:@"erase_data_on"];
+ [_eraseDataSwitch setOn:_eraseDataOn animated:YES];
}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark Table view data source
-
+#pragma mark UITableViewDataSource methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
- return 4;
+ if ([[KKPasscodeLock sharedLock] eraseOption]) {
+ return 2;
+ }
+
+ return 1;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
- return 1;
+ if (section==0) {
+ return 2;
+ }
+
+ return 1;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
- if (section == 2) {
- return @"A simple passcode is a 4 digit number.";
- } else if (section == 3) {
- return @"Erase all data in this app after 10 failed passcode attempts.";
- } else {
- return @"";
- }
+ if (section == 1) {
+ return [NSString stringWithFormat:KKPasscodeLockLocalizedString(@"Erase all content in the app after %d failed passcode attempts.", @""), [[KKPasscodeLock sharedLock] attemptsAllowed]];;
+ } else {
+ return @"";
+ }
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (UITableViewCell *)tableView:(UITableView *)tableView
- cellForRowAtIndexPath:(NSIndexPath *)indexPath
+- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
-
- static NSString *CellIdentifier = @"Cell";
-
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
- }
-
- if (indexPath.section == 0) {
- if (_passcodeLockOn) {
- cell.textLabel.text = @"Turn Passcode Off";
- } else {
- cell.textLabel.text = @"Turn Passcode On";
- }
- cell.textLabel.textColor = [UIColor blackColor];
- cell.textLabel.textAlignment = UITextAlignmentCenter;
+ static NSString *CellIdentifier = @"KKPasscodeSettingsCell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
+ }
+
cell.accessoryView = nil;
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
- } else if (indexPath.section == 1) {
- cell.textLabel.text = @"Change Passcode";
- if (_passcodeLockOn) {
- cell.textLabel.textColor = [UIColor blackColor];
- cell.selectionStyle = UITableViewCellSelectionStyleBlue;
- } else {
- cell.textLabel.textColor = [UIColor grayColor];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- }
- cell.textLabel.textAlignment = UITextAlignmentCenter;
- cell.accessoryView = nil;
- } else if (indexPath.section == 2) {
- cell.textLabel.text = @"Simple Passcode";
- cell.textLabel.textColor = [UIColor blackColor];
- cell.textLabel.textAlignment = UITextAlignmentLeft;
- cell.accessoryView = _simplePasscodeSwitch;
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- if (_passcodeLockOn) {
- cell.textLabel.textColor = [UIColor grayColor];
- _simplePasscodeSwitch.enabled = NO;
- } else {
- cell.textLabel.textColor = [UIColor blackColor];
- _simplePasscodeSwitch.enabled = YES;
- }
- } else if (indexPath.section == 3) {
- cell.textLabel.text = @"Erase Data";
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
cell.textLabel.textAlignment = UITextAlignmentLeft;
- cell.accessoryView = _eraseDataSwitch;
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- if (_passcodeLockOn) {
- cell.textLabel.textColor = [UIColor blackColor];
- _eraseDataSwitch.enabled = YES;
- } else {
- cell.textLabel.textColor = [UIColor grayColor];
- _eraseDataSwitch.enabled = NO;
- }
- }
-
- return cell;
+#else
+ cell.textLabel.textAlignment = NSTextAlignmentLeft;
+#endif
+
+ cell.textLabel.textColor = [UIColor blackColor];
+
+
+ if (indexPath.section == 0) {
+
+ if (indexPath.row == 0) {
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ cell.textLabel.textAlignment = UITextAlignmentCenter;
+#else
+ cell.textLabel.textAlignment = NSTextAlignmentCenter;
+#endif
+
+ if (_passcodeLockOn) {
+ cell.textLabel.text = KKPasscodeLockLocalizedString(@"Turn Passcode Off", @"");
+ } else {
+ cell.textLabel.text = KKPasscodeLockLocalizedString(@"Turn Passcode On", @"");
+ }
+ } else {
+ cell.textLabel.text = KKPasscodeLockLocalizedString(@"Change Passcode", @"");
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ cell.textLabel.textAlignment = UITextAlignmentCenter;
+#else
+ cell.textLabel.textAlignment = NSTextAlignmentCenter;
+#endif
+
+ if (!_passcodeLockOn) {
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ cell.textLabel.textColor = [UIColor grayColor];
+ }
+
+ }
+ } else if (indexPath.section == 1) {
+ cell.textLabel.text = KKPasscodeLockLocalizedString(@"Erase Data", @"");
+ cell.accessoryView = _eraseDataSwitch;
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ if (_passcodeLockOn) {
+ cell.textLabel.textColor = [UIColor blackColor];
+ _eraseDataSwitch.enabled = YES;
+ } else {
+ cell.textLabel.textColor = [UIColor grayColor];
+ _eraseDataSwitch.enabled = NO;
+ }
+ }
+
+ return cell;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark Table view delegate
-
+#pragma mark UITableViewDelegate methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
- if (indexPath.section == 0) {
- KKPasscodeViewController *vc = [[KKPasscodeViewController alloc] initWithNibName:nil
- bundle:nil];
- if (_passcodeLockOn) {
- vc.mode = KKPasscodeModeDisabled;
- } else {
- vc.mode = KKPasscodeModeSet;
- }
- vc.passcodeLockViewController = self;
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- vc.modalPresentationStyle = UIModalPresentationFormSheet;
- }
-
- UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
-
+ if (indexPath.section == 0 && indexPath.row == 0) {
+ KKPasscodeViewController* vc = [[self.passcodeViewControllerClass alloc] initWithNibName:nil
+ bundle:nil];
+ vc.delegate = self;
+
+ if (_passcodeLockOn) {
+ vc.mode = KKPasscodeModeDisabled;
+ } else {
+ vc.mode = KKPasscodeModeSet;
+ }
+
+ UINavigationController *nav = [[UINavigationController alloc]
+ initWithNavigationBarClass:[self.navigationController.navigationBar class]
+ toolbarClass:[self.navigationController.toolbar class]];
+ nav.viewControllers = @[vc];
+
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ nav.modalPresentationStyle = UIModalPresentationFormSheet;
+ nav.navigationBar.barStyle = UIBarStyleBlack;
+ nav.navigationBar.opaque = NO;
+ } else {
+ nav.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
+ nav.navigationBar.translucent = self.navigationController.navigationBar.translucent;
+ nav.navigationBar.opaque = self.navigationController.navigationBar.opaque;
+ nav.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self.navigationController presentModalViewController:nav animated:YES];
+#else
+ [self.navigationController presentViewController:nav animated:YES completion:nil];
+#endif
+
+ } else if (indexPath.section == 0 && indexPath.row == 1 && _passcodeLockOn) {
+ KKPasscodeViewController *vc = [[self.passcodeViewControllerClass alloc] initWithNibName:nil bundle:nil];
+ vc.delegate = self;
+
+ vc.mode = KKPasscodeModeChange;
+
+ UINavigationController *nav = [[UINavigationController alloc]
+ initWithNavigationBarClass:[self.navigationController.navigationBar class]
+ toolbarClass:[self.navigationController.toolbar class]];
+ nav.viewControllers = @[vc];
+
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ nav.modalPresentationStyle = UIModalPresentationFormSheet;
+ nav.navigationBar.barStyle = UIBarStyleBlack;
+ nav.navigationBar.opaque = NO;
+ } else {
+ nav.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
+ nav.navigationBar.translucent = self.navigationController.navigationBar.translucent;
+ nav.navigationBar.opaque = self.navigationController.navigationBar.opaque;
+ nav.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self.navigationController presentModalViewController:nav animated:YES];
+#else
+ [self.navigationController presentViewController:nav animated:YES completion:nil];
+#endif
+ }
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- nav.modalPresentationStyle = UIModalPresentationFormSheet;
- nav.navigationBar.barStyle = UIBarStyleBlack;
- nav.navigationBar.opaque = NO;
- } else {
- nav.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
- nav.navigationBar.translucent = self.navigationController.navigationBar.translucent;
- nav.navigationBar.opaque = self.navigationController.navigationBar.opaque;
- nav.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
- }
-
- [self.navigationController presentModalViewController:nav animated:YES];
- [nav release];
-
-
- [vc release];
- } else if (indexPath.section == 1 && _passcodeLockOn) {
- KKPasscodeViewController *vc = [[KKPasscodeViewController alloc] initWithNibName:@"KKPasscodeViewController" bundle:nil];
- vc.mode = KKPasscodeModeChange;
- vc.passcodeLockViewController = self;
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- vc.modalPresentationStyle = UIModalPresentationFormSheet;
- }
-
- UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
-
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- nav.modalPresentationStyle = UIModalPresentationFormSheet;
- nav.navigationBar.barStyle = UIBarStyleBlack;
- nav.navigationBar.opaque = NO;
- } else {
- nav.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
- nav.navigationBar.translucent = self.navigationController.navigationBar.translucent;
- nav.navigationBar.opaque = self.navigationController.navigationBar.opaque;
- nav.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
- }
-
- [self.navigationController presentModalViewController:nav animated:YES];
- [nav release];
-
- [vc release];
- }
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
+- (void)didPasscodeEnteredCorrectly:(KKPasscodeViewController*)viewController
+{
+ if ([_passcodeViewControllerDelegate respondsToSelector:@selector(didPasscodeEnteredCorrectly:)]) {
+ [_passcodeViewControllerDelegate performSelector:@selector(didPasscodeEnteredCorrectly:) withObject:viewController];
+ }
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-#pragma mark Memory management
+- (void)didPasscodeEnteredIncorrectly:(KKPasscodeViewController*)viewController
+{
+ if ([_passcodeViewControllerDelegate respondsToSelector:@selector(didPasscodeEnteredIncorrectly:)]) {
+ [_passcodeViewControllerDelegate performSelector:@selector(didPasscodeEnteredIncorrectly:) withObject:viewController];
+ }
+}
+- (void)shouldLockApplication:(KKPasscodeViewController*)viewController
+{
+ if ([_passcodeViewControllerDelegate respondsToSelector:@selector(shouldLockApplication:)]) {
+ [_passcodeViewControllerDelegate performSelector:@selector(shouldLockApplication:) withObject:viewController];
+ }
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)dealloc
+- (void)shouldEraseApplicationData:(KKPasscodeViewController*)viewController
{
- [_simplePasscodeSwitch release];
- [_eraseDataSwitch release];
+ if ([_passcodeViewControllerDelegate respondsToSelector:@selector(shouldEraseApplicationData:)]) {
+ [_passcodeViewControllerDelegate performSelector:@selector(shouldEraseApplicationData:) withObject:viewController];
+ }
+}
- [super dealloc];
+- (void)didSettingsChanged:(KKPasscodeViewController*)viewController
+{
+ _passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_on"] isEqualToString:@"YES"];
+ _eraseDataOn = [[KKKeychain getStringForKey:@"erase_data_on"] isEqualToString:@"YES"];
+ _eraseDataSwitch.on = _eraseDataOn;
+
+ [self.tableView reloadData];
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+ if ([_passcodeViewControllerDelegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_passcodeViewControllerDelegate performSelector:@selector(didSettingsChanged:) withObject:viewController];
+ }
}
diff --git a/src/KKPasscodeViewController.h b/src/KKPasscodeViewController.h
index 3788bb9..1c36f97 100755
--- a/src/KKPasscodeViewController.h
+++ b/src/KKPasscodeViewController.h
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,60 +18,101 @@
#import
+#define kPasscodeBoxesCount 4
+
+#define kPasscodeBoxWidth 61.0
+#define kPasscodeBoxHeight 53.0
+
+
+// The mode which controls the passcode view behavior
enum {
- KKPasscodeModeEnter = 0,
- KKPasscodeModeSet = 1,
- KKPasscodeModeDisabled = 2,
- KKPasscodeModeChange = 3
+ /**
+ * Displays the passcode enter view, which the user has to enter the correct passcode
+ */
+ KKPasscodeModeEnter = 0,
+
+ /**
+ * Creates a new passcode. This allows the user to enter a new passcode then
+ * imediately verify it.
+ */
+ KKPasscodeModeSet = 1,
+
+ /**
+ * Disables an existing passcode. This allows the user to disable the passcode lock by
+ * entering the passcode
+ */
+ KKPasscodeModeDisabled = 2,
+
+ /**
+ * Changes an existing passcode. This allows the user to change the passcode by
+ * entering the existing passcode, followed by a new passcode
+ */
+ KKPasscodeModeChange = 3
};
typedef NSUInteger KKPasscodeMode;
-@class KKPasscodeSettingsViewController;
-
-@interface KKPasscodeViewController : UIViewController {
-
- KKPasscodeSettingsViewController* _passcodeLockViewController;
-
- UILabel* _passcodeConfirmationWarningLabel;
- UIView* _failedAttemptsView;
- UILabel* _failedAttemptsLabel;
- NSInteger _failedAttemptsCount;
-
- NSUInteger _tableIndex;
- NSMutableArray* _tableViews;
- NSMutableArray* _textFields;
- NSMutableArray* _squares;
-
- UITableView* _enterPasscodeTableView;
- UITextField* _enterPasscodeTextField;
- NSArray* _enterPasscodeSquareImageViews;
-
- UITableView* _setPasscodeTableView;
- UITextField* _setPasscodeTextField;
- NSArray* _setPasscodeSquareImageViews;
-
- UITableView* _confirmPasscodeTableView;
- UITextField* _confirmPasscodeTextField;
- NSArray* _confirmPasscodeSquareImageViews;
-
- KKPasscodeMode _mode;
-
- BOOL _simplePasscodeOn;
- BOOL _passcodeLockOn;
- BOOL _eraseData;
-
- CGFloat _viewWidth;
-}
+@class KKPasscodeViewController;
-@property (nonatomic, assign) KKPasscodeMode mode;
-@property (nonatomic, retain) KKPasscodeSettingsViewController* passcodeLockViewController;
+@protocol KKPasscodeViewControllerDelegate
+@optional
+- (void)didPasscodeEnteredCorrectly:(KKPasscodeViewController*)viewController;
+- (void)didPasscodeEnteredIncorrectly:(KKPasscodeViewController*)viewController;
+- (void)shouldLockApplication:(KKPasscodeViewController*)viewController;
+- (void)shouldEraseApplicationData:(KKPasscodeViewController*)viewController;
+- (void)didSettingsChanged:(KKPasscodeViewController*)viewController;
@end
+@interface KKPasscodeViewController : UIViewController {
+
+ // delegate which called when major events happens
+ id __unsafe_unretained _delegate;
+
+ UILabel* _passcodeConfirmationWarningLabel;
+ UIView* _failedAttemptsView;
+ UILabel* _failedAttemptsLabel;
+
+ // the current panel that being displayed
+ NSUInteger _currentPanel;
+
+ // used to transition between table views
+ NSMutableArray* _tableViews;
+
+ // array of passcode entry text fields
+ NSMutableArray* _textFields;
+
+ NSMutableArray* _boxes;
+
+ UITableView* _enterPasscodeTableView;
+ UITextField* _enterPasscodeTextField;
+
+ UITableView* _setPasscodeTableView;
+ UITextField* _setPasscodeTextField;
+
+ UITableView* _confirmPasscodeTableView;
+ UITextField* _confirmPasscodeTextField;
+
+ // readwrite override for passlock mode
+ KKPasscodeMode _mode;
+
+ // whatever the passcode lock is turned on or off
+ BOOL _passcodeLockOn;
+
+ // whatever the erase data option is turned on or off
+ BOOL _eraseData;
+
+ // Used to make sure we do not release the keyboard when on iPad
+ BOOL _shouldReleaseFirstResponser;
+
+}
+
+@property (nonatomic, unsafe_unretained) id delegate;
+@property (nonatomic, assign) KKPasscodeMode mode;
+
+
+@end
diff --git a/src/KKPasscodeViewController.m b/src/KKPasscodeViewController.m
index 781969b..c92ad68 100755
--- a/src/KKPasscodeViewController.m
+++ b/src/KKPasscodeViewController.m
@@ -1,12 +1,12 @@
//
-// Copyright 2011-2012 Kosher Penguin LLC
+// Copyright 2011-2012 Kosher Penguin LLC
// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,811 +18,834 @@
#import "KKPasscodeViewController.h"
#import "KKKeychain.h"
#import "KKPasscodeSettingsViewController.h"
+#import "KKPasscodeLock.h"
+
#import
+#import
+
+@interface KKPasscodeViewController ()
+
+@property(nonatomic,assign) BOOL isSmallLandscape;
+@property(nonatomic,strong) UIView *dimView;
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-@interface KKPasscodeViewController(Private)
+@end
+
+@interface KKPasscodeViewController (Private)
-- (UITextField*)allocAndInitPasscodeTextField;
-- (NSArray*)squares;
-- (UIView*)passwordHeaderViewForTextField:(UITextField*)textField;
-- (void)addNextButton;
-- (void)addDoneButton;
+- (UITextField*)passcodeTextField;
+- (NSArray*)boxes;
+- (UIView*)headerViewForTextField:(UITextField*)textField;
- (void)moveToNextTableView;
- (void)moveToPreviousTableView;
+- (void)incrementFailedAttemptsLabel;
@end
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation KKPasscodeViewController
-@synthesize mode, passcodeLockViewController;
-
+@synthesize delegate = _delegate;
+@synthesize mode = _mode;
+@synthesize isSmallLandscape;
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark UIViewController
+- (id)init
+{
+ if (self = [super init]) {
+ self.modalPresentationStyle = UIModalPresentationFormSheet;
+ }
+ return self;
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
- if (self == [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
- _enterPasscodeTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
- _enterPasscodeTableView.delegate = self;
- _enterPasscodeTableView.dataSource = self;
- _enterPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
- _enterPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
- [self.view addSubview:_enterPasscodeTableView];
-
- _setPasscodeTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
- _setPasscodeTableView.delegate = self;
- _setPasscodeTableView.dataSource = self;
- _setPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
- _setPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
- [self.view addSubview:_setPasscodeTableView];
-
- _confirmPasscodeTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
- _confirmPasscodeTableView.delegate = self;
- _confirmPasscodeTableView.dataSource = self;
- _confirmPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
- _confirmPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
- [self.view addSubview:_confirmPasscodeTableView];
- }
-
- return self;
+ if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
+ self.modalPresentationStyle = UIModalPresentationFormSheet;
+ }
+ return self;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+- (id)initWithCoder:(NSCoder *)aDecoder
{
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
+ if (self = [super initWithCoder:aDecoder]) {
+ self.modalPresentationStyle = UIModalPresentationFormSheet;
+ }
+ return self;
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)viewDidLoad
+- (void)loadView
{
- [super viewDidLoad];
-
- _simplePasscodeOn = [[KKKeychain getStringForKey:@"passcode_lock_simple_passcode_on"] isEqualToString:@"YES"];
- _passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"];
- _eraseData = [[KKKeychain getStringForKey:@"passcode_lock_erase_data_on"] isEqualToString:@"YES"];
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- _viewWidth = 540.0f;
- } else {
- _viewWidth = 320.0f;
- }
+ [super loadView];
+
+ self.view.backgroundColor = [UIColor whiteColor];
+
+ CGRect tableViewFrame = self.view.bounds;
+ if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad && [[UIScreen mainScreen] bounds].size.height > 480) {
+ // is running on device with 4" screen so add background tableView
+ UITableView *backgroundTableView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped];
+ [self.view addSubview:backgroundTableView];
+
+ //and move other tableViews down so boxes are vertically centered
+ tableViewFrame.origin.y += 44.0;
+ }
+
+ _enterPasscodeTableView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped];
+ _enterPasscodeTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ _enterPasscodeTableView.delegate = self;
+ _enterPasscodeTableView.dataSource = self;
+ _enterPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ _enterPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
+ [self.view addSubview:_enterPasscodeTableView];
+
+ _setPasscodeTableView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped];
+ _setPasscodeTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ _setPasscodeTableView.delegate = self;
+ _setPasscodeTableView.dataSource = self;
+ _setPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ _setPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
+ [self.view addSubview:_setPasscodeTableView];
+
+ _confirmPasscodeTableView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped];
+ _confirmPasscodeTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ _confirmPasscodeTableView.delegate = self;
+ _confirmPasscodeTableView.dataSource = self;
+ _confirmPasscodeTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ _confirmPasscodeTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
+ [self.view addSubview:_confirmPasscodeTableView];
+
+ _shouldReleaseFirstResponser = NO;
+
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
-
- _enterPasscodeTextField = [self allocAndInitPasscodeTextField];
- _setPasscodeTextField = [self allocAndInitPasscodeTextField];
- _confirmPasscodeTextField = [self allocAndInitPasscodeTextField];
-
- _tableViews = [[NSMutableArray alloc] init];
- _textFields = [[NSMutableArray alloc] init];
- _squares = [[NSMutableArray alloc] init];
-
- if (mode == KKPasscodeModeSet || mode == KKPasscodeModeChange) {
- if (_passcodeLockOn) {
- _enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:_enterPasscodeTextField];
- [_tableViews addObject:_enterPasscodeTableView];
- [_textFields addObject:_enterPasscodeTextField];
- if (_simplePasscodeOn) {
- [_squares addObject:[self squares]];
- for (int i = 0; i < [[_squares lastObject] count]; i++) {
- [_enterPasscodeTableView.tableHeaderView addSubview:[[_squares lastObject] objectAtIndex:i]];
- }
- }
- }
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
- _setPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:_setPasscodeTextField];
- [_tableViews addObject:_setPasscodeTableView];
- [_textFields addObject:_setPasscodeTextField];
- if (_simplePasscodeOn) {
- [_squares addObject:[self squares]];
- for (int i = 0; i < [[_squares lastObject] count]; i++) {
- [_setPasscodeTableView.tableHeaderView addSubview:[[_squares lastObject] objectAtIndex:i]];
- }
- }
- _confirmPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:_confirmPasscodeTextField];
- [_tableViews addObject:_confirmPasscodeTableView];
- [_textFields addObject:_confirmPasscodeTextField];
- if (_simplePasscodeOn) {
- [_squares addObject:[self squares]];
- for (int i = 0; i < [[_squares lastObject] count]; i++) {
- [_confirmPasscodeTableView.tableHeaderView addSubview:[[_squares lastObject] objectAtIndex:i]];
- }
- }
- } else {
- _enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:_enterPasscodeTextField];
- [_tableViews addObject:_enterPasscodeTableView];
- [_textFields addObject:_enterPasscodeTextField];
- if (_simplePasscodeOn) {
- [_squares addObject:[self squares]];
- for (int i = 0; i < [[_squares lastObject] count]; i++) {
- [_enterPasscodeTableView.tableHeaderView addSubview:[[_squares lastObject] objectAtIndex:i]];
- }
- }
- }
-
- [self.view addSubview:[_tableViews objectAtIndex:0]];
-
- // shift any extra table views away
- for (int i = 1; i < [_tableViews count]; i++) {
- UITableView *tableView = [_tableViews objectAtIndex:i];
- tableView.frame = CGRectMake(tableView.frame.origin.x + _viewWidth, tableView.frame.origin.y, tableView.frame.size.width, tableView.frame.size.height);
- [self.view addSubview:tableView];
- }
-
- if (_tableIndex == [_tableViews count] - 1) {
- [self addDoneButton];
- } else {
- [self addNextButton];
- }
-
- [[_textFields objectAtIndex:0] becomeFirstResponder];
- [[_tableViews objectAtIndex:0] reloadData];
- [[_textFields objectAtIndex:[_tableViews count] - 1] setReturnKeyType:UIReturnKeyDone];
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- if ([_tableViews count] > 1) {
- [self moveToNextTableView];
- [self moveToPreviousTableView];
+ _passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_on"] isEqualToString:@"YES"];
+ _eraseData = [[KKPasscodeLock sharedLock] eraseOption] && [[KKKeychain getStringForKey:@"erase_data_on"] isEqualToString:@"YES"];
+
+ _enterPasscodeTextField = [[UITextField alloc] init];
+ _enterPasscodeTextField.delegate = self;
+ _enterPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
+ _enterPasscodeTextField.hidden = YES;
+
+ _setPasscodeTextField = [[UITextField alloc] init];
+ _setPasscodeTextField.delegate = self;
+ _setPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
+ _setPasscodeTextField.hidden = YES;
+
+ _confirmPasscodeTextField = [[UITextField alloc] init];
+ _confirmPasscodeTextField.delegate = self;
+ _confirmPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
+ _confirmPasscodeTextField.hidden = YES;
+
+ _tableViews = [[NSMutableArray alloc] init];
+ _textFields = [[NSMutableArray alloc] init];
+ _boxes = [[NSMutableArray alloc] init];
+
+ // Need to make sure everything is visible in landscape mode on small devices.
+ self.isSmallLandscape = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && UIInterfaceOrientationIsLandscape(self.interfaceOrientation));
+
+ if (_mode == KKPasscodeModeSet) {
+ self.navigationItem.title = KKPasscodeLockLocalizedString(@"Set Passcode", @"");
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(cancelButtonPressed:)];
+ } else if (_mode == KKPasscodeModeChange) {
+ self.navigationItem.title = KKPasscodeLockLocalizedString(@"Change Passcode", @"");
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(cancelButtonPressed:)];
+
+ } else if (_mode == KKPasscodeModeDisabled) {
+ self.navigationItem.title = KKPasscodeLockLocalizedString(@"Turn off Passcode", @"");
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(cancelButtonPressed:)];
+
} else {
- UITableView *tv = [_tableViews objectAtIndex:0];
- tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, 768.0, 960.0);
+ self.navigationItem.title = KKPasscodeLockLocalizedString(@"Enter Passcode", @"");
}
- }
+
+ CGFloat totalBoxesWidth = (71.0 * kPasscodeBoxesCount) - 10.0;
+
+ if (_mode == KKPasscodeModeSet || _mode == KKPasscodeModeChange) {
+ if (_passcodeLockOn) {
+ _enterPasscodeTableView.tableHeaderView = [self headerViewForTextField:_enterPasscodeTextField];
+ [_tableViews addObject:_enterPasscodeTableView];
+ [_textFields addObject:_enterPasscodeTextField];
+ [_boxes addObject:[self boxes]];
+ UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - totalBoxesWidth) * 0.5, 0, totalBoxesWidth, kPasscodeBoxHeight)];
+ boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ for (int i = 0; i < [[_boxes lastObject] count]; i++) {
+ [boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
+ }
+ [_enterPasscodeTableView.tableHeaderView addSubview:boxesView];
+ }
+
+ _setPasscodeTableView.tableHeaderView = [self headerViewForTextField:_setPasscodeTextField];
+
+ [_tableViews addObject:_setPasscodeTableView];
+ [_textFields addObject:_setPasscodeTextField];
+ [_boxes addObject:[self boxes]];
+ UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - totalBoxesWidth) * 0.5, 0, totalBoxesWidth, kPasscodeBoxHeight)];
+ boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ for (int i = 0; i < [[_boxes lastObject] count]; i++) {
+ [boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
+ }
+ [_setPasscodeTableView.tableHeaderView addSubview:boxesView];
+
+ _confirmPasscodeTableView.tableHeaderView = [self headerViewForTextField:_confirmPasscodeTextField];
+ [_tableViews addObject:_confirmPasscodeTableView];
+ [_textFields addObject:_confirmPasscodeTextField];
+ [_boxes addObject:[self boxes]];
+ UIView *boxesConfirmView = [[UIView alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - totalBoxesWidth) * 0.5, 0, totalBoxesWidth, kPasscodeBoxHeight)];
+ boxesConfirmView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ for (int i = 0; i < [[_boxes lastObject] count]; i++) {
+ [boxesConfirmView addSubview:[[_boxes lastObject] objectAtIndex:i]];
+ }
+ [_confirmPasscodeTableView.tableHeaderView addSubview:boxesConfirmView];
+ } else {
+ _enterPasscodeTableView.tableHeaderView = [self headerViewForTextField:_enterPasscodeTextField];
+ [_tableViews addObject:_enterPasscodeTableView];
+ [_textFields addObject:_enterPasscodeTextField];
+ [_boxes addObject:[self boxes]];
+ UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - totalBoxesWidth) * 0.5, 0, totalBoxesWidth, kPasscodeBoxHeight)];
+ boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ for (int i = 0; i < [[_boxes lastObject] count]; i++) {
+ [boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
+ }
+ [_enterPasscodeTableView.tableHeaderView addSubview:boxesView];
+ }
+
+ [self.view addSubview:[_tableViews objectAtIndex:0]];
+
+ for (int i = 1; i < [_tableViews count]; i++) {
+ UITableView *tableView = [_tableViews objectAtIndex:i];
+ tableView.frame = CGRectMake(tableView.frame.origin.x + self.view.bounds.size.width,
+ tableView.frame.origin.y,
+ tableView.frame.size.width,
+ tableView.frame.size.height);
+ [self.view addSubview:tableView];
+ }
+
+ [[_textFields objectAtIndex:0] becomeFirstResponder];
+ [[_tableViews objectAtIndex:0] reloadData];
+ [[_textFields objectAtIndex:[_tableViews count] - 1] setReturnKeyType:UIReturnKeyDone];
+
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ if ([_tableViews count] > 1) {
+ [self moveToNextTableView];
+ [self moveToPreviousTableView];
+ } else {
+ UITableView *tableView = [_tableViews objectAtIndex:0];
+ tableView.frame = CGRectMake(tableView.frame.origin.x,
+ tableView.frame.origin.y,
+ self.view.bounds.size.width,
+ self.view.bounds.size.height);
+ }
+
+ if (!self.dimView) {
+ id appDelegate = [[UIApplication sharedApplication] delegate];
+ self.dimView = [[UIView alloc] initWithFrame:appDelegate.window.rootViewController.view.bounds];
+ self.dimView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.dimView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
+ self.dimView.alpha = 0.0f;
+ [appDelegate.window.rootViewController.view addSubview:self.dimView];
+ [UIView animateWithDuration:0.3f animations:^{
+ self.dimView.alpha = 1.0f;
+ }];
+ }
+ }
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-#pragma mark Private
-
+- (void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+
+ _shouldReleaseFirstResponser = YES;
+ [_enterPasscodeTextField resignFirstResponder];
+ [_setPasscodeTextField resignFirstResponder];
+ [_confirmPasscodeTextField resignFirstResponder];
+
+ if (self.dimView) {
+ [UIView animateWithDuration:0.3f
+ animations:^{
+ self.dimView.alpha = 0.0f;
+ }
+ completion:^(BOOL finished) {
+ [self.dimView removeFromSuperview];
+ self.dimView = nil;
+ }];
+ }
+}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (UITextField*)allocAndInitPasscodeTextField
+- (void)viewDidLayoutSubviews
{
- UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(29.0, 13.0, 271.0, 24.0)];
- textField.text = @"";
- textField.textColor = [UIColor colorWithRed:0.220 green:0.329 blue:0.529 alpha:1.0];
- textField.secureTextEntry = YES;
- textField.delegate = self;
-
- textField.keyboardAppearance = UIKeyboardAppearanceAlert;
-
- return textField;
+ [super viewDidLayoutSubviews];
+
+ CGRect frame = _passcodeConfirmationWarningLabel.frame;
+ frame.origin.x = 10.0f;
+ frame.size.width = self.view.frame.size.width - 10.0f*2;
+
+ _passcodeConfirmationWarningLabel.frame = frame;
}
+#pragma mark -
+#pragma mark Private methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
--(void)cancelButtonPressed:(id)sender
+- (UIImage *)boxEmpty
{
- [self dismissModalViewControllerAnimated:YES];
+ if (floor(NSFoundationVersionNumber) > 993.00) {
+ return [UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty_ios7"];
+ } else {
+ return [UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty"];
+ }
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)addNextButton
+- (UIImage *)boxFilled
{
- if (!_simplePasscodeOn) {
- UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextButtonPressed:)];
- self.navigationItem.rightBarButtonItem = nextButton;
- [nextButton release];
- }
+ if (floor(NSFoundationVersionNumber) > 993.00) {
+ return [UIImage imageNamed:@"KKPasscodeLock.bundle/box_filled_ios7"];
+ } else {
+ return [UIImage imageNamed:@"KKPasscodeLock.bundle/box_filled"];
+ }
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)addDoneButton
+- (void)cancelButtonPressed:(id)sender
{
- if (!_simplePasscodeOn) {
- UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)];
- self.navigationItem.rightBarButtonItem = doneButton;
- [doneButton release];
- }
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)incrementAndShowFailedAttemptsLabel
+- (void)incrementFailedAttemptsLabel
{
- _enterPasscodeTextField.text = @"";
- if (_simplePasscodeOn) {
- for (int i = 0; i < 4; i++) {
- [[[_squares objectAtIndex:_tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
- }
- }
-
- _failedAttemptsCount += 1;
- if (_failedAttemptsCount == 1) {
- _failedAttemptsLabel.text = @"1 Failed Passcode Attempt";
- } else {
- _failedAttemptsLabel.text = [NSString stringWithFormat:@"%i Failed Passcode Attempts", _failedAttemptsCount];
- }
- CGSize size = [_failedAttemptsLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]];
- _failedAttemptsView.frame = CGRectMake((_viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0);
- _failedAttemptsLabel.frame = CGRectMake((_viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0);
-
- CAGradientLayer *gradient = [CAGradientLayer layer];
- gradient.frame = _failedAttemptsView.bounds;
- gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor],
- (id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil];
- [_failedAttemptsView.layer insertSublayer:gradient atIndex:0];
- _failedAttemptsView.layer.masksToBounds = YES;
-
- _failedAttemptsLabel.hidden = NO;
- _failedAttemptsView.hidden = NO;
-
- if (_failedAttemptsCount == 10 && _eraseData) {
- if ([KKKeychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
- [KKKeychain setString:@"" forKey:@"passcode_lock_passcode"];
- }
- [self dismissModalViewControllerAnimated:YES];
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- [UIView beginAnimations:@"fadeIn" context:nil];
- [UIView setAnimationDelay:0.25];
- [UIView setAnimationDuration:0.5];
-
- [UIView commitAnimations];
- }
+ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
+
+ _enterPasscodeTextField.text = @"";
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ [[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[self boxEmpty]];
+ }
+
+ NSInteger _failedAttemptsCount = [[KKKeychain getStringForKey:@"failedAttemptsCount"] integerValue];
+
+ _failedAttemptsCount++;
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"You have entered an incorrect passcode too many times. All account data in this app has been deleted." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [alert show];
- [alert release];
- }
-
+ [KKKeychain setString:[NSString stringWithFormat:@"%ld", (long)_failedAttemptsCount] forKey:@"failedAttemptsCount"];
+
+ if (_failedAttemptsCount == 1) {
+ _failedAttemptsLabel.text = KKPasscodeLockLocalizedString(@"1 Failed Passcode Attempt", @"");
+ } else {
+ _failedAttemptsLabel.text = [NSString stringWithFormat:KKPasscodeLockLocalizedString(@"%i Failed Passcode Attempts", @""), _failedAttemptsCount];
+ }
+ CGSize size = [_failedAttemptsLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:self.isSmallLandscape ? 10.0f : 14.0f]];
+ _failedAttemptsLabel.frame = _failedAttemptsView.frame = CGRectMake((self.view.bounds.size.width - (size.width + (self.isSmallLandscape ? 20.0f : 40.0f))) / 2, self.isSmallLandscape ? 75.0f : 150.0f, size.width + (self.isSmallLandscape ? 20.0f : 40.0f), size.height + (self.isSmallLandscape ? 5.0f : 10.0f));
+
+ CAGradientLayer *gradient = [CAGradientLayer layer];
+ gradient.frame = _failedAttemptsView.bounds;
+ gradient.colors = [NSArray arrayWithObjects:
+ (id)[[UIColor colorWithRed:0.7 green:0.05 blue:0.05 alpha:1.0] CGColor],
+ (id)[[UIColor colorWithRed:0.8 green:0.2 blue:0.2 alpha:1.0] CGColor], nil];
+ [_failedAttemptsView.layer insertSublayer:gradient atIndex:0];
+ _failedAttemptsView.layer.masksToBounds = YES;
+
+ _failedAttemptsLabel.hidden = NO;
+ _failedAttemptsView.hidden = NO;
+
+ if (_failedAttemptsCount == [[KKPasscodeLock sharedLock] attemptsAllowed]) {
+
+ _enterPasscodeTextField.delegate = nil;
+
+ if (_eraseData) {
+ if ([_delegate respondsToSelector:@selector(shouldEraseApplicationData:)]) {
+ [_delegate shouldEraseApplicationData:self];
+ }
+ } else {
+ if ([_delegate respondsToSelector:@selector(didPasscodeEnteredIncorrectly:)]) {
+ [_delegate didPasscodeEnteredIncorrectly:self];
+ }
+
+ [KKKeychain setString:[[KKPasscodeLock sharedLock].dateFormatter stringFromDate:[NSDate date]] forKey:@"incorrect_passcode_datetime"];
+
+ if ([_delegate respondsToSelector:@selector(shouldLockApplication:)]) {
+ [_delegate shouldLockApplication:self];
+ }
+ }
+
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+ }
+
}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)moveToNextTableView
{
- _tableIndex += 1;
- UITableView *oldTableView = [_tableViews objectAtIndex:_tableIndex - 1];
- UITableView *newTableView = [_tableViews objectAtIndex:_tableIndex];
- newTableView.frame = CGRectMake(oldTableView.frame.origin.x + _viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
-
- if (_simplePasscodeOn) {
- for (int i = 0; i < 4; i++) {
- [[[_squares objectAtIndex:_tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
- }
- }
-
- [UIView beginAnimations:@"" context:nil];
- [UIView setAnimationDuration:0.25];
- oldTableView.frame = CGRectMake(oldTableView.frame.origin.x - _viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
- newTableView.frame = self.view.frame;
- [UIView commitAnimations];
-
- if (_tableIndex == [_tableViews count] - 1) {
- [self addDoneButton];
- } else {
- [self addNextButton];
- }
-
- [[_textFields objectAtIndex:_tableIndex - 1] resignFirstResponder];
- [[_textFields objectAtIndex:_tableIndex] becomeFirstResponder];
+ _currentPanel += 1;
+
+ UITableView *oldTableView = [_tableViews objectAtIndex:_currentPanel - 1];
+ UITableView *newTableView = [_tableViews objectAtIndex:_currentPanel];
+
+ newTableView.frame = CGRectMake(oldTableView.frame.origin.x + self.view.bounds.size.width,
+ oldTableView.frame.origin.y,
+ oldTableView.frame.size.width,
+ oldTableView.frame.size.height);
+
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ [[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[self boxEmpty]];
+ }
+
+ [UIView beginAnimations:@"" context:nil];
+ [UIView setAnimationDuration:0.25];
+ newTableView.frame = oldTableView.frame;
+ oldTableView.frame = CGRectMake(oldTableView.frame.origin.x - self.view.bounds.size.width, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
+ [UIView commitAnimations];
+
+ _shouldReleaseFirstResponser = YES;
+ [[_textFields objectAtIndex:_currentPanel - 1] resignFirstResponder];
+ _shouldReleaseFirstResponser = NO;
+ [[_textFields objectAtIndex:_currentPanel] becomeFirstResponder];
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)moveToPreviousTableView
{
- _tableIndex -= 1;
- UITableView *oldTableView = [_tableViews objectAtIndex:_tableIndex + 1];
- UITableView *newTableView = [_tableViews objectAtIndex:_tableIndex];
- newTableView.frame = CGRectMake(oldTableView.frame.origin.x - _viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
-
- if (_simplePasscodeOn) {
- for (int i = 0; i < 4; i++) {
- [[[_squares objectAtIndex:_tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
- }
- }
-
- [UIView beginAnimations:@"" context:nil];
- [UIView setAnimationDuration:0.25];
- oldTableView.frame = CGRectMake(oldTableView.frame.origin.x + _viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
- newTableView.frame = self.view.frame;
- [UIView commitAnimations];
-
- if (_tableIndex == [_tableViews count] - 1) {
- [self addDoneButton];
- } else {
- [self addNextButton];
- }
-
- [[_textFields objectAtIndex:_tableIndex + 1] resignFirstResponder];
- [[_textFields objectAtIndex:_tableIndex] becomeFirstResponder];
+ _currentPanel -= 1;
+
+ UITableView *oldTableView = [_tableViews objectAtIndex:_currentPanel + 1];
+ UITableView *newTableView = [_tableViews objectAtIndex:_currentPanel];
+ newTableView.frame = CGRectMake(oldTableView.frame.origin.x - self.view.bounds.size.width, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
+
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ [[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[self boxEmpty]];
+ }
+
+ [UIView beginAnimations:@"" context:nil];
+ [UIView setAnimationDuration:0.25];
+ newTableView.frame = oldTableView.frame;
+ oldTableView.frame = CGRectMake(oldTableView.frame.origin.x + self.view.bounds.size.width, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
+ [UIView commitAnimations];
+
+ _shouldReleaseFirstResponser = YES;
+ [[_textFields objectAtIndex:_currentPanel + 1] resignFirstResponder];
+ _shouldReleaseFirstResponser = NO;
+ [[_textFields objectAtIndex:_currentPanel] becomeFirstResponder];
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)nextButtonPressed:(id)sender
+- (void)nextDigitPressed
{
-
- UITextField *textField = [_textFields objectAtIndex:_tableIndex];
-
- if (![textField.text isEqualToString:@""]) {
-
- if (mode == KKPasscodeModeSet) {
- if ([textField isEqual:_setPasscodeTextField]) {
- [self moveToNextTableView];
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
+ UITextField* textField = [_textFields objectAtIndex:_currentPanel];
+
+ if (![textField.text isEqualToString:@""]) {
+
+ if (_mode == KKPasscodeModeSet) {
+ if ([textField isEqual:_setPasscodeTextField]) {
+ [self moveToNextTableView];
+ } else if ([textField isEqual:_confirmPasscodeTextField]) {
+ if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
+ _confirmPasscodeTextField.text = @"";
+ _setPasscodeTextField.text = @"";
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Passcodes did not match. Try again.", @"");
+ [self moveToPreviousTableView];
+ } else {
+ if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode"]) {
+ [KKKeychain setString:@"YES" forKey:@"passcode_on"];
+ }
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
+ }
+ }
+ } else if (_mode == KKPasscodeModeChange) {
+ NSString* passcode = [KKKeychain getStringForKey:@"passcode"];
+ if ([textField isEqual:_enterPasscodeTextField]) {
+ if ([passcode isEqualToString:_enterPasscodeTextField.text]) {
+ [self moveToNextTableView];
+ } else {
+ [self incrementFailedAttemptsLabel];
+ }
+ } else if ([textField isEqual:_setPasscodeTextField]) {
+ if ([passcode isEqualToString:_setPasscodeTextField.text]) {
+ _setPasscodeTextField.text = @"";
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Enter a different passcode. You cannot re-use the same passcode.", @"");
+ _passcodeConfirmationWarningLabel.frame = CGRectMake(10.0, 132.0, self.view.bounds.size.width - 10.0*2, 60.0);
+ } else {
+ _passcodeConfirmationWarningLabel.text = @"";
+ _passcodeConfirmationWarningLabel.frame = CGRectMake(10.0, 146.0, self.view.bounds.size.width - 10.0*2, 30.0);
+ [self moveToNextTableView];
+ }
+ } else if ([textField isEqual:_confirmPasscodeTextField]) {
+ if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
+ _confirmPasscodeTextField.text = @"";
+ _setPasscodeTextField.text = @"";
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Passcodes did not match. Try again.", "");
+ [self moveToPreviousTableView];
+ } else {
+ if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode"]) {
+ [KKKeychain setString:@"YES" forKey:@"passcode_on"];
+ }
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
+ }
+ }
+ }
+ }
+}
+
+- (void)vaildatePasscode:(UITextField*)textField
+{
+ if (_mode == KKPasscodeModeDisabled) {
+ NSString *passcode = [KKKeychain getStringForKey:@"passcode"];
+ if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
+ if ([KKKeychain setString:@"NO" forKey:@"passcode_on"]) {
+ [KKKeychain setString:@"" forKey:@"passcode"];
+ }
+
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
} else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
+ [self incrementFailedAttemptsLabel];
}
- }
- } else if (mode == KKPasscodeModeChange) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([textField isEqual:_enterPasscodeTextField]) {
- if ([passcode isEqualToString:_enterPasscodeTextField.text]) {
- [self moveToNextTableView];
+ } else if (_mode == KKPasscodeModeEnter) {
+ NSString *passcode = [KKKeychain getStringForKey:@"passcode"];
+ if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ [UIView beginAnimations:@"fadeIn" context:nil];
+ [UIView setAnimationDelay:0.25];
+ [UIView setAnimationDuration:0.5];
+
+ [UIView commitAnimations];
+ }
+ if ([_delegate respondsToSelector:@selector(didPasscodeEnteredCorrectly:)]) {
+ [_delegate performSelector:@selector(didPasscodeEnteredCorrectly:) withObject:self];
+ }
+
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
} else {
- [self incrementAndShowFailedAttemptsLabel];
+ [self incrementFailedAttemptsLabel];
}
- } else if ([textField isEqual:_setPasscodeTextField]) {
- if ([passcode isEqualToString:_setPasscodeTextField.text]) {
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, _viewWidth, 60.0);
- } else {
- _passcodeConfirmationWarningLabel.text = @"";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, _viewWidth, 30.0);
- [self moveToNextTableView];
+ } else if (_mode == KKPasscodeModeChange) {
+ NSString *passcode = [KKKeychain getStringForKey:@"passcode"];
+ if ([textField isEqual:_enterPasscodeTextField]) {
+ if ([passcode isEqualToString:_enterPasscodeTextField.text]) {
+ [KKKeychain setString:@"0" forKey:@"failedAttemptsCount"];
+ [self moveToNextTableView];
+ } else {
+ [self incrementFailedAttemptsLabel];
+ }
+ } else if ([textField isEqual:_setPasscodeTextField]) {
+ if ([passcode isEqualToString:_setPasscodeTextField.text]) {
+ _setPasscodeTextField.text = @"";
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ [[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[self boxEmpty]];
+ }
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Enter a different passcode. You cannot re-use the same passcode.", @"");
+ _passcodeConfirmationWarningLabel.frame = CGRectMake(10.0, 132.0, self.view.bounds.size.width - 10.0*2, 60.0);
+ } else {
+ _passcodeConfirmationWarningLabel.text = @"";
+ _passcodeConfirmationWarningLabel.frame = CGRectMake(10.0, 146.0, self.view.bounds.size.width - 10.0*2, 30.0);
+ [self moveToNextTableView];
+ }
+ } else if ([textField isEqual:_confirmPasscodeTextField]) {
+ if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
+ _confirmPasscodeTextField.text = @"";
+ _setPasscodeTextField.text = @"";
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Passcodes did not match. Try again.", @"");
+ [self moveToPreviousTableView];
+ } else {
+ if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode"]) {
+ [KKKeychain setString:@"YES" forKey:@"passcode_on"];
+ }
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
+ }
}
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
+ } else if ([textField isEqual:_setPasscodeTextField]) {
+ [self moveToNextTableView];
+ } else if ([textField isEqual:_confirmPasscodeTextField]) {
if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
+ _confirmPasscodeTextField.text = @"";
+ _setPasscodeTextField.text = @"";
+ _passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Passcodes did not match. Try again.", @"");
+ [self moveToPreviousTableView];
} else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
+ if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode"]) {
+ [KKKeychain setString:@"YES" forKey:@"passcode_on"];
+ }
+
+ if ([_delegate respondsToSelector:@selector(didSettingsChanged:)]) {
+ [_delegate performSelector:@selector(didSettingsChanged:) withObject:self];
+ }
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ [self dismissModalViewControllerAnimated:YES];
+#else
+ [self dismissViewControllerAnimated:YES completion:nil];
+#endif
}
- }
}
- }
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)doneButtonPressed:(id)sender
+- (void)doneButtonPressed
{
-
- UITextField *textField = [_textFields objectAtIndex:_tableIndex];
-
- if (mode == KKPasscodeModeEnter) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- [UIView beginAnimations:@"fadeIn" context:nil];
- [UIView setAnimationDelay:0.25];
- [UIView setAnimationDuration:0.5];
-
- [UIView commitAnimations];
- }
- [self dismissModalViewControllerAnimated:YES];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- } else if (mode == KKPasscodeModeSet) {
- if ([textField isEqual:_setPasscodeTextField]) {
- [self moveToNextTableView];
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
- } else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
- }
- }
- } else if (mode == KKPasscodeModeChange) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([textField isEqual:_enterPasscodeTextField]) {
- if ([passcode isEqualToString:_enterPasscodeTextField.text]) {
- [self moveToNextTableView];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- } else if ([textField isEqual:_setPasscodeTextField]) {
- if ([passcode isEqualToString:_setPasscodeTextField.text]) {
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, _viewWidth, 60.0);
- } else {
- _passcodeConfirmationWarningLabel.text = @"";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, _viewWidth, 30.0);
- [self moveToNextTableView];
- }
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
- } else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
- }
- }
- } else if (mode == KKPasscodeModeDisabled) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
- if ([KKKeychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
- [KKKeychain setString:@"" forKey:@"passcode_lock_passcode"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- }
+ UITextField *textField = [_textFields objectAtIndex:_currentPanel];
+ [self vaildatePasscode:textField];
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (UIView*)passwordHeaderViewForTextField:(UITextField*)textField
+- (UIView*)headerViewForTextField:(UITextField*)textField
{
-
- if (_simplePasscodeOn) {
- textField.keyboardType = UIKeyboardTypeNumberPad;
-
- textField.hidden = YES;
[self.view addSubview:textField];
- } else {
- textField.keyboardType = UIKeyboardTypeDefault;
- textField.returnKeyType = UIReturnKeyNext;
- }
-
- UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, _viewWidth, 70.0)] autorelease];
- UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 27.5, _viewWidth, 30.0)];
- headerLabel.textColor = [UIColor colorWithRed:0.298 green:0.337 blue:0.424 alpha:1.0];
- headerLabel.backgroundColor = [UIColor clearColor];
- headerLabel.textAlignment = UITextAlignmentCenter;
- headerLabel.font = [UIFont boldSystemFontOfSize:17.0];
- headerLabel.shadowOffset = CGSizeMake(0, 1.0);
- headerLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
-
- if ([textField isEqual:_setPasscodeTextField]) {
- _passcodeConfirmationWarningLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 146.5, _viewWidth, 30.0)];
- _passcodeConfirmationWarningLabel.textColor = [UIColor colorWithRed:0.298 green:0.337 blue:0.424 alpha:1.0];
- _passcodeConfirmationWarningLabel.backgroundColor = [UIColor clearColor];
- _passcodeConfirmationWarningLabel.textAlignment = UITextAlignmentCenter;
- _passcodeConfirmationWarningLabel.font = [UIFont systemFontOfSize:14.0];
- _passcodeConfirmationWarningLabel.shadowOffset = CGSizeMake(0, 1.0);
- _passcodeConfirmationWarningLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
- _passcodeConfirmationWarningLabel.text = @"";
- _passcodeConfirmationWarningLabel.numberOfLines = 0;
- _passcodeConfirmationWarningLabel.lineBreakMode = UILineBreakModeWordWrap;
- [headerView addSubview:_passcodeConfirmationWarningLabel];
- }
-
- if ([textField isEqual:_enterPasscodeTextField]) {
-
- NSString *text = @"1 Failed Passcode Attempt";
- CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]];
- _failedAttemptsView = [[UIView alloc] initWithFrame:CGRectMake((_viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)];
- _failedAttemptsLabel = [[UILabel alloc] initWithFrame:CGRectMake((_viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)];
- _failedAttemptsLabel.backgroundColor = [UIColor clearColor];
- _failedAttemptsLabel.textColor = [UIColor whiteColor];
- _failedAttemptsLabel.text = text;
- _failedAttemptsLabel.font = [UIFont boldSystemFontOfSize:14.0];
- _failedAttemptsLabel.textAlignment = UITextAlignmentCenter;
- _failedAttemptsLabel.shadowOffset = CGSizeMake(0, -1.0);
- _failedAttemptsLabel.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
- _failedAttemptsView.layer.cornerRadius = 14;
- _failedAttemptsView.layer.borderWidth = 1.0;
- _failedAttemptsView.layer.borderColor = [[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.25] CGColor];
+ UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, 70.0)];
+ UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, self.isSmallLandscape ? 2.0f : 28.0f, self.view.bounds.size.width, 30.0)];
+ headerLabel.textColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.4 alpha:1.0];
+ headerLabel.backgroundColor = [UIColor clearColor];
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ headerLabel.textAlignment = UITextAlignmentCenter;
+#else
+ headerLabel.textAlignment = NSTextAlignmentCenter;
+#endif
- _failedAttemptsLabel.hidden = YES;
- _failedAttemptsView.hidden = YES;
-
- CAGradientLayer *gradient = [CAGradientLayer layer];
- gradient.frame = _failedAttemptsView.bounds;
- gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor],
- (id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil];
- [_failedAttemptsView.layer insertSublayer:gradient atIndex:1];
- _failedAttemptsView.layer.masksToBounds = YES;
-
- [headerView addSubview:_failedAttemptsView];
- [headerView addSubview:_failedAttemptsLabel];
-
- [_failedAttemptsView release];
- [_failedAttemptsLabel release];
- }
-
- if (mode == KKPasscodeModeSet) {
- self.navigationItem.title = @"Set Passcode";
- UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
- self.navigationItem.leftBarButtonItem = cancel;
- [cancel release];
-
-
- if ([textField isEqual:_enterPasscodeTextField]) {
- headerLabel.text = @"Enter your passcode";
- } else if ([textField isEqual:_setPasscodeTextField]) {
- headerLabel.text = @"Enter a passcode";
- UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
- self.navigationItem.leftBarButtonItem = cancel;
- [cancel release];
-
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- headerLabel.text = @"Re-enter your passcode";
+ headerLabel.font = [UIFont boldSystemFontOfSize:self.isSmallLandscape ? 12.0f : 17.0f];
+
+ if ((floor(NSFoundationVersionNumber) <= 993.00)) {
+ headerLabel.shadowOffset = CGSizeMake(0, 1.0);
+ headerLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
}
- } else if (mode == KKPasscodeModeDisabled) {
- self.navigationItem.title = @"Turn off Passcode";
- UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
- self.navigationItem.leftBarButtonItem = cancel;
- [cancel release];
-
- headerLabel.text = @"Enter your passcode";
- } else if (mode == KKPasscodeModeChange) {
- self.navigationItem.title = @"Change Passcode";
- UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
- self.navigationItem.leftBarButtonItem = cancel;
- [cancel release];
-
- if ([textField isEqual:_enterPasscodeTextField]) {
- headerLabel.text = @"Enter your old passcode";
- } else if ([textField isEqual:_setPasscodeTextField]) {
- headerLabel.text = @"Enter your new passcode";
+
+ if ([textField isEqual:_setPasscodeTextField]) {
+ _passcodeConfirmationWarningLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, self.isSmallLandscape ? 73.0f : 146.0, self.view.frame.size.width - 10.0*2, 30.0)];
+ _passcodeConfirmationWarningLabel.textColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.4 alpha:1.0];
+ _passcodeConfirmationWarningLabel.backgroundColor = [UIColor clearColor];
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ _passcodeConfirmationWarningLabel.textAlignment = UITextAlignmentCenter;
+#else
+ _passcodeConfirmationWarningLabel.textAlignment = NSTextAlignmentCenter;
+#endif
+
+ _passcodeConfirmationWarningLabel.font = [UIFont systemFontOfSize:14.0];
+ if ((floor(NSFoundationVersionNumber) <= 993.00)) {
+ _passcodeConfirmationWarningLabel.shadowOffset = CGSizeMake(0, 1.0);
+ _passcodeConfirmationWarningLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
+ }
+ _passcodeConfirmationWarningLabel.text = @"";
+ _passcodeConfirmationWarningLabel.numberOfLines = 0;
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ _passcodeConfirmationWarningLabel.lineBreakMode = UILineBreakModeWordWrap;
+#else
+ _passcodeConfirmationWarningLabel.lineBreakMode = NSLineBreakByWordWrapping;
+#endif
+
+ [headerView addSubview:_passcodeConfirmationWarningLabel];
+ }
+
+ if ([textField isEqual:_enterPasscodeTextField]) {
+ _failedAttemptsView = [[UIView alloc] init];
+ _failedAttemptsLabel = [[UILabel alloc] init];
+ _failedAttemptsLabel.backgroundColor = [UIColor clearColor];
+ _failedAttemptsLabel.textColor = [UIColor whiteColor];
+ _failedAttemptsLabel.text = @"";
+ _failedAttemptsLabel.font = [UIFont boldSystemFontOfSize:self.isSmallLandscape ? 10.0f : 14.0f];
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+ _failedAttemptsLabel.textAlignment = UITextAlignmentCenter;
+#else
+ _failedAttemptsLabel.textAlignment = NSTextAlignmentCenter;
+#endif
+ if ((floor(NSFoundationVersionNumber) <= 993.00)) {
+ _failedAttemptsLabel.shadowOffset = CGSizeMake(0, -1.0);
+ _failedAttemptsLabel.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
+ }
+ _failedAttemptsView.layer.cornerRadius = self.isSmallLandscape ? 7.0f : 14.0f;
+ _failedAttemptsView.layer.borderWidth = 1.0;
+ _failedAttemptsView.layer.borderColor = [[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.25] CGColor];
+
+ _failedAttemptsLabel.hidden = YES;
+ _failedAttemptsView.hidden = YES;
+
+ _failedAttemptsView.layer.masksToBounds = YES;
+
+ [headerView addSubview:_failedAttemptsView];
+ [headerView addSubview:_failedAttemptsLabel];
+ }
+
+ if (_mode == KKPasscodeModeSet) {
+ if ([textField isEqual:_enterPasscodeTextField]) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter your passcode", @"");
+ } else if ([textField isEqual:_setPasscodeTextField]) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter a passcode", @"");
+ } else if ([textField isEqual:_confirmPasscodeTextField]) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Re-enter your passcode", @"");
+ }
+ } else if (_mode == KKPasscodeModeDisabled) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter your passcode", @"");
+ } else if (_mode == KKPasscodeModeChange) {
+ if ([textField isEqual:_enterPasscodeTextField]) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter your old passcode", @"");
+ } else if ([textField isEqual:_setPasscodeTextField]) {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter your new passcode", @"");
+ } else {
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Re-enter your new passcode", @"");
+ }
} else {
- headerLabel.text = @"Re-enter your new passcode";
+ headerLabel.text = KKPasscodeLockLocalizedString(@"Enter your passcode", @"");
}
- } else {
- self.navigationItem.title = @"Enter Passcode";
- headerLabel.text = @"Enter your passcode";
- }
-
- [headerView addSubview:headerLabel];
- [headerLabel release];
-
- return headerView;
+
+ headerLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
+ [headerView addSubview:headerLabel];
+
+ return headerView;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (NSArray*)squares
+- (NSArray*)boxes
{
- NSMutableArray *squareViews = [[NSMutableArray alloc] initWithCapacity:4];
- NSInteger squareX = 23.0;
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- squareX = 133.0;
- }
-
- for (int i = 0; i < 4; i++) {
- UIImageView *square = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
- square.frame = CGRectMake(squareX, 74.0, 61.0, 53.0);
- [squareViews addObject:square];
- [square release];
- squareX += 71.0;
- }
- return [[NSArray alloc] initWithArray:squareViews];
+ NSMutableArray* squareViews = [NSMutableArray array];
+
+ CGFloat squareX = self.isSmallLandscape ? 60.0f : 0.0f;
+
+ CGFloat width = self.isSmallLandscape ? kPasscodeBoxWidth * 0.6f : kPasscodeBoxWidth;
+ CGFloat height = self.isSmallLandscape ? kPasscodeBoxHeight * 0.6f : kPasscodeBoxHeight;
+
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ UIImageView *square = [[UIImageView alloc] initWithImage:[self boxEmpty]];
+ square.frame = CGRectMake(squareX, self.isSmallLandscape ? 32.0f : 74.0, width, height);
+ [squareViews addObject:square];
+ squareX += self.isSmallLandscape ? 42.0f : 71.0;
+ }
+ return [NSArray arrayWithArray:squareViews];
}
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark Table view data source
-
+#pragma mark UITableViewDataSource methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return _simplePasscodeOn ? 0 : 1;
+- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
+{
+ return 0;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return 1;
+- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return 1;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
- static NSString *CellIdentifier = @"Cell";
-
- UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- }
-
- //cell.accessoryView = enterPasscodeTextField; //[textFields objectAtIndex:tableIndex];
- if ([aTableView isEqual:_enterPasscodeTableView]) {
- cell.accessoryView = _enterPasscodeTextField;
- } else if ([aTableView isEqual:_setPasscodeTableView]) {
- cell.accessoryView = _setPasscodeTextField;
- } else if ([aTableView isEqual:_confirmPasscodeTableView]) {
- cell.accessoryView = _confirmPasscodeTextField;
- }
-
- return cell;
+- (UITableViewCell*)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
+{
+ static NSString* CellIdentifier = @"KKPasscodeViewControllerCell";
+
+ UITableViewCell* cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ }
+
+ if ([aTableView isEqual:_enterPasscodeTableView]) {
+ cell.accessoryView = _enterPasscodeTextField;
+ } else if ([aTableView isEqual:_setPasscodeTableView]) {
+ cell.accessoryView = _setPasscodeTextField;
+ } else if ([aTableView isEqual:_confirmPasscodeTableView]) {
+ cell.accessoryView = _confirmPasscodeTextField;
+ }
+
+ return cell;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
-#pragma mark UITextFieldDelegate
-
+#pragma mark UITextFieldDelegate methods
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (BOOL)textFieldShouldReturn:(UITextField *)textField {
- if ([textField isEqual:[_textFields lastObject]]) {
- [self doneButtonPressed:nil];
- } else {
- [self nextButtonPressed:nil];
- }
- return NO;
+- (BOOL)textFieldShouldReturn:(UITextField*)textField
+{
+ if ([textField isEqual:[_textFields lastObject]]) {
+ [self doneButtonPressed];
+ } else {
+ [self nextDigitPressed];
+ }
+ return NO;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
-
- if (_simplePasscodeOn) {
+
+
+
+- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
+{
NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
-
textField.text = result;
- for (int i = 0; i < 4; i++) {
- UIImageView *square = [[_squares objectAtIndex:_tableIndex] objectAtIndex:i];
- if (i < [result length]) {
- square.image = [UIImage imageNamed:@"passcode_square_filled.png"];
- } else {
- square.image = [UIImage imageNamed:@"passcode_square_empty.png"];
- }
- }
-
- if ([result length] == 4) {
-
- if (mode == KKPasscodeModeDisabled) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
- if ([KKKeychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
- [KKKeychain setString:@"" forKey:@"passcode_lock_passcode"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- } else if (mode == KKPasscodeModeEnter) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([_enterPasscodeTextField.text isEqualToString:passcode]) {
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- [UIView beginAnimations:@"fadeIn" context:nil];
- [UIView setAnimationDelay:0.25];
- [UIView setAnimationDuration:0.5];
-
- [UIView commitAnimations];
- }
- [self dismissModalViewControllerAnimated:YES];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- } else if (mode == KKPasscodeModeChange) {
- NSString *passcode = [KKKeychain getStringForKey:@"passcode_lock_passcode"];
- if ([textField isEqual:_enterPasscodeTextField]) {
- if ([passcode isEqualToString:_enterPasscodeTextField.text]) {
- [self moveToNextTableView];
- } else {
- [self incrementAndShowFailedAttemptsLabel];
- }
- } else if ([textField isEqual:_setPasscodeTextField]) {
- if ([passcode isEqualToString:_setPasscodeTextField.text]) {
- _setPasscodeTextField.text = @"";
- for (int i = 0; i < 4; i++) {
- [[[_squares objectAtIndex:_tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
- }
- _passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, _viewWidth, 60.0);
- } else {
- _passcodeConfirmationWarningLabel.text = @"";
- _passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, _viewWidth, 30.0);
- [self moveToNextTableView];
- }
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
- } else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
- }
- }
- } else if ([textField isEqual:_setPasscodeTextField]) {
- [self moveToNextTableView];
- } else if ([textField isEqual:_confirmPasscodeTextField]) {
- if (![_confirmPasscodeTextField.text isEqualToString:_setPasscodeTextField.text]) {
- _confirmPasscodeTextField.text = @"";
- _setPasscodeTextField.text = @"";
- _passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
- [self moveToPreviousTableView];
+ for (int i = 0; i < kPasscodeBoxesCount; i++) {
+ UIImageView *square = [[_boxes objectAtIndex:_currentPanel] objectAtIndex:i];
+ if (i < [result length]) {
+ square.image = [self boxFilled];
} else {
- if ([KKKeychain setString:_setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
- [KKKeychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
- }
- [self.passcodeLockViewController.tableView reloadData];
- [self dismissModalViewControllerAnimated:YES];
+ square.image = [self boxEmpty];
}
- }
+ }
+
+ if ([result length] == kPasscodeBoxesCount) {
+ [self vaildatePasscode:textField];
}
return NO;
- }
-
- return YES;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-#pragma mark Memory management
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)dealloc {
-
- [_enterPasscodeTextField release];
- [_setPasscodeTextField release];
- [_confirmPasscodeTextField release];
- [_tableViews release];
- [_textFields release];
- [_squares release];
- [_passcodeLockViewController release];
-
- [super dealloc];
+- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
+ return _shouldReleaseFirstResponser;
}
+#pragma mark -
+#pragma mark Memory management
+
@end
diff --git a/src/passcode_square_empty.png b/src/passcode_square_empty.png
deleted file mode 100755
index 3c5c529..0000000
Binary files a/src/passcode_square_empty.png and /dev/null differ
diff --git a/src/passcode_square_empty@2x.png b/src/passcode_square_empty@2x.png
deleted file mode 100755
index 2a6e74f..0000000
Binary files a/src/passcode_square_empty@2x.png and /dev/null differ
diff --git a/src/passcode_square_filled.png b/src/passcode_square_filled.png
deleted file mode 100755
index d29c5c3..0000000
Binary files a/src/passcode_square_filled.png and /dev/null differ
diff --git a/src/passcode_square_filled@2x.png b/src/passcode_square_filled@2x.png
deleted file mode 100755
index d266578..0000000
Binary files a/src/passcode_square_filled@2x.png and /dev/null differ
diff --git a/tests/KKPasscodeLock/KKPasscodeLock-Prefix.pch b/tests/KKPasscodeLock/KKPasscodeLock-Prefix.pch
new file mode 100644
index 0000000..7c5cd99
--- /dev/null
+++ b/tests/KKPasscodeLock/KKPasscodeLock-Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'KKPasscodeLock' target in the 'KKPasscodeLock' project
+//
+
+#ifdef __OBJC__
+ #import
+#endif
diff --git a/tests/KKPasscodeLockTests.xcodeproj/project.pbxproj b/tests/KKPasscodeLockTests.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..6966be1
--- /dev/null
+++ b/tests/KKPasscodeLockTests.xcodeproj/project.pbxproj
@@ -0,0 +1,345 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5303097416611E650004810F /* KKPasscodeSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5303096916611E650004810F /* KKPasscodeSettingsViewController.m */; };
+ 5303097516611E650004810F /* KKPasscodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5303096A16611E650004810F /* KKPasscodeViewController.m */; };
+ 5303097716611E650004810F /* KKPasscodeLock.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5303096D16611E650004810F /* KKPasscodeLock.bundle */; };
+ 5303097816611E650004810F /* KKKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 5303096F16611E650004810F /* KKKeychain.m */; };
+ 5303097916611E650004810F /* KKPasscodeLock.m in Sources */ = {isa = PBXBuildFile; fileRef = 5303097016611E650004810F /* KKPasscodeLock.m */; };
+ 6D2394C81548CA89004DF3B7 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394C71548CA89004DF3B7 /* SenTestingKit.framework */; };
+ 6D2394CA1548CA89004DF3B7 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394C91548CA89004DF3B7 /* UIKit.framework */; };
+ 6D2394CB1548CA89004DF3B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394B91548CA89004DF3B7 /* Foundation.framework */; };
+ 6D2394D41548CA89004DF3B7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6D2394D21548CA89004DF3B7 /* InfoPlist.strings */; };
+ 6D2394D71548CA89004DF3B7 /* KKPasscodeLockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2394D61548CA89004DF3B7 /* KKPasscodeLockTests.m */; };
+ 6D2394F81548CBAA004DF3B7 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394F61548CBAA004DF3B7 /* AudioToolbox.framework */; };
+ 6D2394F91548CBAA004DF3B7 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394F71548CBAA004DF3B7 /* CoreGraphics.framework */; };
+ 6D2394FB1548CBAE004DF3B7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394FA1548CBAE004DF3B7 /* Security.framework */; };
+ 6D2394FD1548CBC5004DF3B7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2394FC1548CBC5004DF3B7 /* QuartzCore.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 5303096916611E650004810F /* KKPasscodeSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeSettingsViewController.m; path = ../../src/KKPasscodeSettingsViewController.m; sourceTree = ""; };
+ 5303096A16611E650004810F /* KKPasscodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeViewController.m; path = ../../src/KKPasscodeViewController.m; sourceTree = ""; };
+ 5303096D16611E650004810F /* KKPasscodeLock.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = KKPasscodeLock.bundle; path = ../../src/KKPasscodeLock.bundle; sourceTree = ""; };
+ 5303096E16611E650004810F /* KKPasscodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeViewController.h; path = ../../src/KKPasscodeViewController.h; sourceTree = ""; };
+ 5303096F16611E650004810F /* KKKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKKeychain.m; path = ../../src/KKKeychain.m; sourceTree = ""; };
+ 5303097016611E650004810F /* KKPasscodeLock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KKPasscodeLock.m; path = ../../src/KKPasscodeLock.m; sourceTree = ""; };
+ 5303097116611E650004810F /* KKPasscodeLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeLock.h; path = ../../src/KKPasscodeLock.h; sourceTree = ""; };
+ 5303097216611E650004810F /* KKKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKKeychain.h; path = ../../src/KKKeychain.h; sourceTree = ""; };
+ 5303097316611E650004810F /* KKPasscodeSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KKPasscodeSettingsViewController.h; path = ../../src/KKPasscodeSettingsViewController.h; sourceTree = ""; };
+ 6D2394B91548CA89004DF3B7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 6D2394BD1548CA89004DF3B7 /* KKPasscodeLock-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KKPasscodeLock-Prefix.pch"; sourceTree = ""; };
+ 6D2394C61548CA89004DF3B7 /* KKPasscodeLock.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KKPasscodeLock.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 6D2394C71548CA89004DF3B7 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ 6D2394C91548CA89004DF3B7 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ 6D2394D11548CA89004DF3B7 /* KKPasscodeLock-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "KKPasscodeLock-Info.plist"; sourceTree = ""; };
+ 6D2394D31548CA89004DF3B7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
+ 6D2394D51548CA89004DF3B7 /* KKPasscodeLockTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KKPasscodeLockTests.h; sourceTree = ""; };
+ 6D2394D61548CA89004DF3B7 /* KKPasscodeLockTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KKPasscodeLockTests.m; sourceTree = ""; };
+ 6D2394F61548CBAA004DF3B7 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ 6D2394F71548CBAA004DF3B7 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 6D2394FA1548CBAE004DF3B7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+ 6D2394FC1548CBC5004DF3B7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 6D2394C21548CA89004DF3B7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6D2394FD1548CBC5004DF3B7 /* QuartzCore.framework in Frameworks */,
+ 6D2394FB1548CBAE004DF3B7 /* Security.framework in Frameworks */,
+ 6D2394F81548CBAA004DF3B7 /* AudioToolbox.framework in Frameworks */,
+ 6D2394F91548CBAA004DF3B7 /* CoreGraphics.framework in Frameworks */,
+ 6D2394C81548CA89004DF3B7 /* SenTestingKit.framework in Frameworks */,
+ 6D2394CA1548CA89004DF3B7 /* UIKit.framework in Frameworks */,
+ 6D2394CB1548CA89004DF3B7 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 6D2394AB1548CA89004DF3B7 = {
+ isa = PBXGroup;
+ children = (
+ 6D2394BB1548CA89004DF3B7 /* KKPasscodeLock */,
+ 6D2394CF1548CA89004DF3B7 /* KKPasscodeLockTests */,
+ 6D2394B81548CA89004DF3B7 /* Frameworks */,
+ 6D2394B71548CA89004DF3B7 /* Products */,
+ );
+ sourceTree = "";
+ };
+ 6D2394B71548CA89004DF3B7 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 6D2394C61548CA89004DF3B7 /* KKPasscodeLock.octest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 6D2394B81548CA89004DF3B7 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 6D2394FC1548CBC5004DF3B7 /* QuartzCore.framework */,
+ 6D2394FA1548CBAE004DF3B7 /* Security.framework */,
+ 6D2394F61548CBAA004DF3B7 /* AudioToolbox.framework */,
+ 6D2394F71548CBAA004DF3B7 /* CoreGraphics.framework */,
+ 6D2394B91548CA89004DF3B7 /* Foundation.framework */,
+ 6D2394C71548CA89004DF3B7 /* SenTestingKit.framework */,
+ 6D2394C91548CA89004DF3B7 /* UIKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 6D2394BB1548CA89004DF3B7 /* KKPasscodeLock */ = {
+ isa = PBXGroup;
+ children = (
+ 5303096916611E650004810F /* KKPasscodeSettingsViewController.m */,
+ 5303096A16611E650004810F /* KKPasscodeViewController.m */,
+ 5303096D16611E650004810F /* KKPasscodeLock.bundle */,
+ 5303096E16611E650004810F /* KKPasscodeViewController.h */,
+ 5303096F16611E650004810F /* KKKeychain.m */,
+ 5303097116611E650004810F /* KKPasscodeLock.h */,
+ 5303097016611E650004810F /* KKPasscodeLock.m */,
+ 5303097216611E650004810F /* KKKeychain.h */,
+ 5303097316611E650004810F /* KKPasscodeSettingsViewController.h */,
+ 6D2394BC1548CA89004DF3B7 /* Supporting Files */,
+ );
+ path = KKPasscodeLock;
+ sourceTree = "";
+ };
+ 6D2394BC1548CA89004DF3B7 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 6D2394BD1548CA89004DF3B7 /* KKPasscodeLock-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+ 6D2394CF1548CA89004DF3B7 /* KKPasscodeLockTests */ = {
+ isa = PBXGroup;
+ children = (
+ 6D2394D51548CA89004DF3B7 /* KKPasscodeLockTests.h */,
+ 6D2394D61548CA89004DF3B7 /* KKPasscodeLockTests.m */,
+ 6D2394D01548CA89004DF3B7 /* Supporting Files */,
+ );
+ path = KKPasscodeLockTests;
+ sourceTree = "";
+ };
+ 6D2394D01548CA89004DF3B7 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 6D2394D11548CA89004DF3B7 /* KKPasscodeLock-Info.plist */,
+ 6D2394D21548CA89004DF3B7 /* InfoPlist.strings */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 6D2394C51548CA89004DF3B7 /* KKPasscodeLockTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 6D2394DD1548CA89004DF3B7 /* Build configuration list for PBXNativeTarget "KKPasscodeLockTests" */;
+ buildPhases = (
+ 6D2394C11548CA89004DF3B7 /* Sources */,
+ 6D2394C21548CA89004DF3B7 /* Frameworks */,
+ 6D2394C31548CA89004DF3B7 /* Resources */,
+ 6D2394C41548CA89004DF3B7 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = KKPasscodeLockTests;
+ productName = KKPasscodeLockTests;
+ productReference = 6D2394C61548CA89004DF3B7 /* KKPasscodeLock.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 6D2394AD1548CA89004DF3B7 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0430;
+ ORGANIZATIONNAME = "Kosher Penguin LLC";
+ };
+ buildConfigurationList = 6D2394B01548CA89004DF3B7 /* Build configuration list for PBXProject "KKPasscodeLockTests" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 6D2394AB1548CA89004DF3B7;
+ productRefGroup = 6D2394B71548CA89004DF3B7 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 6D2394C51548CA89004DF3B7 /* KKPasscodeLockTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 6D2394C31548CA89004DF3B7 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6D2394D41548CA89004DF3B7 /* InfoPlist.strings in Resources */,
+ 5303097716611E650004810F /* KKPasscodeLock.bundle in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 6D2394C41548CA89004DF3B7 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 6D2394C11548CA89004DF3B7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6D2394D71548CA89004DF3B7 /* KKPasscodeLockTests.m in Sources */,
+ 5303097416611E650004810F /* KKPasscodeSettingsViewController.m in Sources */,
+ 5303097516611E650004810F /* KKPasscodeViewController.m in Sources */,
+ 5303097816611E650004810F /* KKKeychain.m in Sources */,
+ 5303097916611E650004810F /* KKPasscodeLock.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 6D2394D21548CA89004DF3B7 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6D2394D31548CA89004DF3B7 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 6D2394D81548CA89004DF3B7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 6D2394D91548CA89004DF3B7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 6D2394DE1548CA89004DF3B7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLock-Prefix.pch";
+ INFOPLIST_FILE = "KKPasscodeLockTests/KKPasscodeLock-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = KKPasscodeLock;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ 6D2394DF1548CA89004DF3B7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "KKPasscodeLock/KKPasscodeLock-Prefix.pch";
+ INFOPLIST_FILE = "KKPasscodeLockTests/KKPasscodeLock-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = KKPasscodeLock;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 6D2394B01548CA89004DF3B7 /* Build configuration list for PBXProject "KKPasscodeLockTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6D2394D81548CA89004DF3B7 /* Debug */,
+ 6D2394D91548CA89004DF3B7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 6D2394DD1548CA89004DF3B7 /* Build configuration list for PBXNativeTarget "KKPasscodeLockTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6D2394DE1548CA89004DF3B7 /* Debug */,
+ 6D2394DF1548CA89004DF3B7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 6D2394AD1548CA89004DF3B7 /* Project object */;
+}
diff --git a/tests/KKPasscodeLockTests/KKPasscodeLock-Info.plist b/tests/KKPasscodeLockTests/KKPasscodeLock-Info.plist
new file mode 100644
index 0000000..0a33f6c
--- /dev/null
+++ b/tests/KKPasscodeLockTests/KKPasscodeLock-Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIdentifier
+ com.kosherpenguin.${PRODUCT_NAME:rfc1034identifier}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+
+
diff --git a/tests/KKPasscodeLockTests/KKPasscodeLockTests.h b/tests/KKPasscodeLockTests/KKPasscodeLockTests.h
new file mode 100644
index 0000000..6f02f46
--- /dev/null
+++ b/tests/KKPasscodeLockTests/KKPasscodeLockTests.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2011-2012 Kosher Penguin LLC
+// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#import
+
+@interface KKPasscodeLockTests : SenTestCase
+
+@end
diff --git a/tests/KKPasscodeLockTests/KKPasscodeLockTests.m b/tests/KKPasscodeLockTests/KKPasscodeLockTests.m
new file mode 100644
index 0000000..665587f
--- /dev/null
+++ b/tests/KKPasscodeLockTests/KKPasscodeLockTests.m
@@ -0,0 +1,47 @@
+//
+// Copyright 2011-2012 Kosher Penguin LLC
+// Created by Adar Porat (https://github.com/aporat) on 1/16/2012.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#import "KKPasscodeLockTests.h"
+#import "KKPasscodeLock.h"
+
+@implementation KKPasscodeLockTests
+
+- (void)setUp
+{
+ [super setUp];
+
+ // Set-up code here.
+}
+
+- (void)tearDown
+{
+ // Tear-down code here.
+
+ [super tearDown];
+}
+
+- (void)testDefaultSettings
+{
+ KKPasscodeLock* sharedLock = [KKPasscodeLock sharedLock];
+
+ STAssertEquals(sharedLock.eraseOption, YES, @"Erase option is default to YES");
+ STAssertEquals(sharedLock.attemptsAllowed, (NSUInteger)5, @"attemptsAllowed default to 5 tries");
+
+
+}
+
+@end
diff --git a/tests/KKPasscodeLockTests/en.lproj/InfoPlist.strings b/tests/KKPasscodeLockTests/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/tests/KKPasscodeLockTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+