今天我们主要是说指纹识别传感器,在文章的最后也会顺带说一下距离传感器。swift
Touch ID是苹果公司的一种指纹识别技术。Touch ID不存储用户的任何指纹图像,只保存表明指纹的数字字符。iPhone 的处理器采用了新的高级安全架构,其中有一块名为Secure Enclave
的区域用以专门保护密码和指纹数据。只有Secure Enclave
能够访问指纹数据,并且它还把这些数据同处理器和系统隔开,于是这些永远不会被存储在苹果的服务器上,也不会被同步到iCloud或其余地方。除了Touch ID以外,它们不会被匹配到其余指纹库中。安全
也就是说,每一个Touch ID组件只与一个处理器匹配。对于重视安全性的用户来讲,这个发现固然是个好消息。不过这让iPhone的维修更为复杂,假如你的Touch ID不当心坏了,或者拆屏幕的时候不当心碰断了Touch ID的某根线缆,或许你就再也没法在你的手机上使用指纹识别功能了。bash
如下视频截图来自重案组第四季第四集,看上有点玄乎呀。服务器
今天我们要实现的一个案例需求就是:多线程
上面听完介绍,感受好像屌屌的有没有?很高深,但是iOS封装的已经很是完善了。咱们只须要简单的几个步骤就能够利用好手机最下面这个圆圆的指纹传感器了。架构
苹果在iOS8.0之后开放的TouchID接口,是包含在LocalAuthentication
这个框架里面。咱们须要引入头文件。app
今天本文都是以Swfit为案例,OC的同窗能够进行参考。思路如出一辙,语法也几乎如出一辙。框架
插一个私信里面的问题,挺具备表明性的。post
宅胖你为何又写Swift又写OC?Swift难吗?ui
1,我感受如今会写Swift的同窗基本上都是会写OC的。
2,Swift用了以后,当真会以为OC麻烦不少,各类层面的麻烦。
3,我所写的这些全部的例子里面其实真正用到Swift特性的不多,绝大部分状况下都只是简单翻译了一下OC。
4,Swift难吗?你看到了,基本语法几乎和OC如出一辙。只不过OC不少都是NS开头,Swift把它去掉了。
别惧怕,快上车。看看排行榜,使用Swift的开发者数量正在稳定的上升。
好,回到今天的主题。使用指纹传感器,同样须要典型的几步:
LocalAuthentication
好了,就结束了。就这么简单,下面咱们就几个重点部分分享一下代码。
而后,敲黑板!!!真正应用开发中中,几乎没人只是验证一下touch ID,就不干别的了。验证识别指纹,确定是为了下一步的业务流程作服务。
既然是这样,验证的结果确定直接影响到下一步的业务流程,同时也极大的影响了界面的展现。必然会影响到好几个控制器或者好几个View,极有多是一对多的关系。
一对多
,听上去好耳熟。是否是要暗示点什么?对了。通知,通知,通知,通知。
嗯。这个不是这篇文章的重点。别忘记了通知。
由于会影响到好几个控制器或者好几个View,因此,请真心的不要忘记了。
LAContext
。这个就是LocalAuthentication
暴露出来,让开发者使用的类。由于多线程我们说好了是下一个系列要分享的内容,因此此次关于线程的地方我就用伪代码替代了。
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不可以使用");
}
复制代码
if #available(iOS 8.0, *) {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
复制代码
// 获取当前字符串类型的版本号信息,最不推荐的一种方法
let sysVersionString = UIDevice.current.systemVersion
复制代码
// 获取当前系统版本号。majorVersion:主版本号;minorVersion:次版本号;patchVersion:最后一位小版本号
let systemVersion = OperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)
if ProcessInfo.processInfo.isOperatingSystemAtLeast(systemVersion) {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
复制代码
// 经过系统给定的Double类型版本号进行判断
if NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0 {
//系统版本高于8.0
} else {
//系统版本低于8.0
}
复制代码
指纹验证是已经作完了。可是,我们需求里面是否是还有两条没实现?
APP进入到后台,10秒以内切回到前台,不作二次验证。 APP进入到后台,超过10秒切回到前台,再次进行指纹验证
接下来咱们就要在AppDelegate.swift
作文章了。
UIApplicationDelegate
有不少方法,咱们只说一些跟此次相关的方法。
@available(iOS 3.0, *)
optional public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
复制代码
程序被加载到内存,完成启动,application对象会自动调用delegate的上面这个方法,证实程序已经启动完成。这个方法是首先会被application回调的方法,且这个方法在整个程序的生命周期中只会被调用一次。
若是是手动建立根控制器就要在这里写点神马了,可是此次我们就是使用最原始的加载,因此这里什么也不用写。
@available(iOS 4.0, *)
optional public func applicationDidEnterBackground(_ application: UIApplication)
复制代码
在调用这个方法以前,还会被调用那个叫作WillResignActive
,咱们此次不会用到。那个方法是告诉咱们,程序将要失去焦点,也就是失去控制。
紧接着,就会调用这个DidEnterBackground
方法。在这个方法里面,咱们须要记录一下当前时间。好到时候判断是否是超过了10秒钟。
但是这个地方咱们并不能直接赋值到App里面的某个属性里面,进入后台后,App将很大程度上不受咱们控制,这个数值极有可能会被释放掉。那怎么办?
因此咱们要把这个时间存放在其余地方。数据持久化的几种方法还记得吗?
func applicationDidEnterBackground(_ application: UIApplication) {
enterBackgroundDate = Date()
UserDefaults.standard.set(enterBackgroundDate, forKey: "enterBackgroundDate")
print("进入后台,时间:\(String(describing: enterBackgroundDate))")
}
复制代码
咱们在控制台打印一下,方便调试和看到结果。
@available(iOS 4.0, *)
optional public func applicationWillEnterForeground(_ application: UIApplication)
复制代码
不管经过什么途径进入到前台,都会调用这个方法。什么叫作不管什么途径? 固然啦,咱们回到App有各类状况啊,例如点桌面的应用图标进来了,双击Home键从后台切换回来的。
在这个里面我们要干几件事情:
这里须要注意,不论是什么结果,可能都会存在须要修改若干控制器和View。因此建议若是是这种一对多的状况下,最好使用通知,告诉你们判断的结果。另外,刷新UI请回到UI线程中。
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 {
// 不支持距离传感器
}
复制代码
今天的分享就到这里啦。代码实在太少了,就不上传了。好很差?
啦啦啦啦。下一个系列,多线程。嗯。