iOS 8 Touch ID错误"需要用户交互."

Ste*_*ley 11 objective-c ios touch-id

我一直在努力将Touch ID支持集成到我正在处理的应用程序中.然而,它表现得非常不一致.我看到的一个常见问题是在新的应用程序启动它按预期工作,但随后在应用程序的背景,并将其带到前台我收到一个错误

evaluatePolicy:localizedReason:reply:
Run Code Online (Sandbox Code Playgroud)

它甚至没有多大意义(我从未看到过触摸警报)

Error Domain=com.apple.LocalAuthentication Code=-1004 "User interaction is required." UserInfo=0x171470a00 {NSLocalizedDescription=User interaction is required.}
Run Code Online (Sandbox Code Playgroud)

我已经尝试在应用程序已经运行时显示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];
                    });
                }
            });
        }];
    }
}
Run Code Online (Sandbox Code Playgroud)

HeT*_*Tzi 7

通常在输入背景之前按下PIN视图控制器:

- (void)applicationDidEnterBackground:(UIApplication *)application
Run Code Online (Sandbox Code Playgroud)

因此,在浏览应用预览图像时,应用的内部信息不会出现(主页按钮双击).我猜你正在做类似的事情.

问题是LocalAuthentication的新API要求调用viewController可见.这就是为什么在辞职到背景之前不应该调用"showTouchID"函数的原因.而是在输入前景时调用"showTouchID"函数:

- (void)applicationWillEnterForeground:(UIApplication *)application
Run Code Online (Sandbox Code Playgroud)

它应该工作.首次启动应用时,不要忘记调用它(在这种情况下,不会调用..willEnterForeground).


Luc*_*ien 6

@hetzi 的回答对我很有帮助,但我还有更多要补充的。

基本上,当您的应用程序从后台唤醒并且在您要求 Touch ID 的代码中的某处时,会发生此错误(我的情况是本地身份验证类型,我尚未使用钥匙串类型进行测试)。当应用程序在后台运行时,用户无法与提示的 Touch ID 进行交互,因此会出现错误消息。

需要用户交互。

我的应用程序来自后台的原因是:推送通知Apple Watch

我的修复是在viewDidLoad我最初的 VC的方法上做这样的事情:

if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
    [self promptForTouchID];
}
Run Code Online (Sandbox Code Playgroud)

我使用过!=因为,当您的应用程序首次启动时,它处于UIApplicationStateInactive状态。并且该状态不会生成 Touch ID 错误,因为会出现提示。

我还调用[self promptForTouchID]了 的通知UIApplicationWillEnterForegroundNotification,但由于您知道该应用程序将进入前台,因此无需在此处检查。