iOS传感器:App先后台切换后,获取敏感信息使用touch ID进行校验

今天我们主要是说指纹识别传感器,在文章的最后也会顺带说一下距离传感器。swift

Touch ID是苹果公司的一种指纹识别技术。Touch ID不存储用户的任何指纹图像,只保存表明指纹的数字字符。iPhone 的处理器采用了新的高级安全架构,其中有一块名为Secure Enclave的区域用以专门保护密码和指纹数据。只有Secure Enclave能够访问指纹数据,并且它还把这些数据同处理器和系统隔开,于是这些永远不会被存储在苹果的服务器上,也不会被同步到iCloud或其余地方。除了Touch ID以外,它们不会被匹配到其余指纹库中。安全

也就是说,每一个Touch ID组件只与一个处理器匹配。对于重视安全性的用户来讲,这个发现固然是个好消息。不过这让iPhone的维修更为复杂,假如你的Touch ID不当心坏了,或者拆屏幕的时候不当心碰断了Touch ID的某根线缆,或许你就再也没法在你的手机上使用指纹识别功能了。bash

如下视频截图来自重案组第四季第四集,看上有点玄乎呀。服务器

重案组S4.png

重案组S4.png

重案组S4.png

今天我们要实现的一个案例需求就是:多线程

  1. 使用touch ID进行指纹识别
  2. 指纹识别错误以后,可使用apple ID的密码进行验证
  3. APP进入到后台,10秒以内切回到前台,不作二次验证。
  4. APP进入到后台,超过10秒切回到前台,再次进行指纹验证。

1. 指纹识别传感器的用法介绍

上面听完介绍,感受好像屌屌的有没有?很高深,但是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的开发者数量正在稳定的上升。

好,回到今天的主题。使用指纹传感器,同样须要典型的几步:

  1. 导入头文件LocalAuthentication
  2. 判断版本号,必须在8.0以上
  3. 建立LAContext对象,开始验证

好了,就结束了。就这么简单,下面咱们就几个重点部分分享一下代码。

而后,敲黑板!!!真正应用开发中中,几乎没人只是验证一下touch ID,就不干别的了。验证识别指纹,确定是为了下一步的业务流程作服务。

既然是这样,验证的结果确定直接影响到下一步的业务流程,同时也极大的影响了界面的展现。必然会影响到好几个控制器或者好几个View,极有多是一对多的关系

一对多,听上去好耳熟。是否是要暗示点什么?对了。通知,通知,通知,通知。嗯。这个不是这篇文章的重点。别忘记了通知。

由于会影响到好几个控制器或者好几个View,因此,请真心的不要忘记了。

2. Touch ID指纹识别的代码实现

  • 第一步:导入头文件;
  • 第二步:判断系统是否高于iOS 8.0 。下面会单独有一章来介绍四种方法,花样判断。啦啦啦啦啦。
  • 第三步:建立LAContext。这个就是LocalAuthentication暴露出来,让开发者使用的类。
  • 第四步:检查Touch ID是否可用。 不是判断了系统就行了嘛?固然不是啊。还有不少种状况下,Touch ID是很差用的。模拟器不可使用,被替换了Touch ID,老手机木有这个硬件啦,等等。
  • 第五步:进行识别。 只要识别,就有成功和不成功对不?因此咱们还要根据结果进行下一步操做。 成功: 要回到主线程刷新UI,进行成功后的业务流程。 不成功: 根据返回的错误码,分析错误的缘由。

由于多线程我们说好了是下一个系列要分享的内容,因此此次关于线程的地方我就用伪代码替代了。

image.png

image.png

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. 判断系统版本号的几种方法

3.1 系统预留的快速通道 ,推荐使用

if #available(iOS 8.0, *) {
    //系统版本高于8.0
} else {
    //系统版本低于8.0
}
复制代码

3.2 经过UIDevice获取版本号,不推荐

//        获取当前字符串类型的版本号信息,最不推荐的一种方法
        let sysVersionString = UIDevice.current.systemVersion
复制代码

3.3 经过ProcessInfo,判断是否高于指定的版本号

//        获取当前系统版本号。majorVersion:主版本号;minorVersion:次版本号;patchVersion:最后一位小版本号
       let systemVersion =  OperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)
        
        if ProcessInfo.processInfo.isOperatingSystemAtLeast(systemVersion) {
            //系统版本高于8.0
        } else {
            //系统版本低于8.0
        }
复制代码

3.4 经过系统给定的Double类型版本号进行判断

//        经过系统给定的Double类型版本号进行判断
        if NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0 {
            //系统版本高于8.0
        } else {
            //系统版本低于8.0
        }
复制代码

4. App从后台到前台,从前台到后台的动做

指纹验证是已经作完了。可是,我们需求里面是否是还有两条没实现?

APP进入到后台,10秒以内切回到前台,不作二次验证。 APP进入到后台,超过10秒切回到前台,再次进行指纹验证

接下来咱们就要在AppDelegate.swift作文章了。

UIApplicationDelegate有不少方法,咱们只说一些跟此次相关的方法。

4.1 App被加载到内存后首次而且惟一次调用的方法

@available(iOS 3.0, *)
optional public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
复制代码

程序被加载到内存,完成启动,application对象会自动调用delegate的上面这个方法,证实程序已经启动完成。这个方法是首先会被application回调的方法,且这个方法在整个程序的生命周期中只会被调用一次。

若是是手动建立根控制器就要在这里写点神马了,可是此次我们就是使用最原始的加载,因此这里什么也不用写。

4.2 App已经进入到后台会被调用的方法

@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))")
    
}
复制代码

咱们在控制台打印一下,方便调试和看到结果。

4.3 App进入到前台会被调用的方法

@available(iOS 4.0, *)
optional public func applicationWillEnterForeground(_ application: UIApplication)
复制代码

不管经过什么途径进入到前台,都会调用这个方法。什么叫作不管什么途径? 固然啦,咱们回到App有各类状况啊,例如点桌面的应用图标进来了,双击Home键从后台切换回来的。

在这个里面我们要干几件事情:

  1. 把刚才持久化存储的进入后台的时间取出来
  2. 获取当前时间
  3. 比较两个时间是否是相差超过10秒钟,选择执行相应的操做。 比10秒钟长:从新进行指纹验证 短语10秒:直接进入

这里须要注意,不论是什么结果,可能都会存在须要修改若干控制器和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秒,不须要验证")
    }
    
}
复制代码

5. 距离传感器

咱们在打电话的时候,当屏幕靠近本身的大脸( ̄ε(# ̄)☆╰╮( ̄▽ ̄///) ,屏幕就会关闭了。当远离障碍物的时候,屏幕就又亮了。这其实就用到了距离传感器。

要想实现距离传感器很简单,很简单就能让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传感器系列之四:指纹传感器&距离传感器

相关文章
相关标签/搜索