我一直致力于将Touch ID支持集成到我正在处理的应用中。然而,它表现得非常不一致。我看到的一个常见问题是在一个新的应用程序启动它按预期工作,但随后在应用程序的背景,并将它带到前台我收到一个错误从
evaluatePolicy:localizedReason:reply:
它甚至没有多大意义(我从未看到过触摸警报)
Error Domain=com.apple.LocalAuthentication Code=-1004 "User interaction is required." UserInfo=0x171470a00 {NSLocalizedDescription=User interaction is required.}
我已经尝试在应用已经运行时显示touchid警报,当它刚刚被预先考虑时,似乎并不重要。在最初的应用程序启动后,它每次都会被破坏。
其他人遇到这个?
供参考,以下是我正在使用的代码:
if (_useTouchId && [LAContext class]) {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
_didPresentTouchId = YES;
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"Use your Touch ID to open *****" reply:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^ {
if (success) {
_isClosing = YES;
[self hide];
if (_successBlock) {
_successBlock();
}
}
else if (error && error.code != -2 && error.code != -3 && error.code != -1004) {
[[[UIAlertView alloc] initWithTitle:@"Error" message:@"Authentication failed, please enter your Pin" delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil] show];
}
else {
if (error) {
DDLogError(@"TouchID error: %@", error.description);
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .6 * NSEC_PER_SEC), dispatch_get_main_queue(), ^ {
[self keyboardButtonTouched];
});
}
});
}];
}
}
答案 0 :(得分:7)
通常在进入后台之前推送PIN视图控制器:
- (void)applicationDidEnterBackground:(UIApplication *)application
因此,在浏览应用预览图像时,应用的内部信息不会出现(主页按钮双击)。我猜你正在做类似的事情。
问题是LocalAuthentication的新API要求调用viewController可见。 这就是为什么在辞职到背景之前不应该调用“showTouchID”函数的原因。而是在输入前景时调用“showTouchID”函数:
- (void)applicationWillEnterForeground:(UIApplication *)application
它应该工作。 首次启动应用时,不要忘记调用它(在这种情况下,不会调用..willEnterForeground)。
答案 1 :(得分:4)
@hetzi的答案真的对我很有帮助,但我还有更多要补充的内容。
基本上,当您的应用程序从后台唤醒并且代码中的某个地方需要Touch ID时,会发生此错误(我的情况是本地身份验证类型,我没有使用keychain类型进行测试)。当应用程序在后台运行时,用户无法与提示的Touch ID进行交互,因此出现错误消息。
需要用户互动。
我的应用来自后台的原因是:推送通知或 Apple Watch 。
我的修复是在我最初的VC的viewDidLoad
方法上做了类似的事情:
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
[self promptForTouchID];
}
我使用了!=
因为,当您的应用首次启动时,它处于UIApplicationStateInactive
状态。并且该状态不会生成Touch ID错误,因为会出现提示。
我也会在[self promptForTouchID]
的通知上致电UIApplicationWillEnterForegroundNotification
,但由于您知道应用会进入前台,因此无需在此处查看。