Get `biometryType` of LAContext even if canEvaluatePolicy(_:error:) failed

Originator:mshibanami
Number:rdar://36064151 Date Originated:December 15 2017, 10:52 AM
Status:Closed Resolved:đź‘Ť
Product:iOS Product Version:11
Classification:Local Authentication Framework Reproducible:
 
`LAContext` has `biometryType` property. But the value is `none` if `canEvaluatePolicy(_:error:)` failed.


e.g. I want to show a message like this for a user:

"Oops, this app is locked out! If you want to use Touch ID for this App, then check the Setting app -> 'Touch ID and Passcord'."

But my app can't detect what kind of biometric auth the device supports at the moment due to the current specification. So I changed the above message like this:

"Oops, this app is locked out! If you want to use Touch ID/Face ID for this app, then check the Setting app -> 'Touch ID & Passcode' or 'Face ID & Passcode'."

It's boring and less readable.

I think, whether the method is succeeded or not is not related to know what kind of biometric auth a device supports.

So I believe it would be nice if LAContext has a new way to get biometryType even if canEvaluatePolicy(_:error:) failed.

Comments

I created a small library for this bug.

You can get the correct biometryType even on iOS11.0.x devices.

https://github.com/mshibanami/BiometryTypeBugWorkaround

By mshibanami at Jan. 9, 2018, 5:49 a.m. (reply...)

From Apple Developer Relations (January 5 2018, 12:14 AM)

Engineering has provided the following information regarding this issue:

No problem. As for the documentation - yes, it’s wrong and it’s still wrong in 11.2. It was fixed just recently and the fix is going to land in 11.3 SDK. The only requirement is that you call [LAContext canEvaluatePolicy] on that context. It can succeed or fail, but biometryType property should be set in any case.

As for the failing iPhone 8 running iOS 11.0.3 - I did further investigation into the history of the early iOS 11 releases and it’s really unfortunate, but there was a divergence between iOS trains for iPhone X and all other devices. The result of this split was that iOS 11.0.1 for iPhone X contains some fixes that didn’t make it to iOS 11.0.x for other devices, including several biometryType issues. So with iPhone X, you’ll see the correct biometryType behavior since 11.0.1, but with other devices you need to use at least 11.1.

BTW, when checking for biometryType availability, please check against iOS 11.0.1, because iOS 11.0 didn’t contain the property at all, so you’d end up crashing on devices that still run the initial 11.0 release. The annotation was fixed in 11.2 or 11.3.

Our apologies for all this confusion, we really had a bad luck adding this property.

By mshibanami at Jan. 5, 2018, 5:42 a.m. (reply...)

From Apple Developer Relations (January 4 2018, 12:09 AM)

Thanks, we are working on the new information you provided. We appreciate your help!

By mshibanami at Jan. 4, 2018, 5:40 a.m. (reply...)

From me (December 18 2017, 4:00 PM)

I'll check them tommorow at work.

Checked them:


  1. What’s your device, build and Xcode version?
  • iPhone:
    • iPhone 8 SpaceGray (iOS 11.0.3)
    • iPhone 8 Plus Silver (iOS 11.0.3)
  • Xcode: 9.2 (9C40b)
  1. What is the error returned from canEvaluatePolicy?
  • When locked: Error Domain=com.apple.LocalAuthentication Code=-8 "Biometry is locked out." UserInfo={NSLocalizedDescription=Biometry is locked out.}

  • When no fingerprint enrolled: Error Domain=com.apple.LocalAuthentication Code=-7 "No identities are enrolled." UserInfo={NSLocalizedDescription=No identities are enrolled.}

  1. After you reading the biometryType property from the same LAContext that was used to call canEvaluatePolicy on?

Yes, I executed this code:

`let context = LAContext() if !context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) { if #available(iOS 11.0, *) { print("biometryType.rawValue: \(context.biometryType.rawValue)") // Output "biometryType.rawValue: 0" unexpectedly } } `

  1. What does the biometryType property read then - is it LABiometryTypeNone (0)?

Yes. The rawValue was 0.


I tested the following devices and I noticed almost all iPhone/iPad devices's biometryType is set as you said even if canEvaluatePolicy() failed:

  • iPhone 6 (iOS 11.0.3)
  • iPhone 8 Gold (iOS 11.2)
  • iPhone 8 Silver (iOS 11.1)
  • iPhone X (iOS 11.1.2)
  • iPhone X (iOS 10.0.1)
  • iPad Pro (iOS 11.1.2)

But some devices (like the above iPhone 8) didn't work properly.

I wanted to try to upgrade the above iPhone8 to latest iOS, but I couldn't do it due to various reasons. So I'm not sure it would fix. Sorry...

And, sorry to bother you over and over again but, I want to know that the documentation ( https://developer.apple.com/documentation/localauthentication/lacontext/2867583-biometrytype ) is wrong or not.

By mshibanami at Jan. 4, 2018, 5:39 a.m. (reply...)

From me (December 17 2017, 10:59 AM)

Wow, I see. I got this problem with my company's iPhones. I'll check them tommorow at work.

By the way, you mean the following sentence in documentation (https://developer.apple.com/documentation/localauthentication/lacontext/2867583-biometrytype) will be fixed when iOS 11.2 was released?:

This property is only set when canEvaluatePolicy(_:error:) succeeds for a biometric policy. The default value is LABiometryNone.

By mshibanami at Jan. 4, 2018, 5:34 a.m. (reply...)

From Apple Developer Relations (December 16 2017, 3:30 AM)

The biometryType property used to have some issues back in iOS 11 Seed, but those should have been already resolved. You should be able to read the actual biometry type from this property after calling canEvaluatePolicy on the particular LAContext. It does not matter if the canEvaluate call is successful or not, the biometryType should be set correctly right after it.

Please try with the recent iOS SDK (e.g. 11.2). If it still does not work for you, please clarify: 1. What’s your device, build and Xcode version? 2. What is the error returned from canEvaluatePolicy? 3. After you reading the biometryType property from the same LAContext that was used to call canEvaluatePolicy on? 4. What does the biometryType property read then - is it LABiometryTypeNone (0)?

Please provide your response or results by updating your bug report. If uploading files, please compress first.

By mshibanami at Jan. 4, 2018, 5:24 a.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!