Integrate Touch ID and Face ID for Biometric Security in iOS

In this tutorial, I will guide you through the process of integrating biometric authentication into your iOS application using Swift and the LocalAuthentication framework. By the end of this tutorial, you will have a functional app capable of authenticating users using the built-in biometric sensors of their devices.

Step 1: Import Local Authentication Framework

First, you need to import the LocalAuthentication framework, which provides the necessary tools to work with biometric authentication features like Touch ID and Face ID. Add the following line at the top of your Swift file:

import LocalAuthentication

Step 2: Add Privacy Description for Face ID

To ensure your app complies with Apple’s privacy guidelines, you must provide a usage description for Face ID. Open your project’s Info.plist file and add a new row with the key Privacy - Face ID Usage Description. Set its value to a brief explanation of why your app requires the user’s face ID, for example:

<key>NSFaceIDUsageDescription</key>
<string>We use Face ID to secure your account.</string>

To write a better privacy description, you can watch Apple’s official guideline video about how to write clear purpose strings.

Step 3: Determine Availability of Biometric Sensors

Next, create an instance of LAContext, which is used to interact with biometric sensors. Then, check if the device can evaluate a biometric policy, which indicates whether biometric authentication is possible:

let context = LAContext()
var error: NSError?

if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
    // Biometric authentication is possible
} else {
    // Biometric authentication is not possible
}

Step 4: Use evaluatePolicy() Function

If biometric authentication is possible, use the evaluatePolicy() function to initiate the authentication process. Provide a localized reason that explains why you need the user’s authentication:

let reason = "Please authenticate using Touch ID/Face ID."

context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
    // Handle authentication result
}

Step 5: Handle Local Authentication Error Messages

Inside the completion handler of evaluatePolicy(), you should handle both successful authentication and any potential errors:

if success {
    // Successful authentication
} else {
    // Handle error
    switch authenticationError {
    case LAError.authenticationFailed?:
        // User failed to authenticate
    default:
        // Other errors
    }
}

Complete Code Example

Here’s the complete code example incorporating all the steps:

import UIKit
import LocalAuthentication

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        view.backgroundColor = .white
        
        let authenticateButton = UIButton(type: .system)
        authenticateButton.setTitle("Authenticate", for: .normal)
        authenticateButton.frame = CGRect(x:   100, y:   100, width:   200, height:   40)
        authenticateButton.addTarget(self, action: #selector(performBiometricAuthentication), for: .touchUpInside)
        
        // Add the button to the view
        self.view.addSubview(authenticateButton)
    }
    
    @objc func performBiometricAuthentication() {
        let context = LAContext()
        var error: NSError?
        
        if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
            let reason = "Please authenticate using Touch ID/Face ID."
            
            context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { [weak self] success, authenticationError in
                DispatchQueue.main.async {
                    if success {
                        self?.showSuccessAlert()
                    } else {
                        self?.showFailureAlert(error: authenticationError as? LAError)
                    }
                }
            }
        } else {
            showFailureAlert(error: LAError(.authenticationFailed))
        }
    }
    
    private func showSuccessAlert() {
        let alert = UIAlertController(title: "Success", message: "Touch ID/Face ID authentication was successful.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
    
    private func showFailureAlert(error: LAError?) {
        let message = error?.localizedDescription ?? "Failed to authenticate."
        let alert = UIAlertController(title: "Failure", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}

Here’s a brief overview of the complete code example:

  • ViewController Class: A custom ViewController class is defined which inherits from UIViewController. This class manages the main view of the application.
  • viewDidLoad Method: Within the viewDidLoad lifecycle method, the UI is set up by calling the setupUI function.
  • setupUI Function: This function initializes the UI components, specifically creating an “Authenticate” button that triggers the biometric authentication process when tapped.
  • performBiometricAuthentication Method: This method is the core of the biometric authentication process. It creates an instance of LAContext to interact with the biometric hardware. It checks if biometric authentication is possible using canEvaluatePolicy(_:error:) and, if so, prompts the user to authenticate using either Touch ID or Face ID via evaluatePolicy(_:localizedReason:reply:).
  • Completion Handler: After the user attempts to authenticate, the completion handler is executed. If authentication is successful, a success alert is displayed; otherwise, a failure alert shows the error message.
  • showSuccessAlert and showFailureAlert Functions: These functions display alerts to inform the user of the authentication outcome. They use UIAlertController to present an alert dialog with a title and message.

This code serves as a basic template for integrating biometric authentication into an iOS app, ensuring that sensitive operations require the user’s identity verification through Touch ID or Face ID.

Conclusion

I hope this tutorial was helpful to you. You now know how to Integrate Touch ID and Face ID for your iOS apps.

To learn more about Swift and to find other code examples, check the following page: Swift Code Examples.

Keep coding, and happy learning!