How to detect whether device support FaceID or not?
Asked Answered
M

6

8

Its bit early to ask but I'm planning to add feature specially for FaceID, so before that I need to validate either device support FaceID or not? Need suggestion and help. Thanks in advance.

Munich answered 25/9, 2017 at 10:10 Comment(1)
I googled and searched on Stackoverflow but didn't found right answer, so after then read Apple Documentation and posted answer, I hope this will help others who come here(stackoverflow) to find quick solution when they've short time :). https://mcmap.net/q/1241809/-how-to-detect-whether-device-support-faceid-or-notMunich
V
12

Objective-C version

- (BOOL) isFaceIdSupported{
    if (@available(iOS 11.0, *)) {
        LAContext *context = [[LAContext alloc] init];
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]){
            return ( context.biometryType == LABiometryTypeFaceID);
        }
    }
    return NO;
}
Vola answered 5/12, 2017 at 8:4 Comment(0)
A
11

I found that you have to call canEvaluatePolicy before you will properly get the biometry type. If you don't you'll always get 0 for the raw value.

So something like this in Swift 3, tested and working in Xcode 9.0 & beta 9.0.1.

class func canAuthenticateByFaceID () -> Bool {
    //if iOS 11 doesn't exist then FaceID doesn't either
    if #available(iOS 11.0, *) {
        let context = LAContext.init()

        var error: NSError?

        if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
            //As of 11.2 typeFaceID is now just faceID
            if (context.biometryType == LABiometryType.typeFaceID) {
                return true
            }
        }
    }

    return false
}

You could of course write that just to see if it's either biometric and return the type along with the bool but this should be more than enough for most to work off of.

Amaranth answered 31/10, 2017 at 23:58 Comment(3)
We discovered this code works if the phone has face ID and it's enrolled and ok. However, if face ID is not registered, or if it "locks out" by recognizing too many incorrect faces, then this function returns false (Causing our code at least to go down the path of Touch ID which is incorrect). Does anyone know a way to detect if a device is Face ID capable regardless of whether it's enrolled or locked out?Searcy
This always returns false on an iPhone X simulatorFaradism
Actually not always: only when it's not enrolled. On Simulator menu bar for a iPhone X, "Hardware" > "Face ID" > "Enrolled".Bobbybobbye
M
5

Thanks Ashley Mills, I created a function to detect FaceID in Device.

- (BOOL)canAuthenticateByFaceID {
    LAContext *context = [[LAContext alloc] init];
    if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
       if (context.biometryType == LABiometryTypeFaceID && @available(iOS 11.0, *)) {
        return YES;
    } else {
        return NO;
    }
  }
}

Hope this will help other. Happy coding!!

Finally I wrote my own Library for detecting FaceID here you find

Munich answered 25/9, 2017 at 10:22 Comment(5)
Hi Aleem, Do you have any references as to how to use face id to authenticate a user from our application. I checked online but couldnt find any.Semela
In swift I get 0 on any device in the Simulator for: context.biometryType.rawValue (iPhoneX, iPhone8). Shouldn´t that return 2 and 1 (typeFaceID, typeTouchID)Erratic
mica I found the issue was in the policy not being evaluated first, posted in an answer above more thoroughly in common day Swift!Amaranth
Incorrect code. Let see the property's comment: This property is set only when canEvaluatePolicy succeeds for a biometric policySalespeople
canEvaluatePolicy doesn't cover the device HAS face ID or no! maybe it has not set yet!Outgroup
D
2

Swift 4 compatible version

var isFaceIDSupported: Bool {
    if #available(iOS 11.0, *) {
        let localAuthenticationContext = LAContext()
        if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
            return localAuthenticationContext.biometryType == .faceID
        }
    }
    return false
}
Drogin answered 14/5, 2018 at 9:13 Comment(1)
canEvaluatePolicy doesn't cover the device HAS face ID or no! maybe it has not set yet!Outgroup
O
0
+(BOOL)supportFaceID
{
   LAContext *myContext = [[LAContext alloc] init];
   NSError *authError = nil;
   // call this method only to get the biometryType and we don't care about the result!
   [myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError];
    NSLog(@"%@",authError.localizedDescription);
    if (@available(iOS 11.0, *)) {
    return myContext.biometryType == LABiometryTypeFaceID;
   } else {
    // Device is running on older iOS version and OFC doesn't have FaceID
    return NO;
  }
}
Outgroup answered 25/9, 2018 at 14:36 Comment(0)
H
0

If biometric controls are defined on the device, you can find out which control it is. However, if the user has not defined face ID or touch ID on the device, the code will fail. If the device has biometric control and is not used, you can find it through these error codes. Detailed information for error codes; https://developer.apple.com/documentation/localauthentication/laerror/laerrorbiometrynotenrolled

public static var hasBiometricControl: Bool {
        
        let authContext = LAContext()
        var error: NSError?
        guard authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
            
            switch Int32(error!.code) {
            case kLAErrorBiometryNotAvailable:
                return false
            case kLAErrorBiometryNotEnrolled:
                return true
            default:
                return false
            }
        }

        if #available(iOS 11.0, *) {
            switch authContext.biometryType {
            case .none:
                return false
            case .touchID:
                return true
            case .faceID:
                return true
            @unknown default:
                return false
            }
        }
        return  authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? true: false
    }
Housen answered 15/9, 2023 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.