今天咱们主要是说指纹识别传感器,在文章的最后也会顺带说一下距离传感器.
Touch ID 是苹果公司的一种指纹识别技术.Touch ID 不存储用户的任何指纹图像,只保存代表指纹的数字字符.iPhone 的处理器采用了新的高级安全架构,其中有一块名为 Secure Enclave 的区域用以专门保护密码和指纹数据.只有 Secure Enclave 可以访问指纹数据,而且它还把这些数据同处理器和系统隔开,因而这些永远不会被存储在苹果的服务器上,也不会被同步到 iCloud 或其他地方.除了 Touch ID 之外,它们不会被匹配到其他指纹库中.
也就是说,每个 Touch ID 组件只与一个处理器匹配.对于重视安全性的用户来说,这个发现当然是个好消息.不过这让 iPhone 的维修更为复杂,假如你的 Touch ID 不小心坏了,或者拆屏幕的时候不小心碰断了 Touch ID 的某根线缆,或许你就再也无法在你的手机上使用指纹识别功能了.
以下视频截图来自重案组第四季第四集,看上有点玄乎呀.
今天咱们要实现的一个案例需求就是:
使用 touch ID 进行指纹识别
指纹识别错误之后,可以使用 apple ID 的密码进行验证
APP 进入到后台,10 秒之内切回到前台,不做二次验证.
APP 进入到后台,超过 10 秒切回到前台,再次进行指纹验证.
1. 指纹识别传感器的用法介绍
上面听完介绍,感觉好像屌屌的有没有?很高深,可是 iOS 封装的已经非常完善了.我们只需要简单的几个步骤就可以利用好手机最下面这个圆圆的指纹传感器了.
苹果在 iOS8.0 以后开放的 TouchID 接口,是包含在
LocalAuthentication
这个框架里面.我们需要引入头文件.
今天本文都是以 Swfit 为案例,OC 的同学可以进行参考.思路一模一样,语法也几乎一模一样.
插一个私信里面的问题,挺具有代表性的.
宅胖你为什么又写 Swift 又写 OC?Swift 难吗?
1,我感觉现在会写 Swift 的同学基本上都是会写 OC 的.
2,Swift 用了之后,当真会觉得 OC 麻烦很多,各种层面的麻烦.
3,我所写的这些所有的例子里面其实真正用到 Swift 特性的很少,绝大部分情况下都只是简单翻译了一下 OC.
4,Swift 难吗?你看到了,基本语法几乎和 OC 一模一样.只不过 OC 很多都是 NS 开头,Swift 把它去掉了.
别害怕,快上车.看看排行榜,使用 Swift 的开发者数量正在稳定的上升.
好,回到今天的主题.使用指纹传感器,一样需要典型的几步:
导入头文件
LocalAuthentication
判断版本号,必须在 8.0 以上
创建 LAContext 对象,开始验证
好了,就结束了.就这么简单,下面我们就几个重点部分分享一下代码.
然后,敲黑板!!! 真正应用开发中中,几乎没人只是验证一下 touch ID,就不干别的了.验证识别指纹,肯定是为了下一步的业务流程做服务.
既然是这样,验证的结果肯定直接影响到下一步的业务流程,同时也极大的影响了界面的展示.必然会影响到好几个控制器或者好几个 View,极有可能是一对多的关系.
一对多,听上去好耳熟.是不是要暗示点什么?对了.
通知,通知,通知,通知.
嗯.这个不是这篇文章的重点.别忘记了通知.
因为会影响到好几个控制器或者好几个 View,所以,请真心的不要忘记了.
2. Touch ID 指纹识别的代码实现
第一步:导入头文件;
第二步:判断系统是否高于 iOS 8.0 .下面会单独有一章来介绍四种方法,花样判断.啦啦啦啦啦.
第三步:创建 LAContext.这个就是
LocalAuthentication
暴露出来,让开发者使用的类.
第四步:检查 Touch ID 是否可用. 不是判断了系统就好了嘛?当然不是啊.还有很多种情况下,Touch ID 是不好用的.模拟器不可以使用,被替换了 Touch ID,老手机木有这个硬件啦,等等.
第五步:进行识别. 只要识别,就有成功和不成功对不?所以我们还要根据结果进行下一步操作. 成功: 要回到主线程刷新 UI,进行成功后的业务流程. 不成功: 根据返回的错误码,分析错误的原因.
因为多线程咱们说好了是下一个系列要分享的内容,所以这次关于线程的地方我就用伪代码替代了.
3. 判断系统版本号的几种方法
let laContext = LAContext()
//localizedFallbackTitle:验证TouchID时弹出Alert的输入密码按钮的标题
//ocalizedCancelTitle可以设置验证TouchID时弹出Alert的取消按钮的标题(iOS10才有)
laContext.localizedFallbackTitle = "手气不好,输入密码吧"laContext.localizedCancelTitle = "点错了,取消取消"
var requestError: NSError ? =nil
// 检查Touch ID是否可用
if laContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &requestError) {
print("Touch ID可以使用,开始验证") laContext.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "需要验证您的指纹来确认您的身份信息", reply: { (success, error) in
if success {
print("Successful,验证成功")
//回主线程刷新UI
OperationQueue.main.addOperation {
self.successToInterface()
}
} else {
print("Sorry,error = \(String(describing: error))") if let error1 = (error as NSError ? ) {
switch error1.code {
case LAError.userCancel.rawValue:
print("User Cancel")
case LAError.userFallback.rawValue:
print("Wrong touch ID")
case LAError.systemCancel.rawValue:
print("System Cancel")
default:
break;
}
}
self.successView ? .removeFromSuperview()
}
})
} else {
print("模拟器上不能使用,或者其他原因导致touchID不可使用");
}
3.1 系统预留的快速通道 ,推荐使用
3.2 通过 UIDevice 获取版本号,不推荐
if#available(iOS 8.0, *) {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
3.3 通过 ProcessInfo,判断是否高于指定的版本号
// 获取当前字符串类型的版本号信息,最不推荐的一种方法
let sysVersionString = UIDevice.current.systemVersion
3.4 通过系统给定的 Double 类型版本号进行判断
// 获取当前系统版本号.majorVersion:主版本号;minorVersion:次版本号;patchVersion:最后一位小版本号
let systemVersion = OperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)
if ProcessInfo.processInfo.isOperatingSystemAtLeast(systemVersion) {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
4. App 从后台到前台,从前台到后台的动作
// 通过系统给定的Double类型版本号进行判断
if NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0 {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
指纹验证是已经做完了.但是,咱们需求里面是不是还有两条没实现?
APP 进入到后台,10 秒之内切回到前台,不做二次验证. APP 进入到后台,超过 10 秒切回到前台,再次进行指纹验证
接下来我们就要在 AppDelegate.swift 做文章了.
UIApplicationDelegate
有很多方法,我们只说一些跟这次相关的方法.
4.1 App 被加载到内存后首次并且唯一次调用的方法
程序被加载到内存,完成启动,application 对象会自动调用 delegate 的上面这个方法,证明程序已经启动完成.这个方法是首先会被 application 回调的方法,且这个方法在整个程序的生命周期中只会被调用一次.
@available(iOS 3.0, *)
optional public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
如果是手动创建根控制器就要在这里写点神马了,但是这次咱们就是使用最原始的加载,所以这里什么也不用写.
4.2 App 已经进入到后台会被调用的方法
在调用这个方法之前,还会被调用那个叫做 WillResignActive,我们这次不会用到.那个方法是告诉我们,程序将要失去焦点,也就是失去控制.
@available(iOS 4.0, *)
optional public func applicationDidEnterBackground(_ application: UIApplication)
紧接着,就会调用这个 DidEnterBackground 方法.在这个方法里面,我们需要记录一下当前时间.好到时候判断是不是超过了 10 秒钟.
可是这个地方我们并不能直接赋值到 App 里面的某个属性里面,进入后台后,App 将很大程度上不受我们控制,这个数值极有可能会被释放掉.那怎么办?
所以我们要把这个时间存放在其他地方.数据持久化的几种方法还记得吗?
我们在控制台打印一下,方便调试和看到结果.
func applicationDidEnterBackground(_ application: UIApplication) {
enterBackgroundDate = Date()
UserDefaults.standard.set(enterBackgroundDate, forKey: "enterBackgroundDate")
print("进入后台,时间:\(String(describing: enterBackgroundDate))")
}
4.3 App 进入到前台会被调用的方法
无论通过什么途径进入到前台,都会调用这个方法.什么叫做无论什么途径? 当然啦,我们回到 App 有各种情况啊,例如点桌面的应用图标进来了,双击 Home 键从后台切换回来的.
@available(iOS 4.0, *)
optional public func applicationWillEnterForeground(_ application: UIApplication)
在这个里面咱们要干几件事情:
把刚才持久化存储的进入后台的时间取出来
获取当前时间
比较两个时间是不是相差超过 10 秒钟,选择执行相应的操作. 比 10 秒钟长:重新进行指纹验证 短语 10 秒:直接进入
这里需要注意,不管是什么结果,可能都会存在需要修改若干控制器和 View.所以建议如果是这种一对多的情况下,最好使用通知,告诉大家判断的结果.另外,刷新 UI 请回到 UI 线程中.
5. 距离传感器
func applicationWillEnterForeground(_ application: UIApplication) {
print("即将进入前台")
let backgroundTime = UserDefaults.standard.value(forKey: "enterBackgroundDate")
let currentDate = Date()
print("enterBackgroundDate: \(String(describing: backgroundTime)), currentDate : \(currentDate)")
let timeInterval = (backgroundTime as! Date).addingTimeInterval(10)
let result = timeInterval.compare(currentDate)
if result == .orderedAscending {
homeVC.checkTouchID()
} else {
print("进入后台不足10秒,不需要验证")
}
}
我们在打电话的时候,当屏幕靠近自己的大脸 ( ̄ε(# ̄)☆╰╮( ̄▽ ̄///) ,屏幕就会关闭了.当远离障碍物的时候,屏幕就又亮了.这其实就用到了距离传感器.
要想实现距离传感器很简单,很简单就能让 App 支持检测是否有物体靠近了屏幕.但是并不是所有的 iOS 设备都支持,所以使用前和其他传感器一样,我们依然需要判断一下设备是否支持.
今天的分享就到这里啦.代码实在太少了,就不上传了.好不好?
//判断当前设备是否支持距离传感器
if UIDevice.current.isProximityMonitoringEnabled {
// 设备支持距离传感器
NotificationCenter.default.addObserver(self, selector: #selector(xxxxx), name: NSNotification.Name.UIDeviceProximityStateDidChange, object: nil)
//xxxxx 就是当靠近物体的时候需要执行的方法
} else {
// 不支持距离传感器
}
啦啦啦啦.下一个系列,多线程.嗯.
iOS 传感器系列之一:加速传感器 iOS 传感器系列之二:陀螺仪 iOS 传感器系列之三:磁力计 iOS 传感器系列之四:指纹传感器 & 距离传感器
来源: https://juejin.im/post/5a5cb13a6fb9a01ca071d2a3