- TouchID指纹技术是苹果2013年在iPhone5s(iOS7)上开始应用的。iOS7是不允许开发人员来使用TouchAPI来验证自己的应用程序。
- iOS8开始,苹果陆续开放了Touch ID公共API。TouchID的使用时“本地”的一个验证,框架给我们提供了提示用户进行身份验证的方法。我们可以使用它来认证登录,或授权访问安全敏感信息的应用程序。
TouchID常用的方法(Face ID同TouchID相同)
1. canEvaluatePolicy:error:来判断运行的设备是否支持Touch ID
2. evaluatePolicy:localizedReason:reply:来验证识别的情况,成功或失败(失败的原因以枚举值显示)
Context.biometryType == .faceID //是否人脸识别
1. 判断设置是否支持TouchID
通过canEvaluatePolicy:error:
判断设置是否支持TouchID,返回Bool类型,true代表支持TouchID。
open func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool
LAPolicy: 它是一个枚举,提供两个枚举值,根据需求进行选择
public enum LAPolicy : Int {
//支持iOS8以上系统,使用该设备的TouchID进行验证,当输入TouchID验证5次失败后,TouchID被锁定,只能通过锁屏后解锁设备时输入正确的解锁密码来解锁TouchID。
case deviceOwnerAuthenticationWithBiometrics
//支持iOS9以上系统,使用该设备的TouchID或设备密码进行验证,当输入TouchID验证5次失败后,TouchID被锁定,会触发设备密码页面进行验证。
case deviceOwnerAuthentication
}
Error(LAError结构体): 以下这几个错误要注意以下
/// 该设备支持TouchID,但从来没有注册过指纹,所以指纹登录不能用
public static var touchIDNotEnrolled: LAError.Code { get }
/// 由于未在设备上设置密码,因此无法启动身份验证
public static var passcodeNotSet: LAError.Code { get }
/// 身份验证无法开始,因为设备上没有Touch ID(可能Touch ID坏掉了)
public static var touchIDNotAvailable: LAError.Code { get }
e.g.(示例代码中的枚举值附在文章最后)
// 如果不需要知道错误原因的话可以直接调用canEvaluatePolicy返回Bool值就可以了
static func getTouchIDStatus() -> TouchUseStatus {
let myContext = LAContext()
var authError: NSError?
var status = TouchUseStatus.canNotUse
let isCanEvaluatePolicy = myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
error: &authError)
if isCanEvaluatePolicy {
status = .canUse
} else {
switch authError?.code {
case LAError.touchIDNotEnrolled.rawValue:
status = .canNotUseFingerNotEnrolled
case LAError.passcodeNotSet.rawValue:
status = .canNotUsePasscodeNotSet
case LAError.touchIDNotAvailable.rawValue:
status = .canNotAvailable
default:
status = .canNotUse
}
}
return status
}
2. 获取识别结果
static func authenticateWithTouchID(_ localizedReason: String,
callback: @escaping (Bool, TouchAuthenticationCode) -> Void) {
let touchStatus = getTouchIDStatus()
if touchStatus == .canNotAvailable {
callback(false, TouchAuthenticationCode.invalidContext)
return
}
let myContext = LAContext()
var policyType = LAPolicy.deviceOwnerAuthenticationWithBiometrics
if #available(iOS 9.0, *) {
policyType = LAPolicy.deviceOwnerAuthentication
}
myContext.evaluatePolicy(policyType,
localizedReason: localizedReason) { (isSuccess, error) in
DispatchQueue.main.async {
if isSuccess {
callback(true, TouchAuthenticationCode.sucessed)
} else {
guard let errorOC = error as NSError? else {
callback(false, TouchAuthenticationCode.defalutFailed)
return
}
switch errorOC.code {
case LAError.appCancel.rawValue:
callback(false, TouchAuthenticationCode.appCancel)
case LAError.authenticationFailed.rawValue:
callback(false, TouchAuthenticationCode.failedThree)
case LAError.invalidContext.rawValue:
callback(false, TouchAuthenticationCode.invalidContext)
case LAError.passcodeNotSet.rawValue:
callback(false, TouchAuthenticationCode.passCodeNotSet)
case LAError.systemCancel.rawValue:
callback(false, TouchAuthenticationCode.systemCanceled)
case LAError.touchIDLockout.rawValue:
callback(false, TouchAuthenticationCode.IDLockedOut)
case LAError.touchIDNotAvailable.rawValue:
callback(false, TouchAuthenticationCode.notAvailable)
case LAError.userCancel.rawValue:
callback(false, TouchAuthenticationCode.canceled)
case LAError.userFallback.rawValue:
callback(false, TouchAuthenticationCode.fallBack)
default:
callback(false, TouchAuthenticationCode.defalutFailed)
}
}
}
}
}
附加代码
enum TouchUseStatus {
case canUse //该机器可以使用
case canNotUseFingerNotEnrolled //该机器没有设置指纹
case canNotUsePasscodeNotSet // 密码未设定
case canNotAvailable //机器不支持touchID
case canNotUse //其他情况,应都不能用指纹
}
enum TouchAuthenticationCode {
case sucessed //指纹验证成功
case failedThree //指纹验证失败三次
case failedFive // 指纹验证失败五次,需要调用密码了
case canceled //用户主动取消指纹,点击取消按钮
case fallBack //按了密码按钮,普惠应该不会用到,这个要调回主线程
case systemCanceled //调到了后台,取消授权,如其他应用切入,用户自主
case passCodeNotSet //设备系统未设置密码
case notAvailable //用户未录入指纹
case IDLockedOut //用户连续多次进行Touch ID验证失败,Touch ID被锁,需要用户输入密码解锁,先Touch ID验证密码
case appCancel //用户来了电话之类的,应用被挂起
case invalidContext //之前就已经失效
case defalutFailed //其他失效情况
}
弹出的指纹验证框的两个按钮的标题,可以通过下面的方法修改:
//为空默认显示"Cancel"
context.localizedCancelTitle = "取消"
//为空默认不显示
context.localizedFallbackTitle = "输入密码"