Biometric Authentication
Authenticate users with Face ID and Touch ID.
Biometric Authentication is a free Swift Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Biometrics With LocalAuthentication
Face ID and Touch ID let users prove who they are without typing a password. The LocalAuthentication framework exposes this through LAContext, which evaluates an authentication policy and tells you whether the user passed.
import LocalAuthentication
let context = LAContext()
// One LAContext object drives a single auth attemptChecking Availability First
Always call canEvaluatePolicy before prompting. The device may lack biometric hardware, the user may not be enrolled, or biometrics may be locked out. This returns a Bool and an error explaining why if it fails.
import LocalAuthentication
func canUseBiometrics() -> Bool {
let context = LAContext()
var error: NSError?
return context.canEvaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
error: &error)
}The Two Policies
.deviceOwnerAuthenticationWithBiometrics requires Face ID or Touch ID with no passcode fallback. .deviceOwnerAuthentication tries biometrics but falls back to the device passcode. Choose based on whether a passcode is acceptable.
import LocalAuthentication
// Biometrics only (no passcode fallback):
let strict = LAPolicy.deviceOwnerAuthenticationWithBiometrics
// Biometrics with passcode fallback:
let lenient = LAPolicy.deviceOwnerAuthentication
_ = (strict, lenient)Evaluating the Policy
evaluatePolicy performs the authentication, showing the system biometric sheet. The localizedReason string explains to the user why you are asking. The async form returns a Bool or throws.
import LocalAuthentication
func authenticate() async -> Bool {
let context = LAContext()
do {
return try await context.evaluatePolicy(
.deviceOwnerAuthentication,
localizedReason:
String(localized: "Unlock your account"))
} catch {
return false
}
}Detecting Biometry Type
After canEvaluatePolicy, context.biometryType tells you whether the device uses .faceID, .touchID, .opticID, or .none. Use it to show the correct icon and wording in your own UI.
import LocalAuthentication
func biometryLabel() -> String {
let context = LAContext()
_ = context.canEvaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics, error: nil)
switch context.biometryType {
case .faceID: return "Face ID"
case .touchID: return "Touch ID"
case .opticID: return "Optic ID"
default: return "Passcode"
}
}Handling Errors
Failures arrive as LAError codes: .userCancel, .userFallback (chose passcode), .biometryLockout after too many failures, and .biometryNotEnrolled. Branch on these to give helpful guidance instead of a generic failure.
import LocalAuthentication
func describe(_ error: Error) -> String {
guard let la = error as? LAError else { return "failed" }
switch la.code {
case .userCancel: return "cancelled"
case .biometryLockout: return "locked out"
case .biometryNotEnrolled: return "not set up"
default: return "failed"
}
}The Face ID Usage String
To use Face ID you must add NSFaceIDUsageDescription to Info.plist explaining why. Omitting it crashes the app the first time you evaluate a Face ID policy. Touch ID needs no such key.
// Info.plist:
// NSFaceIDUsageDescription =
// "We use Face ID to unlock your saved passwords."
let required = "NSFaceIDUsageDescription is mandatory"
_ = requiredCustomizing the Sheet
You can tailor the prompt: localizedCancelTitle renames the cancel button, and localizedFallbackTitle sets (or hides, when empty) the fallback option. Setting an empty fallback title suppresses the passcode option.
import LocalAuthentication
func configured() -> LAContext {
let context = LAContext()
context.localizedCancelTitle =
String(localized: "Not now")
context.localizedFallbackTitle = "" // hide fallback
return context
}Reusing a Successful Authentication
By default each evaluatePolicy reprompts. Setting touchIDAuthenticationAllowableReuseDuration lets a recent successful unlock satisfy a later check without a new prompt — useful for grouped sensitive actions within a short window.
import LocalAuthentication
func reusableContext() -> LAContext {
let context = LAContext()
context.touchIDAuthenticationAllowableReuseDuration = 30
return context
}Biometrics vs Keychain Gating
LAContext verifies the user but does not itself protect data. For true security, pair it with Keychain SecAccessControl so the secret is cryptographically unreadable until authentication succeeds — not merely hidden behind a checked Bool.
import LocalAuthentication
// A bare evaluatePolicy == true is bypassable if your
// logic is tampered with. Prefer SecAccessControl so
// the data is encrypted until auth succeeds.
let pairing = "combine LAContext with Keychain ACL"
_ = pairingA Complete Unlock Flow
Combine availability check, type-aware messaging, evaluation, and error handling into one robust routine your UI can call.
import LocalAuthentication
func unlock() async -> Bool {
let context = LAContext()
var err: NSError?
guard context.canEvaluatePolicy(
.deviceOwnerAuthentication, error: &err) else {
return false
}
return (try? await context.evaluatePolicy(
.deviceOwnerAuthentication,
localizedReason:
String(localized: "Access your vault"))) ?? false
}Quick Check
Recall the difference between the two main policies.
Recap
You learned biometric authentication:
- Use
LAContextand callcanEvaluatePolicybeforeevaluatePolicy. .deviceOwnerAuthenticationWithBiometricsis biometrics-only;.deviceOwnerAuthenticationadds passcode fallback.- Read
biometryTypefor correct wording; handleLAErrorcodes like.biometryLockout. - Add
NSFaceIDUsageDescription, and pair with KeychainSecAccessControlfor real protection.
Frequently asked questions
Is the “Biometric Authentication” lesson free?
Yes — the full text of “Biometric Authentication” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Biometric Authentication”?
Authenticate users with Face ID and Touch ID. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Biometric Authentication” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Storing Secrets in the Keychain
- Keychain Access Control
- Biometric Authentication
- Data Protection and Encryption