iOS指纹登录面容登录功能开发详解

iOS TouchID/FaceID 开发 创建LXFAuthentication类的.h和.m文件,继承自LAContext .h代码如下: // // LXFAuthentication.h // Test // // Created by 凌煊峰 on 2019/6/21. // Copyright © 2019 凌煊峰. All rights reserved. // #import <LocalAuthent... 阅读详情
AI摘要

本文详细介绍iOS指纹登录和面容登录功能开发。因产品和运营顾虑隐私问题此前未接入,现重新整理流程。原理是登录后提示绑定,绑定ID由后端控制。代码实现封装成工具类,分别阐述首页、登录页和个人中心的调用流程。

一、背景

        iOS指纹登录和面容登录其实是一个很简单也很成熟的功能了,很多年前就有做过。但是在目前的公司一直没有接入,最近才知道原来是产品和运营认为指纹登录或面容登录会采集用户的人脸或指纹信息,涉及到用户隐私,比较敏感,担心用户不能接受和使用,也担心操作不够简洁。所以一直没有推出。其实App只是使用系统录入的信息进行验证,只接收验证结果,并不会采集用户指纹/面容信息。于是我又重新整理和总结了一套比较简单的登录流程,整理记录下来。

二、流程

首先看一下流程图:

三、原理概括

        基于简单简洁的原则,我们仅在用户登录完成后才提示用户用户绑定指纹/面容登录,提示前需要先判断设备是否支持指纹/面容识别且录入了对应信息,支持且录入则判断是否绑定过,未绑定才提示绑定,点击绑定直接调用后端绑定接口获取绑定ID,,存储到本地,标记为已绑定(这里不要求验证指纹/面容后才能绑定,也是为了简化用户操作,减少敏感度)。下次登录时优先弹出指纹/面容登录界面,识别后将本地存储的绑定ID传给后端获取用户信息完成登录。

        对于绑定ID的生成和规则,最好是由后端控制,每个账号只能绑定一个ID且固定不变(可以是用户id+特定规则加密生成),那么不同设备登录同一个账号绑定指纹/面容后,才能保证两个设备都能使用指纹/面容登录且后端不需要生成多个绑定ID导致绑定ID一直增加;同一个设备登录不同账号绑定指纹,则更新本地缓存,下次登录则登录的是后绑定的设备,卸载重装后需要重新绑定,因绑定ID不变,所以也不会一直增加。

        对于用户交互上,考虑到用户可能担心平台采集指纹/面容不安全,可以在绑定和登录时提示用户平台只接收验证结果,不采集用户信息,同时在个人中心设置页,增加入口和说明,支持用户关闭。

四、代码实现

      这里我是直接封装成工具类方便调用

 1、新建单例工具类BiometricTool,导入生物识别框架。

  .h文件

#import <Foundation/Foundation.h>
//导入框架:生物识别登录(指纹/人脸)
#import <LocalAuthentication/LocalAuthentication.h>

NS_ASSUME_NONNULL_BEGIN

//生物识别类型
typedef NS_ENUM(NSInteger, BiometryType){
    BiometryType_Unsurported = 0,   //不支持生物识别
    BiometryType_AuthRefuse,        //拒绝授权(人脸)
    BiometryType_None,              //支持生物识别但没添加指纹/面容
    BiometryType_TouchID,           //指纹ID
    BiometryType_FaceID,            //面容ID
    BiometryType_Unknown,           //其他
};

@interface BiometricTool : NSObject

@property (nonatomic, assign) BiometryType biometryType;//支持的生物识别类型(指纹/面容)
@property (nonatomic, assign) BOOL hasBindBiometricId;//用户是否开启了生物识别登录
@property (nonatomic, copy) void(^authBlock)(BOOL success, NSString * errorMessage);//识别回调

#pragma mark - 初始化
+ (BiometricTool *)tool;

#pragma mark - 指纹/面容识别
- (void)startAuthenticationWithBlock:(void(^)(BOOL success, NSString * errorMessage))authBlock;

@end

 .m文件

#import "BiometricTool.h"

@implementation BiometricTool

static BiometricTool *__oneTool;

