4

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.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
A. Buksha
  • 830
  • 9
  • 14

2 Answers2

18

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
Stephanus Mostert
  • 909
  • 10
  • 11
  • 1
    Great findings... Thank you. This helped me a lot. – nacho4d Oct 12 '17 at 09:43
  • 1
    Been trying to debug this for a week and thought I was crazy. This fixed it! Thank you. – Brandon Nov 06 '19 at 04:10
  • 1
    Renaming `PRODUCT_NAME` to different values for different versions of the product fixed the problem for me on iOS 13, Xcode 11.3. Note: remember to update TEST_HOST to reference correct product in your unit tests target. – Dmitry Bespalov Dec 19 '19 at 17:06
  • Not agree with this answer. I have an app that is doing and there is no other app like that. How the executable name is related to this issue. It seems just an assumption. – Alok C May 14 '20 at 16:34
  • Thank you SO much! @Alix: this fix will do wonder only after other possible causes are fixed (like presenting the UI when the state of the application is not active yet). – Mick F Sep 17 '20 at 09:15
1

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
Community
  • 1
  • 1
D4ttatraya
  • 3,344
  • 1
  • 28
  • 50
  • I saw that question before. But I don't perform any touchID-relate code in AppDelegate's methods standing for background mode. Only time I ask for touchID is when app initially launched, and this time 'applicationWillEnterForeground' won't get called anyway. – A. Buksha Aug 10 '16 at 06:23
  • @A.Buksha That post says "when your app is woken up from background and somewhere on your code you are asking for Touch ID", i.e. your app may also going background then foreground before user provides biometrics. – D4ttatraya Aug 10 '16 at 07:15
  • I get the same error. My app is definitely in the foreground at the point where it asks for touch id. – onnoweb Oct 28 '16 at 17:16
  • 5
    I'm getting the same issue as well on iOS 10.x and seeing that "User interaction is required" message. The only time I can reliably reproduce is to install the Enterprise and App Store versions of the app (different bundle ids, same code base) side by side. – Android Noob Dec 05 '16 at 16:13