LAContext has method to check if device can evaluate touch ID and gives error message. Problem is that same error message "LAErrorPasscodeNotSet" is given by system in two cases:
1) If user has Touch ID, but turned it off in settings (iPhone 5s with iOS8)
2) If device doesn't have Touch ID (iPad with iOS8)
Q: How to check if device supports Touch ID, but haven't turned it on in settings?
Update:
Had created ticket to Apple regarding this bug (ID# 18364575) and received answer:
"Engineering has determined that this issue behaves as intended based on the following information:
If passcode is not set, you will not be able to detect Touch ID presence. Once the passcode is set, canEvaluatePolicy will eventually return LAErrorTouchIDNotAvailable or LAErrorTouchIdNotEnrolled and you will be able to detect Touch ID presence/state.
If users have disabled passcode on phone with Touch ID, they knew that they will not be able to use Touch ID, so the apps don't need to detect Touch ID presence or promote Touch ID based features. "
Here you can check, Touch-ID and Face-ID both (with iOS 11+)
Use property
biometryType
ofLAContext
to check and evaluate available biometric policy. (For a passcode authentication , when biometric fails, use:LAPolicyDeviceOwnerAuthentication
)Try this and see:
Objective-C:
Swift:
Integrating Touch ID
Now we get to the main part of the tutorial… integrating Touch ID with the app. As it turns out, Apple has made some fairly standard code for accessing Touch ID. The code comes from the Local Authentication Framework and is as follows:
Lets take a look at each line to see what it does:
Line 1: Here we create an LAContext object. The LAContext class is responsible for handling the context for the authentication. Put simply, we use an LAContext object to check if a type of authentication is available. In the case of this tutorial, we will later be checking “if” touch ID is an option.
Line 2: We need an NSError so that the LAContext can use it to return if there is an error.
Line 3: We set an NSString with a description that it put on screen to let the user know why the touch ID view has appeared on screen.
Line 5: This is where we put the LAContext constant to use by calling the canEvaluatePolicy: method and sending it an LAPolicy constant as an argument. In this case, we pass LAPolicyDeviceOwnerAuthenticationWithBiometrics. If this fails, either touch ID is not configured on a compatible device, or touch ID is not available on the device… think an iPhone 4S, 5 or 5c running the app. Also, this doesn’t take in to account a device running iOS 7, so if you plan to run finger print authentication on an app, make sure you check that you are working with a compatible device and if not, make other options available such as password on pin code to access the app.
Lines 6, 7 and 8: If the user can authenticate with biometrics we can now call the evaluatePolicy method on our LAContext object. We do this by passing the same constant over, LAPolicyDeviceOwnerAuthenticationWithBiometrics, as well as passing our reason string and then specifying a block for the response to be handled.
We will get either a YES or a NO as a result. If a YES then line 10 is where we put code for a positive response. Likewise, line 12 is where we put our failure code.
Finally on line 15, we have the ELSE statement which runs if line 5 fails the test… i.e., biometrics is not available. We can check the authError pointer to get the reason and present it to the user if needed.
Finally, to get this to not show errors, we need to import the local authentication framework in to our project:
So, lets add this code to our project. Open ViewController.m and at the top, import the local authentication framework.
For more detail visit this link : http://www.devfright.com/touch-id-tutorial-objective-c/
In Swift 3
deviceSupportsTouchId() return Success if the device has touch Id capability.
If not then, function will return error, giving you the following error code if touchIDNotEnrolled is not set yet.
You can handle it using this value.
Maybe you could write your own method to check which device are you running on, because if returned error is the same, it would be hard to figure out exactly if Touch ID is supported. I would go with something like this:
After having the model identifier, I would just check if model identifier equals is one of the models that support Touch ID:
The array contains all model ID's which support Touch ID, which are:
The only downside of this method is that once new devices are released with Touch ID, the model array will have to be updated manually.
You can find out if a device supports Biometric scanning (touchID and faceID) by checking the error code as shown below: