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
security
swift
swiftui
ios
Natascha Fadeeva
iOS dev & creator of this site
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.
Preparing for a technical iOS
job interview - updated for iOS
18
Check out my book on
preparing for a technical iOS
job interview with over 200
questions & answers. Test your
knowledge on iOS topics such
as Swift, SwiftUI, Architecture &
Design Patterns, Combine,
HTTP Networking,
Authentication, SwiftData &
Core Data, Concurrency with
async/await, Security,
Automated Testing, Machine
Learning and more.
LEARN MORE
Setting up LocalAuthentication
framework
As a first step, we need to add
the NSFaceIDUsageDescription
key in the app’s [Link] 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
[Link](.devi
ceOwnerAuthentication, error:
&error)
}
The
value deviceOwnerAuthenticati
on 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.
[Link](.deviceO
wnerAuthentication,
localizedReason: reason)
{ (success, error) in
[Link] {
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 = false
var body: some View {
VStack {
if isAuthenticated {
Text("Welcome to
your secure data!")
} else {
Button("Authenticate") {
authenticate()
}
}
}
}
private func authenticate() {
[Link]
{ success, error in
if 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 [Link] {
case .userCancel:
// Handle user
cancellation
case .authenticationFailed:
// Handle failed
authentication
default:
// 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.