Implementing Face ID authentication in SwiftUI
Learn how to add biometric authentication with passcode fallback to secure your app.
10 Feb 2025 · 5 min read
Apple's Local Authentication framework enables us to implement biometric authentication, such as Face ID and Touch ID, allowing users to securely access sensitive app data. In this article, we’ll explore how to integrate Face ID using Swift and SwiftUI.
Let's jump in.

Setting up LocalAuthentication framework
As a first step, we need to add the NSFaceIDUsageDescription key in the app’s Info.plist file. This key is mandatory, and without it, the system will prevent Face ID from being used. The value should clearly describe why Face ID access is required.
After that, we can import and use the LocalAuthentication framework, which provides access to biometric authentication functions and error handling.
import LocalAuthentication
Checking if biometry is available
Before authenticating the user, an essential step is to check if biometrics are available on the device:
func isAuthenticationAvailable() -> Bool {let context = LAContext()var error: NSError?return context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error)}
The value deviceOwnerAuthentication includes passcode authentication if biometry is not available.
Starting the authentication process
Once we know authentication is available, we can initiate the process by calling the evaluatePolicy method, which prompts the user to authenticate.
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { (success, error) inDispatchQueue.main.async {if success {// Authentication succeeded.} else {// Handle the error (e.g., user canceled, authentication failed).}}}
Integrating with SwiftUI views
To integrate biometric authentication into a SwiftUI app, we can call the authentication function within a SwiftUI view:
struct ContentView: View {@State private var isAuthenticated = falsevar body: some View {VStack {if isAuthenticated {Text("Welcome to your secure data!")} else {Button("Authenticate") {authenticate()}}}}private func authenticate() {authService.authenticate { success, error inif success {isAuthenticated = true} else {// Handle error}}}}
Handling errors
Authentication may fail due to various reasons, such as the user canceling the prompt or the system being unable to recognize the face. We can handle these errors by evaluating the error as follows:
if let error = error as? LAError {switch error.code {case .userCancel:// Handle user cancellationcase .authenticationFailed:// Handle failed authenticationdefault:// Handle other errors}}
Testing the authentication on a simulator
To test the authentication flow, we don't necessarily need a device. We can simulate success and failure directly in simulator by choosing Features -> Face ID in the menu and then selecting the behaviour we want to simulate.
Good to know
The iOS app never gains any access to the actual authentication data like fingerprint images. It is stored by an isolated security processor called Secure Enclave, which manages this data out of reach even for the operating system.
So when we ask the Local Authentication framework to evaluate, the framework asks the Secure Enclave to carry out the operation. Afterwards, we only receive a Boolean result and an optional error indicating success or failure.



Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips



