iOS应用二次面容认证崩溃:提示“Window was already deactivated”求助
解决iOS第二次面容认证崩溃(报错“Window was already deactivated”)
问题分析
该错误源于生物识别弹窗关联的UI窗口在首次认证后未正确释放或重置,二次调用时窗口处于已失效状态,导致应用崩溃。
可行解决方案
- 放弃单例服务实例:避免使用
BiometricAuthenticationService.Default单例,每次认证都创建新的服务实例(或通过依赖注入获取全新实例),确保每次认证的窗口资源独立。 - 强制资源清理:如果服务实现了
IDisposable接口,在认证完成后(无论成功失败)手动释放资源,避免窗口对象残留。 - 关联活跃UI上下文:在iOS平台的生物识别实现中,确保每次认证都绑定当前活跃的
UIWindow,而非复用旧窗口。 - 检查调用时机:避免在UI状态不稳定(如页面跳转、弹窗未关闭)时触发认证,确保调用时当前ViewController处于活跃状态。
修改后的代码示例
1. 服务实例化与资源清理
// 避免使用Default单例,每次创建新实例或从DI获取 var biometricService = new BiometricAuthenticationService(); try { var result = await biometricService.AuthenticateAsync( new AuthenticationRequest() { Title = $"{AppResources.Pleaseauthenticateforfaceid}", NegativeText = $"{AppResources.Cancelauthentication}" }, CancellationToken.None ); // 处理认证结果 if (result == AuthenticationResult.Success) { // 执行后续逻辑 } } finally { // 释放服务资源(若实现IDisposable) if (biometricService is IDisposable disposableService) { disposableService.Dispose(); } }
2. iOS平台特定窗口处理
在iOS项目的BiometricAuthenticationService实现中,确保绑定当前活跃窗口:
public async Task<AuthenticationResult> AuthenticateAsync(AuthenticationRequest request, CancellationToken cancellationToken) { var context = new LAContext(); NSError authError; // 检查生物识别可用性 if (!context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out authError)) { return AuthenticationResult.Failed; } // 获取当前活跃的UI窗口 var activeWindow = UIApplication.SharedApplication.Windows .FirstOrDefault(w => w.IsKeyWindow && !w.IsHidden); if (activeWindow != null) { activeWindow.MakeKeyAndVisible(); } // 执行面容认证 var authSuccess = await context.EvaluatePolicyAsync( LAPolicy.DeviceOwnerAuthenticationWithBiometrics, request.Title ); return authSuccess ? AuthenticationResult.Success : AuthenticationResult.Failed; }
额外注意事项
- 若使用MAUI/Xamarin框架,确保在调用认证前,当前页面处于
Appearing状态,而非Disappearing或Disposed状态。 - 检查第三方生物识别库(若使用)的版本,确认是否存在已知的窗口复用Bug,必要时升级到最新版本。
内容的提问来源于stack exchange,提问作者Vrushabh Konde
相关产品推荐
相关产品推荐