#pragma mark - 初始化
+ (BiometricTool *)tool
{
    static dispatch_once_t oneToken;
    
    dispatch_once(&oneToken, ^{
        __oneTool = [[BiometricTool alloc]init];
    });
    
    return __oneTool;
}

#pragma mark - Getter
- (BiometryType)biometryType
{
    LAContext *context = [[LAContext alloc] init];
    NSError *error = nil;
    
    // 检查设备是否支持生物识别
    if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
        // 支持生物识别且已录入:判断是 Face ID 还是 Touch ID
        if (context.biometryType == LABiometryTypeFaceID) {
                NSLog(@"设备支持 Face ID");
                return BiometryType_FaceID;
                
            } else if (context.biometryType == LABiometryTypeTouchID) {
                NSLog(@"设备支持 Touch ID");
                return BiometryType_TouchID;
            }
            return BiometryType_Unknown;
            
    } else {
        // 不支持生物识别或未录入生物识别
        NSLog(@"设备不支持或未录入生物识别或未授权等code:%ld errorInfo:%@", error.code, error.localizedDescription);
        if (error.code == LAErrorBiometryNotEnrolled) {
            NSLog(@"设备支持生物识别:但用户未录入指纹/面容");
            return BiometryType_None;
            
        }else if (error.code == LAErrorAuthenticationFailed) {
            NSLog(@"设备支持生物识别:但用户拒绝授权(面容)");
            return BiometryType_AuthRefuse;//拒绝后并未返回这个错误码,暂不清楚为何
            
        }else if (error.code == LAErrorBiometryNotAvailable) {
            NSLog(@"设备不支持生物识别");
            return BiometryType_Unsurported;
        }
        return BiometryType_Unsurported;
    }
}


//是否绑定
- (BOOL)hasBindBiometricId
{
    NSString * biometricId = [UserDefaultsFactory getStringForUserWithKey:UDKEY_BIOMETRIC_ID];
    if ([biometricId isNotEmpty]) {
        return YES;
    }
    return NO;
}

#pragma mark - 指纹/面容识别
- (void)startAuthenticationWithBlock:(void(^)(BOOL success, NSString * errorMessage))authBlock
{
    self.authBlock = authBlock;
    
    LAContext *context = [[LAContext alloc] init];
    NSString *reason = self.biometryType == BiometryType_FaceID ? @"通过面容识别验证登录" : @"通过Home键验证指纹登录";

    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:reason reply:^(BOOL success, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (success) {
                NSLog(@"验证成功");
                self.authBlock(YES, @"");
            } else {
                NSLog(@"验证失败: %@", error.localizedDescription);
                [self handleAuthenticationError:error];
            }
        });
    }];
}


//错误校验
- (void)handleAuthenticationError:(NSError *)error
{
    NSString *biometricTypeString = self.biometryType == BiometryType_FaceID ? @"面容ID" : @"指纹ID";
    switch (error.code) {
        case LAErrorAuthenticationFailed:
            NSLog(@"认证失败");
            self.authBlock(NO, @"验证失败");
            break;

        case LAErrorUserCancel:
            NSLog(@"用户取消认证");
            break;

        case LAErrorUserFallback:
            NSLog(@"用户选择使用备用方法:弹窗自动隐藏,显示密码登录");
//            [self showAlternativeLoginMethod];
            break;

        case LAErrorSystemCancel:
            NSLog(@"系统取消认证");
            break;

        case LAErrorPasscodeNotSet:
            NSLog(@"未设置密码");
            self.authBlock(NO, [NSString stringWithFormat:@"您还没有设置密码,请先到系统设置>%@与密码中设置密码", biometricTypeString]);
            break;

        case LAErrorBiometryNotAvailable:
            NSLog(@"生物识别不可用");
            self.authBlock(NO, @"生物识别不可用");
            break;

        case LAErrorBiometryNotEnrolled:
            NSLog(@"未录入生物识别信息");
            self.authBlock(NO, [NSString stringWithFormat:@"您还没有设置%@,请先到系统设置>%@与密码中录入信息",biometricTypeString, biometricTypeString]);
            break;

        case LAErrorBiometryLockout:
            NSLog(@"生物识别被锁定,需要输入密码");
            [self showDevicePasscodeAuthentication];
            break;

        default:
            NSLog(@"未知错误");
            self.authBlock(NO, @"未知错误");
            break;
    }
}

