Biometric authentication
Face ID and Touch ID with SwiftUI
Biometric authentication
Face ID and Touch ID with SwiftUI
0
0
Checkbox to mark video as read
Mark as read

Security and privacy are critical aspects of mobile applications. Apple’s LocalAuthentication framework enables developers to integrate biometric authentication like Face ID and Touch ID, along with device passcode authentication, to enhance security within their apps. In this article, we’ll explore how to use LocalAuthentication in SwiftUI to authenticate users with biometrics and device passcodes.

Setting Up LocalAuthentication

Before start using LocalAuthentication we need to add a new key to our info.plist file: NSFaceIDUsageDescription. This is just a string that should describe the use we are going to give it in our app:


Then we are ready to use the LocalAuthentication framework in our SwiftUI view. In order to do this we need to import the framework on each view that we are going to use it.

import SwiftUI
import LocalAuthentication

Authentication Check

In LocalAuthentication, we use an instance of LAContext to manage authentication. This context checks for the availability of biometric capabilities on the device and initiates the authentication request. Here’s a sample structure for setting up basic authentication:

struct ContentView: View {
    @State private var isAuthenticated = false
    @State private var authenticationError: String?

    var body: some View {
        VStack {
            if isAuthenticated {
                Text("Welcome! You are authenticated.")
            } else {
                Button("Authenticate") {
                    Task {
                        await authenticateUser()
                    }
                }
                .padding()

                if let error = authenticationError {
                    Text(error)
                        .foregroundColor(.red)
                        .padding()
                }
            }
        }
    }

    func authenticateUser() async {
        let context = LAContext()
        var error: NSError?

        if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
            let reason = "Authenticate to access your secure data"

            do {
                isAuthenticated = try await context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason)
            }
            catch let error {
                self.authenticationError = error.localizedDescription
            }
        } else {
            authenticationError = "Biometric authentication is not available"
        }
    }
}

The first time we try to trigger the authentication check, the system will show the premission dialog automatically to the user.


Test on Simulator

You can test Fade ID on a simulator activating the option Features->Face ID->Enrolled, then when authentication is checked, the simulator will wait for you to trigger Matching face or Non-matching face option on the same menu:


Handling Authentication Policies

The LocalAuthentication framework provides different policies for authentication, such as:

  • deviceOwnerAuthenticationWithBiometrics: Uses biometric authentication (Face ID or Touch ID).
  • deviceOwnerAuthentication: Uses biometric authentication or falls back to device passcode if biometrics are unavailable.

If you want to allow both biometrics and passcode, use deviceOwnerAuthentication instead:

context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error)

This way, if biometrics fail or are not available, the system will prompt the user to enter their device passcode.

Handling Errors

When an authentication attempt fails, the LAContext provides an error object with details about why the authentication failed. Here’s a list of common errors:

  • LAError.authenticationFailed: The user failed to authenticate successfully.
  • LAError.userCancel: The user canceled the authentication.
  • LAError.userFallback: The user chose to enter a password instead.
  • LAError.biometryNotAvailable: The device does not support Face ID or Touch ID.
  • LAError.biometryNotEnrolled: The user has not enrolled in Face ID or Touch ID.

You can use these errors to provide specific feedback to the user. For example:

if let error = authenticationError {
    switch error.code {
    case .authenticationFailed:
        authenticationError = "Authentication failed. Please try again."
    case .userCancel:
        authenticationError = "Authentication canceled."
    case .biometryNotAvailable:
        authenticationError = "Biometric authentication not available on this device."
    default:
        authenticationError = error.localizedDescription
    }
}

0 Comments

Join the community to comment

Be the first to comment

Accept Cookies

We use cookies to collect and analyze information on site performance and usage, in order to provide you with better service.

Check our Privacy Policy