An iOS passcode lock with TouchID authentication written in Swift.

Last update: May 9, 2022

PasscodeLock

A Swift implementation of passcode lock for iOS with TouchID authentication.

Originally created by @yankodimitrov, hope you're doing well.

Installation

PasscodeLock requires Swift 2.0 and Xcode 7

CocoaPods

Podfile

To integrate PasscodeLock into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

pod 'PasscodeLock', '~> 1.0.2'

Then, run the following command:

$ pod install

Carthage

Add the following line to your Cartfile

github "velikanov/SwiftPasscodeLock"

Usage

  • Create an implementation of the PasscodeRepositoryType protocol.
import UIKit
import PasscodeLock

class PasscodeRepository: PasscodeRepositoryType {
    
    var hasPasscode: Bool = true
    var passcode: [String]?
    
    func savePasscode(passcode: [String]) {}
    
    func deletePasscode() {}
    
}
  • Create an implementation of the PasscodeLockConfigurationType protocol and set your preferred passcode lock configuration options. If you set the maximumInccorectPasscodeAttempts to a number greather than zero, when user will reach that number of incorrect passcode attempts a notification with name PasscodeLockIncorrectPasscodeNotification will be posted on the default NSNotificationCenter.
import UIKit
import PasscodeLock

class PasscodeLockConfiguration: PasscodeLockConfigurationType {
    let repository: PasscodeRepositoryType
    var passcodeLength = 4 // Specify the required amount of passcode digits
    var isTouchIDAllowed = true // Enable Touch ID
    var shouldRequestTouchIDImmediately = true // Use Touch ID authentication immediately
    var maximumInccorectPasscodeAttempts = 3 // Maximum incorrect passcode attempts
    
    init(repository: PasscodeRepositoryType) {
        self.repository = repository
    }
    
    init() {
        self.repository = PasscodeRepository() // The repository that was created earlier
    }
}
  • Create an instance of the PasscodeLockPresenter class. Next inside your UIApplicationDelegate implementation call it to present the passcode in didFinishLaunchingWithOptions and applicationDidEnterBackground methods. The passcode lock will be presented only if your user has set a passcode.

  • Allow your users to set a passcode by presenting the PasscodeLockViewController in .SetPasscode state:

let configuration = ... // your implementation of the PasscodeLockConfigurationType protocol

let passcodeViewController = PasscodeLockViewController(state: .SetPasscode, configuration: configuration)

presentViewController(passcodeViewController, animated: true, completion: nil)

You can present the PasscodeLockViewController in one of the four initial states using the LockState enumeration options: .EnterPasscode, .SetPasscode, .ChangePasscode, .RemovePasscode.

Also you can set the initial passcode lock state to your own implementation of the PasscodeLockStateType protocol.

Customization

Custom Design

The PasscodeLock will look for PasscodeLockView.xib inside your app bundle and if it can't find it will load its default one, so if you want to have a custom design create a new xib with the name PasscodeLockView and set its owner to an instance of PasscodeLockViewController class.

Keep in mind that when using custom classes that are defined in another module, you'll need to set the Module field to that module's name in the Identity Inspector:

Then connect the view outlet to the view of your xib file and make sure to conenct the remaining IBOutlets and IBActions.

PasscodeLock comes with two view components: PasscodeSignPlaceholderView and PasscodeSignButton that you can use to create your own custom designs. Both classes are @IBDesignable and @IBInspectable, so you can see their appearance and change their properties right inside the interface builder:

Localization

Take a look at PasscodeLock/en.lproj/PasscodeLock.strings for the localization keys. Here again the PasscodeLock will look for the PasscodeLock.strings file inside your app bundle and if it can't find it will use the default localization file.

Demo App

The demo app comes with a simple implementation of the PasscodeRepositoryType protocol that is using the NSUserDefaults to store and retrieve the passcode. In your real applications you will probably want to use the Keychain API. Keep in mind that the Keychain records will not be removed when your user deletes your app.

GitHub