//验证设备密码
- (void)showDevicePasscodeAuthentication {
    LAContext *context = [[LAContext alloc] init];
    NSString *reason = @"验证设备密码";

    [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
           localizedReason:reason
                     reply:^(BOOL success, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (success) {
                NSLog(@"设备密码验证成功");
                self.authBlock(YES, @"");
            } else {
                NSLog(@"设备密码验证失败: %@", error.localizedDescription);
                self.authBlock(NO, @"未知错误");
            }
        });
    }];
}


@end
2、首页调用:检查生物识别状态 - 检查绑定状态 - 询问是否绑定 - 绑定成功 - 存储ID。
//检查生物识别状态
- (void)checkBiometricAuthenticationSupport
{
    if (![UserDefaultsFactory getBoolForPhoneWithKey:UDKEY_NEED_TIP_BIND_BIOMETRIC]) {
        return;
    }
    //获取生物识别类型
    BiometryType biometryType = [BiometricTool tool].biometryType;
    if (biometryType == BiometryType_FaceID || biometryType == BiometryType_TouchID) {
        //判断是已绑定生物识别
        if ([[BiometricTool tool] hasBindBiometricId]) {
            return;
        }
        //未绑定则询问用户是否绑定
        [self askUserToEnableBiometricLogin];
    }
    
}

//自定义开启生物识别登录弹窗
- (void)askUserToEnableBiometricLogin
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"启用生物识别登录" message:[NSString stringWithFormat:@"是否启用%@登录?下次登录时可直接识别登录",[BiometricTool tool].biometryType == BiometryType_FaceID?@"面容":@"指纹"]  preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *enableAction = [UIAlertAction actionWithTitle:@"启用" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //启用并绑定生物识别
        [self loadBindBiometricIdData];
    }];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    
    [alert addAction:enableAction];
    [alert addAction:cancelAction];
    
    [self presentViewController:alert animated:YES completion:nil];
}

//绑定设备
- (void)loadBindBiometricIdData
{
    [Utilities showClearStatus:NetWork_Loading];
    [[Api sharedJsonClient] loadBindBiometricCodeWithParams:nil success:^(id data, BOOL rel, NSString *messageError) {
        if (rel) {
            [Utilities showSuccessStatus:@"开启成功"];
            NSString * biometricId = (NSString *)data;
            //存储到本地
            [UserDefaultsFactory setStringForUserWithKey:UDKEY_BIOMETRIC_ID value:biometricId?:@""];
            
        }else{
            [Utilities showErrorStatus:messageError];
        }
    } failure:^(NSString *messageError) {
        [Utilities showErrorStatus:messageError];
    }];    
}
3、登录页:检查生物识别状态 - 检查绑定状态 - 询问是否使用指纹/面容登录 - 开始指纹/面容识别 - 识别成功 -  登录。
//检查生物识别状态
- (void)checkBiometricAuthenticationSupport
{
    //获取生物识别类型
    BiometryType biometryType = [BiometricTool tool].biometryType;
    if (biometryType == BiometryType_FaceID || biometryType == BiometryType_TouchID) {
        //判断是已绑定生物识别
        if (![[BiometricTool tool] hasBindBiometricId]) {
            return;
        }
        //提醒使用生物识别登录
        YLOpenBiometricCodeView * view = (YLOpenBiometricCodeView *)[YLOpenBiometricCodeView viewWithNib];
        view.imageName = [BiometricTool tool].biometryType == BiometryType_FaceID ? @"biometric_faceid" : @"biometric_touchid";
        NSString * typeString = [BiometricTool tool].biometryType == BiometryType_FaceID?@"面容":@"指纹";
        view.message = [NSString stringWithFormat:@"点击确定进行%@登录?危化镖局仅接收%@ID验证结果,并不收集%@ID信息",typeString,typeString,typeString];
        view.sureTitle = @"确定";
        view.cancelTitle = @"取消";
        view.openBlock = ^{
            //开始生物识别
            [self startBiometriAuthentication];
        };
        view.cancelBlock = ^{
            
        };
        [KeyWindow addSubview:view];
        
    }
}

