ios 如何以编程方式检查“Face Id”和“Touch Id”的支持
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46887547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically check support of 'Face Id' and 'Touch Id'
提问by Krunal
I've integrated LocalAuthenticationfor my app security purpose, which has been supporting 'Touch Id'based supporting. But now, apple has recently added 'Face Id'based authentication also.
我已经为我的应用程序安全目的集成了LocalAuthentication,它一直支持基于“Touch Id”的支持。但是现在,苹果最近还添加了基于“Face Id”的身份验证。
How can I check, which type of authentication is supported by a device. Touch Id or Face Id?
如何检查设备支持哪种类型的身份验证。触控 ID 还是面容 ID?
回答by leifdan01
I've been struggling to get this to work and found that I needed to use a single instance of the LAContext and needed to call the LAContextInstance.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) before getting the biometryType. Here is my final code with support for older iOS versions:
我一直在努力让它工作,发现我需要使用 LAContext 的单个实例,并且需要在获取biometryType 之前调用LAContextInstance.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)。这是我支持旧 iOS 版本的最终代码:
import LocalAuthentication
static func biometricType() -> BiometricType {
let authContext = LAContext()
if #available(iOS 11, *) {
let _ = authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
switch(authContext.biometryType) {
case .none:
return .none
case .touchID:
return .touch
case .faceID:
return .face
}
} else {
return authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? .touch : .none
}
}
enum BiometricType {
case none
case touch
case face
}
回答by Surjeet
With Xcode 9, Look at LocalAuthentication -> LAContext -> LABiometryType.
使用 Xcode 9,查看LocalAuthentication -> LAContext -> LABiometryType。
LABiometryTypeis a enum with values as in attached image
LABiometryType是一个枚举,其值如附加图像中所示
You can check which authentication type supported by device between Touch ID and FaceID or none.
您可以在 Touch ID 和 FaceID 之间检查设备支持哪种身份验证类型或不支持。
Edit:
编辑:
Apple have updated values for this enum LABiometryType. none is deprecated now.
Apple 已更新此枚举LABiometryType 的值。现在没有被弃用。
回答by Alix
As I am a big fan of extension. I phrase this answer a little differently. Essense is the same. This is a drop-in extension.
因为我是扩展的忠实粉丝。我对这个答案的表述略有不同。本质是一样的。这是一个插入式扩展。
import LocalAuthentication
extension LAContext {
enum BiometricType: String {
case none
case touchID
case faceID
}
var biometricType: BiometricType {
var error: NSError?
guard self.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
// Capture these recoverable error thru Crashlytics
return .none
}
if #available(iOS 11.0, *) {
switch self.biometryType {
case .none:
return .none
case .touchID:
return .touchID
case .faceID:
return .faceID
}
} else {
return self.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? .touchID : .none
}
}
}
Use like this:
像这样使用:
var currentType = LAContext().biometricType
回答by Dren
Here is one more way via the property (for example, on your access instance).
这是通过属性的另一种方式(例如,在您的访问实例上)。
import LocalAuthentication
enum BiometricType {
case none
case touchID
case faceID
}
var biometricType: BiometricType {
get {
let context = LAContext()
var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
print(error?.localizedDescription ?? "")
return .none
}
if #available(iOS 11.0, *) {
switch context.biometryType {
case .none:
return .none
case .typeTouchID:
return .touchID
case .typeFaceID:
return .faceID
}
} else {
return .touchID
}
}
}
回答by karim
Objective C :)
目标 C :)
/** Only interesting devices are enumerated here. To change view constraints depending
on screen height. Or the top notch for iPhone X
*/
typedef NS_ENUM(NSUInteger, BPDeviceType) {
BPDeviceTypeUnknown,
BPDeviceTypeiPhone4,
BPDeviceTypeiPhone5,
BPDeviceTypeiPhone6,
BPDeviceTypeiPhone6Plus,
BPDeviceTypeiPhone7,
BPDeviceTypeiPhone7Plus,
BPDeviceTypeiPhoneX,
BPDeviceTypeiPad
};
+ (BPDeviceType)getDeviceType {
double screenHeight = [[UIScreen mainScreen] bounds].size.height;
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
return BPDeviceTypeiPad;
} else if (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone)
{
if (@available(iOS 11, *)) {
UIEdgeInsets insets = [UIApplication sharedApplication].delegate.window.safeAreaInsets;
if (insets.top > 0) {
return BPDeviceTypeiPhoneX;
}
}
if(screenHeight == 480) {
return BPDeviceTypeiPhone4;
} else if (screenHeight == 568) {
return BPDeviceTypeiPhone5;
} else if (screenHeight == 667) {
return BPDeviceTypeiPhone6;
} else if (screenHeight == 736) {
return BPDeviceTypeiPhone6Plus;
}
}
return BPDeviceTypeUnknown;
}
+ (BOOL) isBiometricIDAvailable {
if (![LAContext class]) return NO;
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (![myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
NSLog(@"%@", [authError localizedDescription]);
return NO;
}
return YES;
}
+ (BOOL) isTouchIDAvailable {
if (![LAContext class]) return NO;
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (![myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
NSLog(@"%@", [authError localizedDescription]);
return NO;
// if (authError.code == LAErrorTouchIDNotAvailable) {}
}
if (@available(iOS 11.0, *)) {
if (myContext.biometryType == LABiometryTypeTouchID){
return YES;
} else {
return NO;
}
} else {
return YES;
}
}
+ (BOOL) supportFaceID {
return [BPDeviceInfo getDeviceType] == BPDeviceTypeiPhoneX;
}
+ (BOOL) isFaceIDAvailable {
if (![LAContext class]) return NO;
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (![myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
NSLog(@"%@", [authError localizedDescription]);
return NO;
}
if (@available(iOS 11.0, *)) {
if (myContext.biometryType == LABiometryTypeFaceID){
return YES;
} else {
return NO;
}
} else {
return NO;
}
}
回答by Vinayak Pal
I made a singleton class for local authentication as it helps to initialise an instance one time using static
property for the entire application.
我为本地身份验证创建了一个单例类,因为它有助于使用static
整个应用程序的属性一次初始化一个实例。
import Foundation
import LocalAuthentication
public class LocalAuthManager: NSObject {
public static let shared = LocalAuthManager()
private let context = LAContext()
private let reason = "Your Request Message"
private var error: NSError?
enum BiometricType: String {
case none
case touchID
case faceID
}
private override init() {
}
// check type of local authentication device currently support
var biometricType: BiometricType {
guard self.context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
return .none
}
if #available(iOS 11.0, *) {
switch context.biometryType {
case .none:
return .none
case .touchID:
return .touchID
case .faceID:
return .faceID
}
} else {
return self.context.canEvaluatePolicy(.deviceOwnerAuthentication, error: nil) ? .touchID : .none
}
}
}
Implementation:
执行:
func checkAuth() {
let authType = LocalAuthManager.shared.biometricType
switch authType {
case .none:
print("Device not registered with TouchID/FaceID")
case .touchID:
print("Device support TouchID")
case .faceID:
print("Device support FaceID")
}
}
回答by Usman Awan
Face IDis available from iOS 11 and iPhone X comes with iOS 11 by default. In the LocalAuth framework they have added a 'biometryType' property which can give you ability to detect whether Face ID is available on device.
面容 ID可从 iOS 11 使用,iPhone X 默认随 iOS 11 一起提供。在 LocalAuth 框架中,他们添加了一个“biometryType”属性,可以让您检测设备上是否可以使用 Face ID。
/// checks if face id is avaiable on device
func faceIDAvailable() -> Bool {
if #available(iOS 11.0, *) {
let context = LAContext()
return (context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthentication, error: nil) && context.biometryType == .faceID)
}
return false
}
回答by Markicevic
Here is my "helper class", it includes passcode also
这是我的“助手类”,它还包括密码
enum BiometryType: String {
case none = "None"
case faceID = "Face ID"
case touchID = "Touch ID"
case passcode = "Passcode"
}
var biometryType: BiometryType {
let myContext = LAContext()
let hasAuthenticationBiometrics = myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
let hasAuthentication = myContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: nil)
if #available(iOS 11.0, *) {
if hasAuthentication {
if hasAuthenticationBiometrics {
switch myContext.biometryType {
case .none: return .none
case .faceID: return .faceID
case .touchID: return .touchID
}
} else {
return .passcode
}
} else {
return .none
}
} else {
if hasAuthentication {
if hasAuthenticationBiometrics {
return .touchID
} else {
return .passcode
}
} else {
return .none
}
}
}
回答by Everton Cunha
From @Markicevic extension, but ignoring cases where user is not enrolled, etc...
来自@Markicevic 扩展,但忽略用户未注册的情况等...
extension LAContext {
enum BiometricType: String {
case none = ""
case touchID = "Touch ID"
case faceID = "Face ID"
}
static var biometricType: BiometricType {
var error: NSError?
let context = LAContext()
_ = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
if error?.code == LAError.Code.touchIDNotAvailable.rawValue {
return .none
}
if #available(iOS 11.0, *) {
switch context.biometryType {
case .none:
return .none
case .touchID:
return .touchID
case .faceID:
return .faceID
}
} else {
return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? .touchID : .none
}
}
}
}
回答by Victor Bogdan
This code builds without warnings on Xcode 9.2
-9.4
(see comments for 9.1
):
此代码在 Xcode 上构建时没有警告9.2
- 9.4
(请参阅 的注释9.1
):
@objc let biometricsAuthPolicy = LAPolicy.deviceOwnerAuthenticationWithBiometrics
@objc func supportsFaceID() -> Bool {
if #available(iOS 11.0, *) {
return biometryType() == .faceID // return biometryType() == .typeFaceID for Xcode 9.1
}
return false
}
@objc func supportsTouchID() -> Bool {
if #available(iOS 11.0, *) {
return biometryType() == .touchID // return biometryType() == .typeTouchID for Xcode 9.1
}
let context = LAContext()
return context.canEvaluatePolicy(biometricsAuthPolicy, error: nil)
}
@objc @available(iOS 11.0, *)
func biometryType() -> LABiometryType {
var error: NSError?
let context = LAContext()
guard context.canEvaluatePolicy(biometricsAuthPolicy, error: &error) else {
if #available(iOS 11.2, *) {
return .none
}
return LABiometryType.LABiometryNone // return LABiometryType.none for Xcode 9.1
}
return context.biometryType
}