确定iOS设备是否支持TouchID而不设置密码

问题描述 投票:20回答:6

我目前正在开发一个iOS应用程序,使用户可以使用TouchID登录应用程序,但首先他们必须首先在应用程序内设置密码。问题是,要显示设置密码选项以启用TouchID登录,我需要检测iOS设备是否支持TouchID。

使用LAContext和canEvaluatePolicy(如If Device Supports Touch ID中的答案),如果用户在其iOS设备上设置了密码,我可以确定当前设备是否支持TouchID。这是我的代码片段(我使用的是Xamarin,所以它在C#中):

static bool DeviceSupportsTouchID () 
{
    if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
    {
        var context = new LAContext();
        NSError authError;
        bool touchIDSetOnDevice = context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out authError);

        return (touchIDSetOnDevice || (LAStatus) Convert.ToInt16(authError.Code) != LAStatus.TouchIDNotAvailable);
    }

    return false;
}

如果用户尚未设置设备密码,则无论设备是否实际支持TouchID,authError都将返回“PasscodeNotSet”错误。

如果用户的设备支持TouchID,我想在我的应用程序中始终显示TouchID选项,无论用户是否在其设备上设置了密码(我只是警告用户首先在他们的设备上设置密码)。反之亦然,如果用户的设备不支持TouchID,我显然不想在我的应用程序中显示TouchID选项。

所以我的问题是,无论用户是否在其设备上设置了密码,是否有一种很好的方法可以始终如一地确定iOS设备是否支持TouchID?

我能想到的唯一解决方法是确定设备的架构(在Determine if iOS device is 32- or 64-bit中得到解答),因为只有具有64位架构的设备才支持TouchID。但是,我正在寻找是否有更好的方法来做到这一点。

先谢谢! :)

ios iphone ipad xamarin touch-id
6个回答
17
投票

在下面的讨论结束时,当用户未在其设备上设置密码时,暂时无法确定设备是否实际支持TouchID。

我在Apple bug记者上报告了这个TouchID漏洞。那些想要关注这个问题的人可以在Open Radar上看到它:http://www.openradar.me/20342024

谢谢@rckoenes的输入:)

编辑

事实证明有人已经报告了类似的问题(#18364575)。以下是Apple对此问题的回复:

“Engineering已根据以下信息确定此问题的行为符合预期:

如果未设置密码,您将无法检测Touch ID的存在。一旦设置了密码,canEvaluatePolicy将最终返回LAErrorTouchIDNotAvailable或LAErrorTouchIdNotEnrolled,您将能够检测Touch ID存在/状态。

如果用户在具有Touch ID的手机上禁用了密码,则他们知道他们无法使用Touch ID,因此这些应用无需检测Touch ID状态或推广基于Touch ID的功能。 “

所以.....来自Apple的最终答案是否是:(

注意:类似的StackOverflow问题来自报告此事的人 - > iOS8 check if device has Touch ID(想知道为什么我之前没有找到这个问题,尽管我广泛搜索...)


11
投票

检测TouchID是否可用的正确方法:

BOOL hasTouchID = NO;
// if the LAContext class is available
if ([LAContext class]) {
    LAContext *context = [LAContext new];
    NSError *error = nil;
    hasTouchId = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
}

抱歉,它位于Objective-C中,您可能需要将其翻译为C#。

您应该避免检查系统版本,只检查该类或方法是否可用。


7
投票

我知道这是去年的一个问题,但这个解决方案不能满足您的需求吗? (SWIFT代码)

if #available(iOS 8.0, *) {
    var error: NSError?
    let hasTouchID = LAContext().canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)

    //Show the touch id option if the device has touch id hardware feature (even if the passcode is not set or touch id is not enrolled)
    if(hasTouchID || (error?.code != LAError.TouchIDNotAvailable.rawValue)) {
        touchIDContentView.hidden = false
    } 
}

然后,当用户按下按钮以使用触摸ID登录时:

