随着iphone系统的升级,ios的登录方式也越来越多,其中指纹登录和脸部识别也越来越常见了,下面为大家集成一下关于指纹登录和脸部识别登录的方法;
并为大家简单地封装一下吧;
下面贴上代码
SWFingerprintLock.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//支持的登录方式
typedef NS_ENUM(NSInteger ,UnlockSupportType) {
JUnlockType_None = 0,//既不支持指纹,也不支持脸部识别
JUnlockType_TouchID,//指纹解锁
JUnlockType_FaceID//脸部识别
};
//登录回调类型
typedef NS_ENUM(NSInteger ,UnlockResult) {
JUnlockFailed = 0,//失败
JUnlockSuccess//成功
};
typedef void(^UnlockResultBlock)(UnlockResult result , NSString* errMsg);
@interface SWFingerprintLock : NSObject
@property (nonatomic , assign) UnlockSupportType supportType;//支持的登录方式
+ (SWFingerprintLock*)shareInstance;//单例
+ (UnlockSupportType)checkUnlockSupportType;//检测支持的登录方式
+ (void)unlockWithResultBlock:(UnlockResultBlock)block;//登录回调结果(在调用此方法前,需要调用上面的方式获取登录的支持方式)
@end
NS_ASSUME_NONNULL_END
SWFingerprintLock.m
#import "SWFingerprintLock.h"
#import <LocalAuthentication/LocalAuthentication.h>
static SWFingerprintLock* g_fingerprintLock = nil ;
@interface SWFingerprintLock()
@property (nonatomic , strong) LAContext* context;
@end
@implementation SWFingerprintLock
- (instancetype)init{
if(self = [super init]){
if(@available(iOS 8.0, *)){
_context = [[LAContext alloc] init];
}
}
return self;
}
+ (SWFingerprintLock*)shareInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
g_fingerprintLock = [[SWFingerprintLock alloc] init];
});
return g_fingerprintLock;
}
+ (UnlockSupportType)checkUnlockSupportType{
UnlockSupportType supportType = JUnlockType_None;
// 检测设备是否支持TouchID或者FaceID
if (@available(iOS 8.0, *)) {
LAContext* LAContent = [[LAContext alloc] init];
NSError *authError = nil;
BOOL isCanEvaluatePolicy = [LAContent canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError];
if (authError) {
NSLog(@"检测设备是否支持TouchID或者FaceID失败!\n error : == %@",authError.localizedDescription);
// [self showAlertView:[NSString stringWithFormat:@"检测设备是否支持TouchID或者FaceID失败。\n errorCode : %ld\n errorMsg : %@",(long)authError.code, authError.localizedDescription]];
} else {
if (isCanEvaluatePolicy) {
// 判断设备支持TouchID还是FaceID
if (@available(iOS 11.0, *)) {
switch (LAContent.biometryType) {
case LABiometryNone:
{
}
break;
case LABiometryTypeTouchID:
{
supportType = JUnlockType_TouchID;
}
break;
case LABiometryTypeFaceID:
{
supportType = JUnlockType_FaceID;
}
break;
default:
break;
}
} else {
// Fallback on earlier versions
NSLog(@"iOS 11之前不需要判断 biometryType");
// 因为iPhoneX起始系统版本都已经是iOS11.0,所以iOS11.0系统版本下不需要再去判断是否支持faceID,直接走支持TouchID逻辑即可。
supportType = JUnlockType_TouchID;
}
} else {
}
}
} else {
// Fallback on earlier versions
}
[self shareInstance].supportType = supportType;
return supportType;
}
+ (void)unlockWithResultBlock:(UnlockResultBlock)block{
if([self shareInstance].supportType == JUnlockType_None){
//[self errorTipWithMessage:@"此设备未设置ToucID或FaceID,请使用手势登录" WithIsReturn:NO];
return;
}
LAContext* jcontext = [self shareInstance].context;
jcontext.localizedFallbackTitle = @"输入密码";
LAPolicy policyType = LAPolicyDeviceOwnerAuthenticationWithBiometrics;
if (@available(iOS 9.0, *)) {
policyType = LAPolicyDeviceOwnerAuthentication;
}
NSError* error = nil;
if ([jcontext canEvaluatePolicy:policyType error:&error]) {
NSString* str ;
if([self shareInstance].supportType == JUnlockType_TouchID){
str = @"通过Home键验证已有手机指纹";
}else if([self shareInstance].supportType == JUnlockType_FaceID){
str = @"请正对屏幕启动脸部识别";
}
[jcontext evaluatePolicy:policyType localizedReason:str reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 验证成功");
if(block){
block(JUnlockSuccess,@"");
}
});
}else if(error){
switch (error.code) {
case LAErrorAuthenticationFailed:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 验证失败");
});
break;
}
case LAErrorUserCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被用户手动取消");
});
}
break;
case LAErrorUserFallback:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"用户不使用TouchID,选择手动输入密码");
});
}
break;
case LAErrorSystemCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)");
});
}
break;
case LAErrorPasscodeNotSet:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 无法启动,因为用户没有设置密码");
});
}
break;
case LAErrorTouchIDNotEnrolled:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 无法启动,因为用户没有设置TouchID");
});
}
break;
case LAErrorTouchIDNotAvailable:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 无效");
});
}
break;
case LAErrorTouchIDLockout:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码)");
});
}
break;
case LAErrorAppCancel:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"当前软件被挂起并取消了授权 (如App进入了后台等)");
});
}
break;
case LAErrorInvalidContext:{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"当前软件被挂起并取消了授权 (LAContext对象无效)");
});
}
break;
default:
break;
}
}
}];
}else{
block(JUnlockFailed,@"TouchID失效");
}
}
@end
ps:一些童鞋发现脸部识别没用的话,记得要在plist文件加入描述的key
ok 拿去用吧