Implementing TouchID Authentication in iOS 8 Apps

From Techotopia
Revision as of 14:37, 5 May 2016 by Neil (Talk | contribs) (Text replacement - "<table border="0" cellspacing="0" width="100%">" to "<table border="0" cellspacing="0">")

Jump to: navigation, search
PreviousTable of ContentsNext
An iOS 8 Swift Gesture Recognition TutorialAn Overview of iOS 8 Collection View and Flow Layout


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


In the world of computer security, user authentication falls into the three categories of something you know, something you have and something you are. The “something you know” category typically involves a memorized password or PIN number and is considered the least secure option. A more secure option is the “something you have” approach which usually takes the form of a small authentication token or device which generates one-time access codes on request.

The final category, “something you are”, refers to a physical attribute that is unique to the user. This, of course, involves biometrics in the form of a retina scan, voice recognition or fingerprint.

With the iPhone 5s, Apple introduced a built-in fingerprint scanner which enabled users to access the device and make purchases in the iTunes, App and iBooks stores using fingerprint authentication. With the introduction of iOS 8, this biometric authentication capability can now be built into your own applications.


Contents


The Local Authentication Framework

TouchID based authentication for iOS applications is implemented using the Local Authentication Framework. The key class within this framework is the LAContext class which, among other tasks, is used to evaluate the authentication abilities of the device on which the application is running and perform the authentication.

Checking for TouchID Availability

Not all iOS devices have the fingerprint scanner and, even on devices with a scanner, not all users will have activated the TouchID authentication features. The first step in using TouchID authentication, therefore, is to check that TouchID authentication is a viable option on the device:

let context = LAContext()

var error: NSError?

if context.canEvaluatePolicy(
	LAPolicy.DeviceOwnerAuthenticationWithBiometrics, 
		error: &error) {
	// TouchID is available on the device
} else {
	// TouchID is not available on the device
	// No scanner or user has not set up TouchID
}

If TouchID authentication is not available, the reason can be identified by accessing the errorCode property of the error parameter and will fall into one of the following categories:

  • LAError.TouchIDNotEnrolled – The user has not enrolled any fingerprints into TouchID on the device.
  • LAError.PasscodeNotSet – The user has not yet configured a passcode on the device.
  • LAError.TouchIDNotAvailable – The device does not have a TouchID fingerprint scanner.

Evaluating TouchID Policy

In the event that TouchID is available, the next step is to evaluate the policy (which in terms of TouchID involves prompting the user to provide authentication). This task is performed by calling the evaluatePolicy method of the LAContext instance, passing through the authentication policy type and a message to be displayed to the user. The task is performed asynchronously and a reply closure expression called once the user has provided input:

context.evaluatePolicy(
	LAPolicy.DeviceOwnerAuthenticationWithBiometrics, 
	localizedReason: "Authentication is required for access", 
	reply: {(success, error) in
		// Code to handle reply here
  })

The reply closure expression is passed a Boolean value indicating the success or otherwise of the authentication and an NSError object from which the nature of any failure can be identified via the corresponding error code. Failure to authenticate will fall into one of the following three categories:

  • LAError.SystemCancel – The authentication process was cancelled by the operating system. This error typically occurs when the application is placed in the background.
  • LAError.UserCancel - The authentication process was cancelled by the user.
  • LAError.UserFallback – The user opted to authenticate using a password instead of using TouchID.

In the event of the user fallback, it is the responsibility of the application to prompt for and verify a password before providing access.

If the authentication process is successful, however, the application should provide the user with access to whatever screens, data or functionality were being protected.

A TouchID Example Project

Launch Xcode and create a new iOS Universal Single View Application project named TouchID using Swift as the programming language.

Select the Main.storyboard file and drag and drop a Button view so that it is positioned in the center of the storyboard scene. Double-click on the button and change the text so that it reads “Test TouchID”.

With the button still selected, display the Auto Layout Align menu and configure both horizontal and vertical Center in Container constraints.

Finally, display the Assistant Editor and Ctrl-click and drag from the button view to a position just beneath the viewDidLoad method in the ViewController.swift file. Release the line and, in the connection dialog, establish an Action connection to a method named testTouchID.

On completion of the user interface design the layout should resemble Figure 53-1:


Ios 8 touchid ui.png

Figure 53-1

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Checking for TouchID Availability

With the user interface designed, the next step is to add some code to the testTouchID function to verify that the device can handle TouchID authentication. Select the ViewController.swift file, import the LocalAuthentication Framework and add code to the testTouchID method as follows:

import UIKit
import LocalAuthentication

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func testTouchID(sender: AnyObject) {

        let context = LAContext()

        var error: NSError?

        if context.canEvaluatePolicy(
		LAPolicy.DeviceOwnerAuthenticationWithBiometrics, 
			error: &error) {

	      // Device can use TouchID

        } else {
	      // Device cannot use TouchID
            switch error!.code{

            case LAError.TouchIDNotEnrolled.rawValue:
                notifyUser("TouchID is not enrolled", 
			err: error?.localizedDescription)

            case LAError.PasscodeNotSet.rawValue:
                notifyUser("A passcode has not been set", 
			err: error?.localizedDescription)

            default:
                notifyUser("TouchID not available", 
			err: error?.localizedDescription)

            }
        }
    }
.
.
}

Before proceeding, implement the notifyUser method as follows:

func notifyUser(msg: String, err: String?) {
    let alert = UIAlertController(title: msg, 
		message: err, 
		preferredStyle: UIAlertControllerStyle.Alert)

    let cancelAction = UIAlertAction(title: "OK", 
		style: .Cancel, handler: nil)

    alert.addAction(cancelAction)

    self.presentViewController(alert, animated: true, 
			completion: nil)
}

Seeking TouchID Authentication

The next task is to attempt to obtain authentication from the user. This involves a call to the evaluatePolicy method of the local authentication context:

@IBAction func testTouchID(sender: AnyObject) {

    let context = LAContext()

    var error: NSError?

    if context.canEvaluatePolicy(
	LAPolicy.DeviceOwnerAuthenticationWithBiometrics, 
		error: &error) {

        // Device can use TouchID

            context.evaluatePolicy(
		LAPolicy.DeviceOwnerAuthenticationWithBiometrics, 
		localizedReason: "Access requires authentication", 
			reply: {(success, error) in

            if error != nil {

                switch error!.code {

                    case LAError.SystemCancel.rawValue:
                        self.notifyUser("Session cancelled", 
				err: error?.localizedDescription)

                    case LAError.UserCancel.rawValue:
                    self.notifyUser("Please try again", 
			      err: error?.localizedDescription)

                    case LAError.UserFallback.rawValue:
                        self.notifyUser("Authentication", 
				err: "Password option selected")
                        // Custom code to obtain password here

                    default:
                        self.notifyUser("Authentication failed", 
				err: error?.localizedDescription)
                }

            } else {
                self.notifyUser("Authentication Successful", 
			err: "You now have full access")
            }

        })

    } else {
        // Device cannot use TouchID
.
.
.

    }
}

The code added to the method initiates the authentication process and displays a message confirming a successful authentication. In the event of an authentication failure, a message is displayed to the user indicating the reason for the failure. Selection of the password option simply confirms that the option was selected. The actual action taken in this situation will be application specific but will likely involve prompting for a password and verifying it against a database of valid passwords.

Testing the Application

Compile and run the application on a physical iOS device (TouchID is not available on the simulator environment) and tap on the Test TouchID button. If the device supports TouchID and has been enabled and configured by the user, the touch request panel will appear as demonstrated in Figure 53-2:


Ios 8 touchid panel.png

Figure 53-2


Authenticate with a registered fingerprint and wait for the confirmation of successful authentication to appear. Experiment with a variety of failure scenarios to verify that the error handling code covers all events (such as tapping the Cancel button or attempting to authenticate with a non-registered fingerprint).

Summary

Introduced with iOS 7 and the iPhone 5s device, TouchID has been provided to iOS users as a way to gain access to devices and to make Apple related purchases. With the introduction of iOS 8, fingerprint authentication using the TouchID system is now available to application developers. This chapter has outlined the steps involved in using the Local Authentication Framework to implement biometric authentication using the TouchID system.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
An iOS 8 Swift Gesture Recognition TutorialAn Overview of iOS 8 Collection View and Flow Layout