2018.08.04 22:09 字数 671 阅读 203评论 0喜欢 0

通过LAContext evaluatedPolicyDomainState属性可以获取到当前data类型的指纹信息数据,当指纹增加或者删除,该data就会发生变化,通过记录这个TouchIdData与最新的data做对比就能判断指纹信息是否变更,从而定制app功能。

存在的疑问:

  1. TouchIdData可能为空吗?
  2. 官方文档说明:

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执行并指纹识别通过,这个属性才能有值,否则为空。

  1. TouchIdData能否获取具体的指纹信息?

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.

返回的数据是一个不透明的结构。它可以用来与此属性返回的其他值进行比较,以确定是否更新了授权数据库。然而,变化的性质不能从这些数据中确定。

  1. 在指纹信息没有修改的时候,不同app获取到的TouchIdData是一样的吗?
  2. 实测不同的app,在指纹没有变化的情况下TouchIdData是不一样的。但这个是不能打包票的,如果苹果修改了这部分的算法,返回一个相同值也是有可能的。
  1. 添加一个新指纹,再删除刚添加的那个指纹,TouchIdData相对一轮操作之前变化了吗?
  2. 实测TouchIdData没有变化,也就是说TouchIdData是面向结果的,而不是面向过程的,只要最终结果指纹集合一样,TouchIdData就一样。

代码实现

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

  • deviceOwnerAuthenticationWithBiometrics
  • 这个类型不能弹出密码解锁界面,但能更精准的反馈用户操作的状态:如指纹识别三次失败等。
  • deviceOwnerAuthentication
  • 对识别行为的结果做了简化,无法判断具体状态。但能弹出密码解锁界面。
  • 结合两者可以使指纹解锁做的更友善一点。
  • 最终效果[正常流程]:指纹识别错误三次回调失败->再点击再识别错误两次->弹出密码解锁界面->密码错误5次->锁定1分钟->再输错->锁定五分钟。

代码实现

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

iOS 图像处理(一):获取某一点位置的像素的更多相关文章

  1. C# 图像处理: 获取当前活动窗口句柄,获取窗口大小及位置

    需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllImport( ...

  2. iOS 7.0获取iphone UDID 【转】

    iOS 7.0 iOS 7中苹果再一次无情的封杀mac地址,使用之前的方法获取到的mac地址全部都变成了02:00:00:00:00:00.有问题总的解决啊,于是四处查资料,终于有了思路是否可以使用K ...

  3. 详解OS X和iOS图像处理框架Core Image

    转自:http://www.csdn.net/article/2015-02-13/2823961-core-image 摘要:本 文结合实例详解了OS X和iOS图像处理框架Core Image的使 ...

  4. XAML: 获取元素的位置

    在之前讨论 ListView 滚动相关需求的文章中(UWP: ListView 中与滚动有关的两个需求的实现)曾经提到了获取元素相对位置的方法,即某元素相对另一元素的位置.现将所有相关方法再作整理,并 ...

  5. html5获取用户当前位置

    支持地理定位的浏览器有IE9+.Firefox 3.5+ .Opera 10.6+ .Safari 5+ .Chrome.iOS 版Safari.Android版WebKit. navigator.g ...

  6. ionic 获取手机所在位置

    之前项目中需要使用到定位功能,前边的文章提到的坐标位置是有问题的,是国际坐标,国内的环境使用google地图会出现问题,所以需要使用国内的地图进行坐标解析,因为国内和国外的坐标体系不一致,需要通过转换 ...

  7. iOS根据Url 获取图片尺寸

    iOS根据Url 获取图片尺寸 // 根据图片url获取图片尺寸 +(CGSize)getImageSizeWithURL:(id)imageURL { NSURL* URL = nil; if([i ...

  8. document.compatMode属性和获取鼠标的位置

    document.compatMode属性 document.compatMode用来判断当前浏览器采用的渲染方式. 官方解释: BackCompat:标准兼容模式关闭.CSS1Compat:标准兼容 ...

  9. 李洪强iOS开发-网络新闻获取数据思路回顾

    李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据  1.1 定义类方法返回单例对 ...

随机推荐

  1. Python对文件的解压和压缩

    zipfile: 解压: import os, zipfile serverzip_path = 'D:\\server.zip' serverzip_target_path = 'd:\\2' f ...

  2. c/c++ 字节对齐

    c 字节对齐 概念: 结构体里会包括各种类型的成员,比如int char long等等,它们要占用的空间不同,系统为一个结构体开辟内存空间时,会有2种选择. 第一种:节省空间的方案,以上面的列子来说的 ...

  3. 持续集成-Jenkins安装部署

    1. 安装JDK[java8] 1.1. 软件安装 [yun@mini05 software]# pwd /app/software [yun@mini05 software]# .0_112.tar ...

  4. Linux 小知识翻译 - 「代理服务器」

    这回聊聊「代理服务器」. 在公司里,不通过代理服务器无法连接互联网的,由于代理服务器的原因,有些服务的使用是受到限制的. 有人可能会觉得为什么会存在这种东西?(这里指代理服务器) Proxy本来的意思 ...

  5. jquery.qrcode.js 生成二维码并支持中文的方法

    GitHub地址: https://github.com/jeromeetienne/jquery-qrcode <div class="QR"></div> ...

  6. MySQL高级知识(九)——慢查询日志

    前言:慢查询日志是MySQL提供的一种日志记录,它记录MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的sql语句,该sql语句会被记录到慢查询日志中.慢查询日志 ...

  7. 【ZJOI2017】仙人掌

    [ZJOI2017]仙人掌 参考博客:https://www.cnblogs.com/wfj2048/p/6636028.html 我们先求出\(dfs\)树(就是\(dfs\)一遍),然后问题就变成 ...

  8. 如何学习Linux性能优化?

    如何学习Linux性能优化? 你是否也曾跟我一样,看了很多书.学了很多 Linux 性能工具,但在面对 Linux 性能问题时,还是束手无策?实际上,性能分析和优化始终是大多数软件工程师的一个痛点.但 ...

  9. Python 抖音机器人,论如何在抖音上找到漂亮小姐姐?

    只有想不到,没有做不到,最近抖音风靡好友圈,马上就有技术宅本着“代码改变世界”的理念开始了搞事之路. 需要注意的事,漂亮不漂亮没有明确的界限,每个人都有每个人的审美,只有外表而没有心灵的美也是空洞的. ...

  10. centos7下kubernetes(7.kubernetesScale Up/Down)

    伸缩(Scale up/down)是指在线增加或减少pod副本数量 通过yml文件创建两个nginx的pod 先查看一下nginx的yml文件: 通过kubectl apply -f创建 通过kube ...