//开始生物识别
- (void)startBiometriAuthentication{
    //生物识别
    [[BiometricTool tool] startAuthenticationWithBlock:^(BOOL success, NSString * _Nonnull errorMessage) {
        if (success) {
            //验证成功
            [self loadLoginWithBiometricIdData];
        } else {
            //验证失败
            [Utilities showErrorStatus:errorMessage];
        }
    }];
}

- (void)loadLoginWithBiometricIdData
{
    NSDictionary * params = @{
        @"identificationCode":[UserDefaultsFactory getStringForUserWithKey:UDKEY_BIOMETRIC_ID]?:@"",
        @"signOnSource":@"iOS",//注册来源 安卓:ANDROID iOS:iOS h5 :WAP PC:PC
        @"signOnScene":@"APP_SELF",//注册场景
        @"signOnSceneId":@"",//注册场景id(如文章id)
        @"promoterUid":@"",//推广人uuid
    };
    
    [Utilities showClearStatus:NetWork_Loading];
    [[Api sharedJsonClient] loadLoginWithBiometricCodeWithParams:params success:^(id data, BOOL rel, NSString *messageError) {
        if (rel) {
            [Utilities showSuccessStatus:@"登录成功"];
            
            WHBJUserInfo * user = (WHBJUserInfo *)data;
            [self loginSuccessWithUserInfo:user loginType:LoginType_BiometricId];
            
        }else{
            [Utilities showErrorStatus:messageError];
        }
    } failure:^(NSString *messageError) {
        [Utilities showErrorStatus:messageError];
    }];
}
4、个人中心同首页流程。

基于嵌入式Linux/Qt 开发RFID智能仓储指纹管理系统 基于嵌入式Linux/Qt 开发RFID智能仓储指纹管理系统 Qt 是一个用于桌面系统和嵌入式开发的跨平台应用程序框架。它包括一个直观的API和一个丰富的类库,以及用于GUI开发和国际化的集成工具,另外它支持Java™和C++开发。利用它,我们无须重新编写源代码,便可以构建运行在不同桌面操作系统和嵌入式设备上的软件应用程序。 借助Qt,我们可以更快速地构建先进的用户界面:它不仅提供了丰富的标 阅读详情

相关推荐

【原创 附源码】Flutter跨平台开发:Google登录与Firebase Auth深度集成指南

本文详细介绍了如何在Flutter跨平台开发中集成Google登录与Firebase Auth,涵盖从Firebase项目配置到Android/iOS平台专项设置的完整流程。通过实战代码示例,帮助开发者快速实现用户认证功能,解决常见问题,并分享安全最佳实践,提升应用的安全性和用户体验。

weixin_29016315的博客 322

iOS 指纹识别/人脸识别登录(ECDSA 加签)

人脸识别/指纹识别登录(ECDSA签名)

weixin_42050662的博客 3959

集成微信登录功能的友盟SDK实战教程

随着移动互联网的快速发展,第三方登录已成为提升用户注册转化率和优化登录体验的重要手段。微信作为国内最大的社交平台之一,其开放平台提供的OAuth2.0授权机制为开发者提供了安全、便捷的用户身份认证方式。而友盟作为国内领先的移动开发者服务平台,通过封装微信SDK,极大简化了第三方登录的集成流程。本章将系统阐述友盟在移动应用生态中的定位,深入剖析其为何成为接入微信登录的首选中间件,并从技术架构层面解析“应用→友盟SDK→微信SDK→微信开放平台”的调用链路。

weixin_42452483的博客 1288

iOS指纹识别登录流程及实现

转自:仁伯安简书 苹果设计的iOS是以安全性为核心的,不管是沙盒机制,还是代码签名等,他们的最终目的都是为了安全。

Evan 2798

iOS指纹登录(TouchID)集成方案详解

TouchID指纹识别是iPhone 5S设备中增加的一项重大功能.苹果的后续移动设备也相继添加了指纹功能,在实际使用中还是相当方便的,比如快捷登录,快捷支付等等.系统提供了相应框架,使用起来还是比较方便的.使用LAContext对象即可完成指纹识别,提高用户体验. 提示:指纹识别必须用真机测试,并且在iOS8以上系统. TouchID API使用 1.添加头文件 #import 2.判断系统版本 //首先判断版本 if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) { NSLog(@系统版本不支持

