Biometric Authentication
Biometric Authentication
Face ID and Touch ID provide convenient and secure authentication. Proper implementation ensures fallback mechanisms and handles various edge cases.
Advanced Biometric Implementation:
import LocalAuthentication
class BiometricAuthManager {
private let context = LAContext()
enum BiometricType {
case none
case touchID
case faceID
}
var biometricType: BiometricType {
var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
error: &error) else {
return .none
}
switch context.biometryType {
case .faceID:
return .faceID
case .touchID:
return .touchID
default:
return .none
}
}
func authenticateWithBiometrics(reason: String,
fallbackTitle: String? = nil,
completion: @escaping (Bool, Error?) -> Void) {
// Configure context
context.localizedFallbackTitle = fallbackTitle
context.localizedCancelTitle = "Cancel"
// Set timeout for Touch ID
if #available(iOS 10.0, *) {
context.touchIDAuthenticationAllowableReuseDuration = 30.0
}
// Evaluate policy
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
localizedReason: reason) { success, error in
DispatchQueue.main.async {
if success {
completion(true, nil)
} else {
// Handle specific error cases
if let laError = error as? LAError {
switch laError.code {
case .userFallback:
// User tapped fallback button
self.authenticateWithPasscode(completion: completion)
case .userCancel:
// User cancelled
completion(false, error)
case .biometryLockout:
// Too many failed attempts
self.authenticateWithPasscode(completion: completion)
default:
completion(false, error)
}
} else {
completion(false, error)
}
}
}
}
}
private func authenticateWithPasscode(completion: @escaping (Bool, Error?) -> Void) {
let context = LAContext()
context.evaluatePolicy(.deviceOwnerAuthentication,
localizedReason: "Enter your passcode") { success, error in
DispatchQueue.main.async {
completion(success, error)
}
}
}
}