标签:domain 不同的 sea 类型 判断 tab 更新 ati current
2018.08.04 22:09 字数 671 阅读 203评论 0喜欢 0
通过LAContext evaluatedPolicyDomainState属性可以获取到当前data类型的指纹信息数据,当指纹增加或者删除,该data就会发生变化,通过记录这个TouchIdData与最新的data做对比就能判断指纹信息是否变更,从而定制app功能。
存在的疑问:
Discussion
This property returns a value only when the canEvaluatePolicy(:error:) method succeeds for a biometric policy or the evaluatePolicy(:localizedReason:reply:) method is called and a successful biometric authentication is performed. Otherwise, nil is returned.
只有当canEvaluatePolicy方法执行并返回YES或者evaluatePolicy执行并指纹识别通过,这个属性才能有值,否则为空。
The returned data is an opaque structure. It can be used to compare with other values returned by this property to determine whether the authorized database has been updated. However, the nature of the change cannot be determined from this data.
返回的数据是一个不透明的结构。它可以用来与此属性返回的其他值进行比较,以确定是否更新了授权数据库。然而,变化的性质不能从这些数据中确定。
代码实现
static var IDENTIFY:String? = nil
static let SERVICE = "TOUCHID_SERVICE"
static let ACCOUNT_PREFIX = "TOUCHID_PERFIX"
open class func setCurrentTouchIdDataIdentity(identity:String )
{
//设定当前身份用于存储data
TouchIdManager.IDENTIFY = identity
}
//获取当前时刻的data
class func currentOriTouchIdData() -> Data?{
let context = LAContext()
var error:NSError? = nil;
//先使用canEvaluatePolicy方法进行评估
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
return context.evaluatedPolicyDomainState
}
print("errorMsg:" + self.errorMessageForFails(errorCode:(error?.code)! ))
return nil
}
//使用keychain保存当前身份的data
open class func setCurrentIdentityTouchIdData()-> Bool
{
if self.currentTouchIdDataIdentity() == nil
{
return false;
}
else
{
if self.currentOriTouchIdData() != nil
{
//storage by keychain
SAMKeychain.setPasswordData(self.currentOriTouchIdData()!, forService:SERVICE, account: ACCOUNT_PREFIX + self.currentTouchIdDataIdentity()!)
return true;
}
else
{
return false;
}
}
}
//获取当前身份的上一次存储的data,用于对比
class func currentIdentityTouchIdData()->Data?
{
guard (self.currentTouchIdDataIdentity() != nil) else {
return nil;
}
return SAMKeychain.passwordData(forService: TouchIdManager.SERVICE, account: TouchIdManager.ACCOUNT_PREFIX + self.currentTouchIdDataIdentity()!)
}
//检测以这个身份设置开始到当前时刻指纹信息是否变更
open class func touchIdInfoDidChange()->Bool
{
let data = self.currentOriTouchIdData()
if data == nil && self.isErrorTouchIDLockout() {
//lock after unlock failed many times,and the fingerprint is not changed.
return false
}
else
{
let oldData = self.currentIdentityTouchIdData()
if oldData == nil
{
//never set
return false
}
else if oldData == data
{
//not change
return false
}
else
{
return true
}
}
}
//检测当前是否为biometryLockout状态
class func isErrorTouchIDLockout()->Bool
{
let context = LAContext()
var error:NSError?
context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error)
guard error != nil else {
return false
}
if error!.code == LAError.biometryLockout.rawValue {
return true
}
else
{
return false
}
}
指纹识别的两种LAPolicy:
代码实现
open class func showTouchId(title:String,fallbackTitle:String?, fallbackBlock:TouchIdFallBackBlokc?,resultBlock:TouchIdResultBlock?)
{
let context = LAContext();
context.localizedFallbackTitle = fallbackTitle
var useableError:NSError?
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &useableError) {
context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: title) { (success, error) in
DispatchQueue.main.async {
if success
{
if resultBlock != nil
{
resultBlock!(true,success,error)
}
}
else
{
guard let error = error else
{
return;
}
print("errorMsg:" + self.errorMessageForFails(errorCode: error._code))
if error._code == LAError.userFallback.rawValue
{
if fallbackBlock != nil
{
fallbackBlock!()
}
}
else if error._code == LAError.biometryLockout.rawValue
{
//try to show password interface
self.tryShowTouchIdOrPwdInterface(title: title, resultBlock: resultBlock)
}
else
{
if resultBlock != nil
{
resultBlock!(true,success,error)
}
}
}
}
}
}
else
{
print("errorMsg:" + self.errorMessageForFails(errorCode:(useableError?.code)! ))
if useableError?.code == LAError.biometryLockout.rawValue
{
//try to show password interface
self.tryShowTouchIdOrPwdInterface(title: title, resultBlock: resultBlock)
}
else
{
if resultBlock != nil
{
resultBlock!(false,false,useableError)
}
}
}
}
class func tryShowTouchIdOrPwdInterface(title:String,resultBlock:TouchIdResultBlock?)
{
let context = LAContext();
context.localizedFallbackTitle = ""
var useableError:NSError?
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthentication, error: &useableError) {
context.evaluatePolicy(LAPolicy.deviceOwnerAuthentication, localizedReason: title) { (success, error) in
DispatchQueue.main.async {
if resultBlock != nil
{
resultBlock!(true,success,error)
}
}
guard let error = error else
{
return;
}
print("errorMsg:" + self.errorMessageForFails(errorCode: error._code))
}
}
else
{
print("errorMsg:" + self.errorMessageForFails(errorCode:(useableError?.code)! ))
if resultBlock != nil
{
resultBlock!(false,false,useableError)
}
}
}
测试demo:
swift:https://github.com/zmubai/TouchIDTest-swift
object-c:https://github.com/zmubai/TouchIDTest-OC
标签:domain 不同的 sea 类型 判断 tab 更新 ati current
原文地址:https://www.cnblogs.com/sundaysgarden/p/10316003.html