第 3 天:Actor 是什么?创建你的第一个游戏对象!

本文详细介绍 Actor 在 Unreal Engine 5 中的作用,并通过 C++ 创建你的第一个游戏对象。你将学习 Actor 的生命周期(BeginPlay、Tick)、如何添加组件(Static Mesh),并让 Actor 在游戏世界中运作。同时提供 常见问题解决方案,助你快速上手 UE5 C++ 开发!🎮 跟随本教程,构建属于你的第一个游戏对象!

m0_37643873的博客 2629

iOS人脸识别Demo

最近用过了支付宝的人脸识别登录,作为一个技术人员应该保持对技术探索、追求的学习心态。这两天就搜集各方资料学习了一下,但好像走了弯路/(ㄒoㄒ)/~~!!!这篇笔记记录一下自己的学习。 1、体验分析 首先思考的应该是人脸识别登录的流程。本人第一次体验到的人脸识别技术的应用当然是支付宝。 支付宝开启人脸登录流程:首先是账号密码登录 ---->  然后在app内根据提示完成信息采集

kangpp的博客 1万+

西工大noj100题python2024第三季21-30

【代码】西工大noj100题python2024第三季21-30。

weixin_70523540的博客 1578

iOS学习—调用Face ID

iOS学习—调用Face ID

qq_43441647的博客 1646

【PLC】三菱plc控件安装 component Movedata had the following error ... Error Number:-119

Windows 10 专业版/企业版本版本号:22H2操作系统内部版本:19045.3448。

少莫千华 8002

第三篇:NVIDIA cuOpt Python API 详解:LP、QP、MILP 建模与求解,附核心术语名词解释

NVIDIA cuOpt是一款GPU加速的优化求解库,支持LP、QP、MILP和路径优化问题。本文详细介绍了其Python API使用方法,包括核心类Problem的变量定义、约束添加、目标设置和求解配置,并提供了术语解释。cuOpt通过GPU并行计算大幅提升大规模优化问题的求解效率,支持多种求解算法和参数配置,适用于需要高性能计算的优化场景。安装方式包含pip和Docker两种,验证安装后即可快速开始建模求解。

算法工程师 236

指纹面容识别登录流程概述

本文主要侧重于,整体的移动端指纹/面容实现用户登录的解决方案逻辑的概述,并不叙述指纹识别技术原理, 或者API具体编码过程等具体技术细节。

锅叔的博客 2011

S7-1200 G2移植旧版本S7-1200程序的具体方法示例

S7-1200 G2移植旧版本S7-1200程序的具体方法示例

Robot_PLC_HMI_Automation 1513

iOS 指纹识别登录功能实现

简介 Touch ID是苹果公司的一种指纹识别技术,从iPhone 5s开始,早已为人们所熟知。 Touch ID不存储用户的任何指纹图像,只保存代表指纹的数字字符。苹果公司提供Touch ID给第三方应用程序使用,程序只会收到认证是否成功的通知,而无法访问 Touch ID 或与已注册指纹相关的数据,这一点对安全而言尤为重要。 现在有很多银行类APP、涉及到支付类的APP都集成了指纹、手势等二次...

记录从移动端、鸿蒙到物联网与AI的完整实战与思考。专注于分享可复用的工程方案与产品思维,尤其深入鸿蒙生态与全栈开发。以十年工程与管理沉淀,为你提供清晰的技术纵深路径。坚信技术的价值在于“贯通”与“落地”。 5072

BevFusion (1): 传感器介绍

激光雷达,也称光学雷达(LIght Detection And Ranging)是激光探测与测距系统的简称,它通过测定传感器发射器与目标物体之间的传播距离,分析目标物体表面的反射能量大小、反射波谱的幅度、频率和相位等信息,从而呈现出目标物精确的三维结构信息。激光雷达是自动驾驶车辆的关键传感器,如下图所示,车辆上方旋转的圆柱体对应就是激光雷达传感器。

@bangbang的博客 1475

