我已将LocalAuthentication集成到我的应用安全目的,该目的一直支持'Touch Id'支持。但是现在,苹果最近还添加了'Face Id'身份验证。
如何检查设备支持哪种类型的身份验证。触摸ID或面部识别码?
答案 0 :(得分:35)
我一直在努力让这个工作,并发现我需要使用LAContext的单个实例并需要调用 LAContextInstance .canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,error:nil )在获取biometryType之前。这是我的最终代码,支持旧的iOS版本:
input {
background-color: red;
&:checked {
label & {
background-color: green;
}
}
}
答案 1 :(得分:18)
使用Xcode 9,查看LocalAuthentication -> LAContext -> LABiometryType。
LABiometryType 是一个枚举,其值如附加图像
您可以在Touch ID和FaceID之间检查设备支持的身份验证类型,或者不检查。
修改强>
Apple已更新此枚举 LABiometryType 的值。 none现已弃用。
答案 2 :(得分:7)
我非常喜欢扩展。我对这个答案的措辞有些不同。本质是一样的。这是一个插件扩展。
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
}
}
}
像这样使用:
var currentType = LAContext().biometricType
答案 3 :(得分:5)
目标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;
}
}
答案 4 :(得分:4)
这是通过属性的另一种方式(例如,在您的访问实例上)。
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
}
}
}
答案 5 :(得分:4)
人脸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
}
答案 6 :(得分:4)
这是我的“帮助程序类”,它还包括密码
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
}
}
}
答案 7 :(得分:1)
此代码在Xcode from .block import *
-9.2
上构建时没有警告(请参见9.4
的注释):
9.1
答案 8 :(得分:1)
来自@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
}
}
}
答案 9 :(得分:1)
我为本地身份验证创建了一个单例类,因为它有助于使用整个应用程序的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
}
}
}
实施:
func checkAuth() {
let authType = LocalAuthManager.shared.biometricType
switch type {
case .none:
print("Device not registered with TouchID/FaceID")
case .touchID:
print("Device support TouchID")
case .faceID:
print("Device support FaceID")
}
}
答案 10 :(得分:1)
-(BOOL)faceIDAvailable {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (@available(iOS 11.0, *)) {
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&authError] && myContext.biometryType == LABiometryTypeFaceID) {
return true;
}
}
return false;
}
-(BOOL)touchIDAvailable {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (@available(iOS 11.0, *)) {
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&authError] && myContext.biometryType == LABiometryTypeTouchID) {
return true;
}
}
return false;
}
答案 11 :(得分:0)
快速更新5,开关流量需要默认条件。
rvs
测试案例在下面
import Foundation
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 through fabric
return .none
}
if #available(iOS 11.0, *) {
switch self.biometryType {
case .touchID:
return .touchID
case .faceID:
return .faceID
default:
return .none
}
}
return self.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? .touchID : .none
}
}
答案 12 :(得分:0)
请参阅为“使用面部ID或触摸ID将用户登录到您的应用程序” 中提供的Apple示例代码。
Apple示例代码链接- https://docs-assets.developer.apple.com/published/fbfd13f4d9/LoggingAUserIntoYourAppWithFaceIDOrTouchID.zip
在下面的链接上阅读示例代码的详细说明。 https://developer.apple.com/documentation/localauthentication/logging_a_user_into_your_app_with_face_id_or_touch_id
答案 13 :(得分:0)
开始在 12 Pro 上测试一些新应用,发现我发布的应用只有 Touch ID 而没有 Face ID。
我来到这里看到了这一切,所以我开始尝试更改我的 Touch ID 代码,但我需要做的就是将隐私密钥添加到 info.plist。
信息属性列表➕
然后向下滚动到:Privacy- Face ID Usage Description, (Type: String), (Value: YES)
太简单了?