https://github.com/velikanov/SwiftPasscodeLock
Comments
  • 1. Fixed a security issue

    Previously, inccorectPasscodeAttempts was reset to 0 after kill and restart. So an attacker can bypass the maximumInccorectPasscodeAttempts setting by killing and restarting the app after trying a different password again and again.

    Reviewed by happylance at 2016-05-16 03:07
  • 2. Made the value of reason in authenticateWithBiometrics injectable

    I've coded a potential solution to issue #20. This solution leverages PasscodeLockConfigurationType to optionally pass a value leveraged by authenticateWithBiometrics. If the value is not set in the implementation of the Configuration Type then the code falls back to the existing logic that uses the strings resource file.

    Reviewed by phampton24 at 2016-05-06 14:15
  • 3. Updates to accommodate FaceID and cancellable locks

    This pull request encompasses two issues.

    1. With the release of iOS 11.0 Apple released FaceID. Fortunately all of the calls are identical to using TouchId so there weren't any changes needed there. However, the current property names and text on the view controller do not reflect that. They were changed to a more generic "Biometric Authentication" to better reflect functionality. A potential improvement for this is that as of iOS 11.0 the device can differentiate between which functionality the device supports and we could change the text of the button on the controller to reflect this.

    2. Currently the only cancellable lock type is .remove which is done via the declaration of the type. This really doesn't make any sense. We should allow users to decide which locks are and are not cancellable. I have added a property to the PasscodeLockConfigurationType class which the view controller will key off of to show/hide the cancel button. Personally I think this makes more sense as the cancellation seems more like a configuration thing rather than a lock type thing.

    Reviewed by mjmarathon at 2017-11-23 02:33
  • 4. Touch ID misbehaviour

    The case is:

    1. Set the passcode
    2. Inactive the app
    3. Back to the app
    4. Unlock with Touch ID
    5. Remove the passcode
    6. Inactive the app
    7. Back to the App

    The expectation is normal use the app, however, a touch ID panel is there. Although I can press cancel and use the app normally, it should be a bug.

    When looking into the Library, there should be a coding error in PasscodeLockViewController.swift in func authenticateWithBiometrics, it should also check the passcodeConfiguration.repository.hasPasscode. Please update the library, Thanks.

    Reviewed by konnanl at 2016-05-31 10:11
  • 5. Make `authenticateWithBiometrics` public so as App can present it if needed

    Some apps need to be able to request TouchID immediately which is served by a nice option in the library. Furthermore, the nice thing with this library is that it can be easily extended for supporting more features. One feature that we have added to our app is passcode expiry after a time period. For example user wants to leave app unlocked for 3 minutes.

    In this case our flow is as follows:

    1. When app moves to background
      • Passcode is presented
      • A splash view is being added
    2. When app comes to foreground
      • We check if Passcode is expired
        • remove splash view
        • if not expired:
          • dismisss passcode view
          • *

    So for * the issue is that by setting shouldRequestTouchIDImmediately to true it will display the TouchID alert and there is no easy way to dismiss it. Apple has introduced LAContext().invalidate() at iOS9, although the animation has to happen and the user sees a flickering/annoying animation.

    So instead of this, it works better to leave shouldRequestTouchIDImmediately to false and call authenticateWithBiometrics in our apps' code if needed.

    p.s: passcodeConfiguration.shouldRequestTouchIDImmediately has been moved out of authenticateWithBiometrics as it doesn't feel to be in the right context and also caused the above scenario to not work.

    Reviewed by ziogaschr at 2016-02-03 16:40
  • 6. Add cancel option to Enter state

    Our team would like the option to be able to cancel out of the .EnterPasscode state.

    I thought of a couple different ways to do this:

    1. Set the default value for isCancellableAction on EnterPasswordState to true
    2. Make isCancellableAction on PasscodeLockStateType settable
    3. Add an associated value to LockState.EnterPasscode to allow for that state with or without a cancellable action.

    While all options had their pros and cons, I felt that the most flexible way to do this was option (3). Keep in mind that this breaks backwards compatibility, so it may be a good idea to wait for the next major release to add this in, but of course, it's up to the owners of this repo.

    Reviewed by jrmsklar at 2016-06-15 17:57
  • 7. Update README

    When customizing our Passcode view, I began by copying and pasting the PasscodeLockView.xib file into our app's main target. I noticed that the custom classes PasscodeSignPlaceholderView and PasscodeSignButton were not displaying/functioning in the Storyboard as expected. I then realized that it was because the Module field in the Identity Inspector was set to my current module, and not PasscodeLock. Changing it to PasscodeLock fixed that issue.

    I thought it'd be helpful to add a little note in the README reminding people to do this.

    That the image I added (identity-inspector.png) is not coming through in this, but it should as soon as this PR is merged into master.

    Reviewed by jrmsklar at 2016-06-15 16:22
  • 8. App switcher screenshot

    First of all thank you. This is a great project I really like it. But I have a problem with the screenshot in the app switcher. It only shows a white screen (not even the numpad). I would like to show the user a picture instead of the white screen is this possible? image

    Reviewed by LucasZL at 2016-03-20 19:09
  • 9. Add demo code for adding splash view

    Someone requested for code on how to add a splash view for when app is in task switcher.

    Code is not the best one as I didn't had much time now, but is a working example. I might add more later this month.

    @velikanov if you want merge this PR.

    Reviewed by ziogaschr at 2015-12-18 22:48
  • 10. Udpate passcode view on viewWillAppear

    In our app we are giving an option so as user can toggle on/off the isTouchIDAllowed in the implementation of PasscodeLockConfigurationType.

    So if the user changes the switch the PasscodeLockViewController will not update its view if it is already loaded.

    I can't think of any implications to Apps that already implemented the lib.

    Reviewed by ziogaschr at 2016-02-12 13:48
  • 11. Present PasscodeLock view over iOS system keyboard

    Currently, if iOS system keyboard is open in the main window in iOS9 then keyboard is being displayed on top the PasscodeLockPresenter. The bottom buttons of the PasscodeLockViewController [7,8,9,0 and TouchID + Cancel] are hidden below the iOS keyboard. While the iOS keyboard is active for the input element of the mainWindow and does not work for our Passcode screen.

    For fixing this a hack has been implemented and it was the only way that I found possible to make it work. Please check and advice if you see a better solution.

    Reviewed by ziogaschr at 2016-01-31 17:44
  • 12. Support FaceID

    Based on @mjmarathon PR #53

    • Removed @mjmarathon changes about cancelable locks
    • Added Localizable Strings
    • Fixed the outlets for PasscodeLockView.xib
    • Fixed demo

    Many thanks to @mjmarathon for the initial PR.

    Reviewed by ziogaschr at 2018-01-10 15:39
  • 13. PasscodeLockPresenter not showing passcode screen

    I'm calling:

    let presenter = PasscodeLockPresenter(mainWindow: UIApplication.shared.keyWindow, configuration: configuration)
    presenter.presentPasscodeLock()
    

    from didFinishLaunchingWithOptions and applicationDidEnterBackground but it doesn't seem to work properly.

    On launch, only the Touch ID alert shows up, and the passcode screen doesn't. On going to background, the passcode screen shows up in the task switcher, but when selecting the app, the screen goes away, and the Touch ID alert is not shown at all.

    Seems like it's something window related. This is on iOS 11.1

    Reviewed by moesalih at 2017-11-16 21:04
  • 14. dismissPasscodeLock(animated: Bool = true) called many times?

    Thanks for the great effort maintaining this library!

    Please refer to the screenshot below captured after repeatedly putting the Demo app into background, then to foreground to unlock, and background again: screen shot 2017-05-26 at 6 33 37 pm

    It appears that the method dismissPasscodeLock(animated: Bool = true) will be called many times, is that the expected behaviour? I was testing why the dismiss animation only works for the first time unlock but not the subsequent unlock, then found this.

    Please advise.

    Reviewed by klwoon at 2017-05-26 10:47
  • 15. mainWindow's windowLevel should not be changed

    Changing the main window's windowLevel will cause some unexpected issues, such as using the library with Intercom: https://github.com/intercom/intercom-ios because the Intercom window is using windowLevel = 0.1 or some other values.

    This library should use a value less than 0 to be the windowLevel for it's private passcodeLockWindow, and never change the windowLevel of the main window.

    When presenting the passcodeLockWindow, it's window level can be a bigger number (such UIWindowLevelStatusBar - 1), but once it's dismissed, it should be set back to a number less than UIWindowLevelNormal.

    Reviewed by bull-xu at 2017-05-11 02:50
  • 16. Use of UIApplication.shared prevents usage within ios extensions

    IOS extensions like share, document provider, etc do not allow access to UIAplication.shared.

    This results in a compile time error due to

    PasscodeLockPresenter.swift line 55.

    Reviewed by fuji7l at 2017-05-05 22:13
