问题
I am working on the app that uses touch ID for login. It should ask for touch ID only at first launch (i.e. I am not asking for touch ID auth when app enters foreground from background). Here is what I do to show touchID:
AppDelegate.swift:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let loginViewController = storyboard.instantiateViewControllerWithIdentifier("login") as! LoginViewController
rootViewController = loginViewController
let navigationController = UINavigationController(rootViewController: rootViewController)
window!.rootViewController = navigationController
}
Then in viewDidAppear() of LoginViewController I ask for touch like so:
LoginViewController.swift:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let context = LAContext()
if context.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, error: nil) {
context.evaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics,
localizedReason: NSLocalizedString("Login To Your Account", comment: ""),
reply: { [weak self] (success, error) in
dispatch_async(dispatch_get_main_queue(), {
if success {
self?.loginUser()
} else if error!.code != LAError.UserCancel.rawValue {
self?.focusOnPassword()
} else
})
})
} else {
loginUser()
}
}
The problem is some of testers report that they are not getting TouchID alert at all. It just show shows password screen right away. I added error logging and the error I receive is:
Domain: com.apple.LocalAuthentication Code: -1004 NSLocalizedDescription: User interaction is required.
And I can't reproduce it at all. Touch ID works fine on all of my test devices, so I can't get the reason of that. Bugs were received from iPhone 6, 6S, 6s Plus, iOS 9.3.1-9.3.3.
回答1:
This happens on iOS 10 even when your application is in the foreground. As mentioned by Android Noob in one of the comments.
I did further investigation and found that it happens when you have multiple apps with the same product/executable name.
In my scenario I had 3 versions of the same app(code) with different bundle identifiers and display names. Only one of them, the last one that was installed, worked with Touch ID. The others returned the 'User interaction required error'.
Regarding the OP's issue. It is likely that the testers have another app with the same executable name installed on their devices. This could be another version of your app or another developer's app.
To circumvent the issue, change your executable or product name: Targets -> [Your Target Name] -> Build Settings -> Packaging -> Product Name
My tests and findings:
Given 3 apps with same code and product name but different bundle ids and display names: CI, UAT and Prod.
Install CI:
- CI - Touch ID works
Install UAT:
- UAT - Touch ID works
- CI - Touch ID fails with 'User interaction required' error
Install Prod:
- Prod - Touch ID works
- UAT - Touch ID fails with 'User interaction required' error
- CI - Touch ID fails with 'User interaction required' error
Uninstall Prod:
- UAT - Touch ID works (but seems to have lost context because it does not display the app name)
- CI - Touch ID works (but seems to have lost context because it does not display the app name)
Uninstall UAT and CI, reinstall CI:
- CI - Touch ID works
Change UAT product name and install UAT:
- CI - Touch ID works
- UAT - Touch ID works
回答2:
Check out this SO post regarding the same issue.
The answer says that
Basically this error happens when your app is woken up from background and somewhere on your code you are asking for Touch ID (my case is the local authentication type, I haven't tested with the keychain type). There's no way the user can interact with Touch ID prompted while the app is running on background, hence the error message.
If this same case is happening with you also, you need to add some logic in following AppDelegate
method:
- (void)applicationWillEnterForeground:(UIApplication *)application
来源:https://stackoverflow.com/questions/38854052/touchid-error-code-1004-nslocalizeddescription-user-interaction-is-required