Swift(Xcode):如何获取系统访问码拦截应用控制器?
Hey there! I’ve built similar functionality before, so let’s break down exactly how to make this work in your app. The core goal is twofold: shut down all custom access code creation flows and replace them with Apple’s native LocalAuthentication framework to leverage the system’s passcode/TouchID/FaceID.
Step 1: Intercept & Disable Custom Access Code Entries
First, you need to cut off every path that lets users create a custom access code:
- If you have a dedicated
CreateAccessCodeViewController, either remove all logic that presents/pushes this VC, or override itsviewDidLoadto immediately trigger system authentication instead of showing the custom UI. - For any buttons/table cells that previously launched custom access code setup, rewire their actions to call your system authentication method (we’ll write that next) and disable/hide the old custom options.
Example of updating a button action:
// Old code that opened custom access code VC // @IBAction func createCustomAccessCodeTapped(_ sender: UIButton) { // present(CreateAccessCodeVC(), animated: true) // } // New code that triggers system authentication @IBAction func verifyWithSystemPasscodeTapped(_ sender: UIButton) { authenticateWithSystemPasscode() }
If you have a settings screen with a "Create Access Code" option, modify it to reflect the system-based flow:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "AccessCodeCell", for: indexPath) if indexPath.row == 0 { // Old custom access code cell cell.textLabel?.text = "System Passcode Verification" cell.detailTextLabel?.text = "Uses your device's built-in passcode" cell.isUserInteractionEnabled = false // Disable tapping to old flow } return cell }
Step 2: Implement System Authentication with LocalAuthentication
Apple’s LocalAuthentication framework handles all native passcode/TouchID/FaceID validation automatically. It will fall back to the system passcode if biometrics aren’t available or the user chooses to use their passcode instead.
First, import the framework:
import LocalAuthentication
Then write a reusable authentication function:
func authenticateWithSystemPasscode() { let context = LAContext() var authError: NSError? // Check if the device supports system-level authentication guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &authError) else { // Device doesn't have a passcode/biometrics set up showSetupPasscodePrompt() return } // Trigger the system authentication prompt let reason = "Verify your device passcode to continue" context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { [weak self] success, error in // Always run UI updates on the main thread DispatchQueue.main.async { guard let self = self else { return } if success { // Authentication passed — proceed with your app's logic print("System authentication successful!") self.navigateToMainApp() // Example: Unlock main content } else { // Handle authentication failure if let error = error as? LAError { switch error.code { case .userCancel: print("User canceled authentication") case .userFallback: print("User chose to enter passcode") default: print("Authentication failed: \(error.localizedDescription)") } } } } } }
Step 3: Handle Cases Where No System Passcode Is Set
If the user hasn’t set up a device passcode or biometrics, guide them to enable it in system settings:
func showSetupPasscodePrompt() { let alert = UIAlertController( title: "No Device Passcode Found", message: "Please set up a passcode in your device settings to use this feature.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in if let settingsURL = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.open(settingsURL) } }) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) present(alert, animated: true) }
Important Notes
- Info.plist Requirements: If your app supports FaceID, add the
NSFaceIDUsageDescriptionkey to your Info.plist with a clear reason (e.g., "Use Face ID to verify your identity and access the app"). Without this, your app will crash when attempting FaceID authentication. - Clean Up Old Code: Remove any logic that stored custom access codes (e.g., Keychain entries, UserDefaults) to avoid conflicts or unused code.
- Test Edge Cases: Verify behavior on devices with TouchID, FaceID, only passcode, and no authentication set up to ensure full coverage.
内容的提问来源于stack exchange,提问作者Bartłomiej Janczak