iOS 7 style Passcode Lock
iOS 7 style Passcode Lock

LTHPasscodeViewController Simple to use iOS 7 style Passcode - the one you get in Settings when changing your passcode. How to use Drag the contents o

May 28, 2022
A library for make a beautiful Passcode Lock View
A library for make a beautiful Passcode Lock View

SmileLock A library for make a beautiful Passcode Lock View, also support Touch ID. Requirements iOS 9.0+ Swift 4 (pod version 3.x), Swift 3 (pod vers

Jun 15, 2022
The TouchID authentication mechanism implemented in Swift.

iOS-TouchID-Swift The TouchID authentication mechanism implemented in Swift About In iOS 8, Apple provides a new framework named LocalAuthentication w

May 20, 2018
Framework for biometric authentication (via TouchID) in your application
Framework for biometric authentication (via TouchID) in your application

Features Requirements Communication Installation Usage Intro Biometric authentication availability Feature enabled/disabled for biometric authenticati

Apr 24, 2022
Use Apple FaceID or TouchID authentication in your app using BiometricAuthentication.
Use Apple FaceID or TouchID authentication in your app using BiometricAuthentication.

BiometricAuthentication Use Apple FaceID or TouchID authentication in your app using BiometricAuthentication. It's very simple and easy to use that ha

Jun 15, 2022
TouchID used easy on one line in your ViewController.

TouchIDExtension TouchID used easy on one line in your ViewController. ##Installation At this moment, You can install only a way, manually. For instal

Feb 26, 2020
TouchEncryptedJson - Simple project that accepts an input and encrypts it with the TouchID on a Mac

TouchEncryptedJson Simple project that accepts an input and encrypts it with the

Feb 11, 2022
iOS 14 checkra1n-jailbreak-targeted passcode interposition

lockdown I can't remember if this version (involving ksecured) is actually functioning, Started working on this right before I moved, haven't really w

Jun 15, 2022
A modal passcode input and validation view controller for iOS
A modal passcode input and validation view controller for iOS

TOPasscodeViewController A modal passcode input and validation view controller for iOS. TOPasscodeViewController is an open-source UIViewController su

Jun 12, 2022
Very simple swift wrapper for Biometric Authentication Services (Touch ID) on iOS.

SimpleTouch Very simple swift wrapper for Biometric Authentication Services (Touch ID) on iOS. Sample Project There is a SimpleTouchDemo target define

Mar 18, 2022
Two-Factor Authentication Client for iOS

Authenticator Two-Factor Authentication Client for iOS. Authenticator is a simple, free, and open source two-factor authentication app. It helps keep

Jun 24, 2022
An easy-to-use, open-source two-factor authentication app designed specifically for iOS.
An easy-to-use, open-source two-factor authentication app designed specifically for iOS.

Tofu An easy-to-use, open-source two-factor authentication app designed specifically for iOS. Tofu generates one-time passwords to help you protect yo

Jun 18, 2022
LocalAuth - Another Fusion library to implement the local authentication using Biometry

FusionLocalAuth Another Fusion library to implement the local authentication usi

Jan 13, 2022
The minimalistic, secure and open-source two-factor authentication app.
The minimalistic, secure and open-source two-factor authentication app.

Einmal /ˈainmaːl/ German: once The minimalistic, secure and open-source two-factor authentication app. Features ♻️ Cross-platform — available on Andro

Jun 7, 2022
A simple wrapper for the iOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift.

SwiftKeychainWrapper A simple wrapper for the iOS / tvOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift. Prov

Jun 25, 2022
A wrapper for Apple's Common Crypto library written in Swift.

IDZSwiftCommonCrypto A Swift wrapper for Apple's CommonCrypto library. IDZSwiftCommonCrypto works with both CocoaPods and Cathage. For more details on

Apr 8, 2022
A framework for the JOSE standards JWS, JWE, and JWK written in Swift.

JOSESwift is a modular and extensible framework for the JOSE standards JWS, JWE, and JWK written in Swift. ?? Please note that this implementation of

May 12, 2022
KeyClip is yet another Keychain library written in Swift.

KeyClip KeyClip is yet another Keychain library written in Swift. Features Multi Types ( String / NSDictionary / NSData ) Error Handling Settings ( kS

Feb 2, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

May 31, 2022