@IBAction func loginWithTouchId() {
    let context = LAContext()

    var error: NSError?
    let reasonString = "Log in with Touch ID"

    if (context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)) {
        [context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in
            //Has touch id. Treat the success boolean
        })]
    } else { 
        //Then, if the user has touch id but is not enrolled or the passcode is not set, show a alert message
        switch error!.code{

        case LAError.TouchIDNotEnrolled.rawValue:
            //Show alert message to inform that touch id is not enrolled
            break

        case LAError.PasscodeNotSet.rawValue:
            //Show alert message to inform that passcode is not set
            break

        default:
            // The LAError.TouchIDNotAvailable case.
            // Will not catch here, because if not available, the option will not visible
        }
    }
}

希望能帮助到你!


4
投票

对于Objective C 它无需检查设备版本即可在所有设备上运行良好。

- (void)canAuthenticatedByTouchID{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = touchIDRequestReason;

if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
 }else{
    switch (authError.code) {
        case kLAErrorTouchIDNotAvailable:
            [labelNotSupportTouchID setHidden:NO];
            [switchBtn setHidden:YES];
            [labelEnableTouchid setHidden:YES];
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                [self showAlertMessage:@"EyeCheck Pro" message:@"Device does not support Touch ID Service."];
            });

            break;
    }
  }
}

3
投票

这是一个有点乏味的方法来弄清楚设备是否有物理触摸id传感器。

+ (BOOL)isTouchIDExist {
if(![LAContext class]) //Since this mandotory class is not there, that means there is no physical touch id.
    return false;

//Get the current device model name
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *model = malloc(size);
sysctlbyname("hw.machine", model, &size, NULL, 0);
NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];

//Devices that does not support touch id
NSArray *deviceModelsWithoutTouchID = [[NSArray alloc]
                                       initWithObjects:
                                       @"iPhone1,1", //iPhone
                                       @"iPhone1,2", //iPhone 3G
                                       @"iPhone2,1", //iPhone 3GS
                                       @"iPhone3,1", //iPhone 4
                                       @"iPhone3,2",
                                       @"iPhone3,3",
                                       @"iPhone4,1", //iPhone 4S
                                       @"iPhone5,1", //iPhone 5
                                       @"iPhone5,2",
                                       @"iPhone5,3", //iPhone 5C
                                       @"iPhone5,4",
                                       @"iPod1,1", //iPod
                                       @"iPod2,1",
                                       @"iPod3,1",
                                       @"iPod4,1",
                                       @"iPod5,1",
                                       @"iPod7,1",
                                       @"iPad1,1", //iPad
                                       @"iPad2,1", //iPad 2
                                       @"iPad2,2",
                                       @"iPad2,3",
                                       @"iPad2,4",// iPad mini 1G
                                       @"iPad2,5",
                                       @"iPad2,5",
                                       @"iPad2,7",
                                       @"iPad3,1", //iPad 3
                                       @"iPad3,2",
                                       @"iPad3,3",
                                       @"iPad3,4", //iPad 4
                                       @"iPad3,5",
                                       @"iPad3,6",
                                       @"iPad4,1", //iPad Air
                                       @"iPad4,2",
                                       @"iPad4,3",
                                       @"iPad4,4", //iPad mini 2
                                       @"iPad4,5",
                                       @"iPad4,6",
                                       @"iPad4,7",
                                       nil];

return ![deviceModelsWithoutTouchID containsObject:deviceModel];

}

参考:https://www.theiphonewiki.com/wiki/Models https://en.wikipedia.org/wiki/IOS


0
投票

对于iOS 11+,您可以使用biometryType: LABiometryTypeLAContext。更多来自Apple文档:

/// Indicates the type of the biometry supported by the device.
///
/// @discussion  This property is set only when canEvaluatePolicy succeeds for a biometric policy.
///              The default value is LABiometryTypeNone.
@available(iOS 11.0, *)
open var biometryType: LABiometryType { get }

@available(iOS 11.0, *)
public enum LABiometryType : Int {

    /// The device does not support biometry.
    @available(iOS 11.2, *)
    case none

    /// The device does not support biometry.
    @available(iOS, introduced: 11.0, deprecated: 11.2, renamed: "LABiometryType.none")
    public static var LABiometryNone: LABiometryType { get }

    /// The device supports Touch ID.
    case touchID

    /// The device supports Face ID.
    case faceID
}
© www.soinside.com 2019 - 2024. All rights reserved.