芒果YOLOv1改进35:主干Backbone篇之MobileViTv3:全网首发最新 MobileViTv3 系列最强改进版本(三)|轻量化Transformer视觉转换器,简单有效地融合了本地全局

芒果YOLOv1改进35:主干Backbone篇之MobileViTv3:全网首发最新 MobileViTv3 系列最强改进版本(三)|轻量化Transformer视觉转换器,简单有效地融合了本地全局

包括YOLOv5、YOLOv7、YOLOv8等模型改进 417

在 iOS 和 tvOS 上实现 Sign in with Apple 登录功能

Apple 提供的 Sign in with Apple(Apple 登录)是一个既安全又注重隐私的身份验证方式,支持用户通过 Apple ID 登录您的 App。在 iOS 和 tvOS 上,虽然使用场景不同,但底层接口基本一致。本文将详细介绍其 API、状态处理、回调方法,并提供代码示例,帮助大家快速集成。

郭永明的技术专栏 2036

8、音频运行时系统的架构设计

本文深入探讨了音频运行时系统的分层设计及其优势,包括逻辑层和物理层的功能划分。通过分层设计,开发者可以更轻松地管理和优化音频资源,确保其在不同平台上的高效运行。文章还介绍了平台适配与优化、错误处理与调试以及未来发展方向等内容,为开发者提供了宝贵的参考和指导。

juice的博客 461

uni-app人脸和指纹登录

uni-app人脸和指纹登录 最近公司在用uni-app开发项目,有人脸识别和指纹登录的一个需求,研究的过程中也感觉挺有意思的,分享给大家。 官网是这样的示例: <template> <view class="content"> <button type="primary" @click="checkIsSupportSoterAuthentication">检查支持的认证方式</button> <button t

vue+echarts实现中国地图流动效果 4745

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

iOS指纹登录

指纹登录简述 #pragma mark 指纹识别 //指纹识别功能是 iphone 5S之后推出的.SDK是 iOS 8.0 推出! //推出指纹识别功能的目的,是为了简化移动支付环节,占领移动支付市场. - (void)fingerPrintIdentification { // 1️⃣获得当前系统版本号 float version = [UIDevice currentDe

Rephontil的博客 667

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【原创 附源码】Flutter安卓及iOS海外登录--Google登录最详细流程

Flutter 集成google 第三方登录

mumubumaopao的博客 6229

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

React Native for OpenHarmony 实战:FingerprintAuth 指纹认证详解

指纹认证是一种生物识别技术,通过采集用户指纹特征并与预先存储的模板进行比对,从而验证用户身份。指纹采集:使用设备的指纹传感器捕获用户指纹图像特征提取:从指纹图像中提取独特的特征点(如分叉点、端点等)特征比对:将提取的特征与存储的模板进行比对认证决策:根据比对结果决定是否通过认证在OpenHarmony平台上,这些操作由系统级服务处理,应用层通过接口与之交互。

Abin 1022

指纹验证

iOS8之后开发者可以使用指纹验证功能,允许App对用户身份进行验证。 指纹识别只是判断当前用户是否是手机的主人!程序原本的逻辑不会受到任何的干扰! 很简单: 首先: 导入#import <LocalAuthentication/LocalAuthentication.h>,这个库只有真机才有,模拟器没有。 然后:LAContext *context = [[LAContext alloc

Bubble_H的博客 825

iOS生物验证登录的正确姿势(干货)

在开发蓝象安全云的过程中,学习了iOS的生物验证登录技术(包括Touch ID 和 Face ID)。然后对比了一些常用的App的指纹登录功能,发现很多并没有充分利用iOS的安全能力。跟大家分享一下相关的知识,也希望我们使用的App也能够越来越安全。 https://www.jianshu.com/p/803dd8c0743c ...

lxaqycc的博客 683

iOS 指纹解锁

//指纹识别解锁的VC #import @interface KBTouchLoginController : UIViewController @end  实现文件 // // KBTouchLoginController.m // kabao // // Created by wxb on 15/6/30. // Copyright (c)

qq_20578029的博客 763
上一篇: iOS https证书配置闪退问题
下一篇: iOS使用Build Configuration实现多环境切换
devil_0311
博客等级 码龄10年 13粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值