Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A class to set/challenge for a passcode modelled closely on Apple's own, with some tasteful enhancements (iPhone only)

branch: master
README.textile

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:

  1. An incorrect passcode causes the entry screen to shake/shiver a little, just like the Mac OS X log-in dialogue does.
  2. You can set an increasing delay period after several incorrect passcode attempts, to slow down anyone who’s just guessing.

Screenshot

PasscodeViewController screenshot

Example usage

The controller can be used as follows.

.h

  #import "PasscodeViewController.h"

  typedef enum {
    PasscodeChallengeReasonProtectedAction,
    PasscodeChallengeReasonTurnOffPasscode
  } PasscodeChallengeReason;

  @interface MyController : SomeViewController <UIActionSheetDelegate, PasscodeViewControllerDelegate> {
    PasscodeChallengeReason challengeReason;
  }

  @end

.m

  // 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
  }

Notes

  • 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.

Suggested enhancements

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.)

Licence

This software is released under the MIT licence.

Something went wrong with that request. Please try again.