Appearance
Implement Biometric Authentication in the iOS App
Local Authentication Framework
Set the Face ID Usage Description
In any project that uses biometrics, include the NSFaceIDUsageDescription
key in your app’s Info.plist file. Otherwise, authorization requests may fail.
The value for this key is a string that the system presents to the user the first time your app attempts to use Face ID.
XML
<key>NSFaceIDUsageDescription</key>
<string>We use Face ID/Touch ID to enhance the security of your app and protect your personal information.</string>
Create and Configure a LAContext
You perform biometric authentication in your app using an LAContext instance, which brokers interaction between your app and the Secure Enclave.
swift
var context = LAContext()
context.localizedCancelTitle = "Enter Username/Password" // Optional, set a custom message for the Cancel button
Test Policy Availability
Before attempting to authenticate, test to make sure that you actually have the ability to do so by calling the canEvaluatePolicy(_:error:) method:
swift
var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
print(error?.localizedDescription ?? "Can't evaluate policy")
// Fall back to a asking for username and password.
// ...
return
}
LAPolicy definition:
.deviceOwnerAuthenticationWithBiometrics
: authenticated using a biometric method (Touch ID or Face ID)..deviceOwnerAuthentication
: authenticated by biometry or device passcode..deviceOwnerAuthenticationWithCompanion
(iOS18): authenticated by a companion device e.g. Watch, Mac, etc..deviceOwnerAuthenticationWithBiometricsOrCompanion
(iOS18): authenticated by biometry or a companion device e.g. Watch, Mac, etc.
Evaluate a Policy
When you’re ready to authenticate, call the evaluatePolicy(_:localizedReason:reply:) method, using the same policy you already tested:
swift
Task {
do {
try await context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "Log in to your account")
state = .loggedin
} catch let error {
print(error.localizedDescription)
// Fall back to a asking for username and password.
// ...
}
}
The localizedReason
is used by Touch ID or passcode authentication. The name of your app already appears before the reason you give, so you don’t need to include that in your message.
Accessing Keychain Items
swift
let access = SecAccessControlCreateWithFlags(nil, // Use the default allocator.
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
.userPresence,
nil) // Ignore any error.
The userPresence flag tells keychain services to request biometric authentication, or to fall back on the device passcode, whenever the item is later read from the keychain.
SecAccessControlCreateFlags definition:
devicePasscode
: access an item with a passcodebiometryAny
: access an item with Touch ID for any enrolled fingers, or Face IDbiometryCurrentSet
: access an item with Touch ID for currently enrolled fingers, or from Face ID with the currently enrolled user.userPresence
: access an item with either biometry or passcode.