This is a passcode view controller that you’re free to use in your own iPhone apps. I developed it for mappiness.
See it in action by downloading the free app — and signing up — or by checking out this short screencast.
Appearance and behaviour is modelled very closely on the Apple original (in Settings > General > Passcode Lock), but there are a couple of optional, tasteful enhancements:
- An incorrect passcode causes the entry screen to shake/shiver a little, just like the Mac OS X log-in dialogue does.
- You can set an increasing delay period after several incorrect passcode attempts, to slow down anyone who’s just guessing.
The controller can be used as follows.
#import "PasscodeViewController.h"
typedef enum {
PasscodeChallengeReasonProtectedAction,
PasscodeChallengeReasonTurnOffPasscode
} PasscodeChallengeReason;
@interface MyController : SomeViewController <UIActionSheetDelegate, PasscodeViewControllerDelegate> {
PasscodeChallengeReason challengeReason;
}
@end
// PasscodeProtectedCellController delegate
- (void)doProtectedAction {
challengeReason = PasscodeChallengeReasonProtectedAction;
[PasscodeViewController challengeWithDelegate:self parentViewController:self];
}
- (void)showPasscodeOptions {
BOOL locked = !! [PasscodeViewController passcode];
UIActionSheet *as;
NSString *sheetTitle = @"Control access to (protected action)";
NSString *cancelLabel = @"Cancel";
if (locked) as = [[UIActionSheet alloc] initWithTitle:sheetTitle
delegate:self
cancelButtonTitle:cancelLabel
destructiveButtonTitle:nil
otherButtonTitles:@"Change Passcode", @"Turn Passcode off", nil];
else as = [[UIActionSheet alloc] initWithTitle:sheetTitle
delegate:self
cancelButtonTitle:cancelLabel
destructiveButtonTitle:nil
otherButtonTitles:@"Turn Passcode on", nil];
[as showInView:self.view]; // might alternatively be self.tableView
[as release];
}
// UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) // i.e. 'Turn Passcode on' or 'Change Passcode'
[PasscodeViewController setWithDelegate:self parentViewController:self];
else { // must be 'Turn Passcode off'
challengeReason = PasscodeChallengeReasonTurnOffPasscode;
[PasscodeViewController challengeWithDelegate:self parentViewController:self];
}
}
// PasscodeViewController delegate
- (void)passcodeChallengeSucceeded {
if (challengeReason == PasscodeChallengeReasonProtectedAction) {
// do the passcode-protected action
} else { // by elimination, we know that challengeReason == PasscodeChallengeReasonTurnOffPasscode
// so turn the passcode off...
[PasscodeViewController clear];
// ...and now do any necessary display changes to indicate that a passcode is no longer set
}
}
- (void)passcodeSetSucceeded {
// do any necessary display changes to indicate that a passcode is set
}
- All public-facing methods are class methods. These deal with allocating an instance, and instances release themselves when finished.
- If a challenge is requested when no passcode is set, no prompt is shown and the
passcodeChallengeSucceeded
delegate method is called immediately. - Automatic Reference Counting (ARC) is not used.
These things are all currently missing:
- Support for iPad
- Support for localisation (using a
.strings
file) - Localisations
- More/better documentation!
- Consistent use of Title Case (I hate title case. But I Want To Do What Apple Would Do. This is probably the leading cause of mental anguish when I do iOS development.)
This software is released under the MIT licence.