解决使用Touch ID API在回调时界面“长时间卡住”的问题

  Touch ID是iOS8上新公开的API,关于详细介绍和用法可以看CocoaChina的这两篇文章:,在此篇文章中不在赘述。

  我在app中需要的效果是如果touch id验证通过,则页面push到下一个viewController,否则本视图的数字密码输入框becomeFirstResponder。研究过touch id的人应该知道,这段代码大概会这么实现:

 1   LAContext *context = [[LAContext alloc] init];
 2     NSError *error;
 3
 4     BOOL canUse = [context canEvaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
 5     if (canUse) {
 6         [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
 7                 localizedReason:@"使用touch ID来打开"  8                           reply:^(BOOL success, NSError *authenticationError) {
 9                                   if (success) {
10                                      //push视图
11                                   } else {
12                                      //弹出输入框
13                                   }
14                           }];
15     }

  我一开始确实也是这么写的,结果发现,验证完成后,无论是否成功,界面都会卡了5秒以上才会进行下一步。这显然不科学啊,然后仔细看了一下这个方法的说明,在网上搜索一番,最后在stackoverflow的帮助下才弄清。一晚上时间的成果。。。。

  我们先看一下- (void)evaluatePolicy:(LAPolicy)policy localizedReason:(NSString *)localizedReason reply:(void (^)(BOOL success, NSError *error))reply这个方法对最后一个参数reply这个block的描述:

reply

Reply block that is executed when policy evaluation finishes. This block is evaluated on a private queue internal to the framework in an unspecified threading context. You must not call canEvaluatePolicy:error: in this block, because doing so could lead to deadlock.

注意第二句话,大概意思是(英语不是很好,轻喷):这个block会在framework内部的一个私有队列中进行判断,而这个framework更是在一个不确定的线程中。。。说简单点就是,这个block就不在主线程中执行啊有木有!刷新界面的操作必须要放在主线程中啊有木有!意识到这点再回过头来看网上的那些讲解包括官方Demo,都只是在reply中NSLog啊、println啊、给变量赋值啊,让我抄的时候完全忽视线程这个东西。。。。

  接下来就容易解决了,要不就定义一个是否验证成功的BOOL flag,在reply里判断赋值,然后紧跟着在方法外判断flag来进行下一步;要不就直接点,把reply里的操作放到主线程里,形如

 1 [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
 2                 localizedReason:@"使用touch ID来打开"  3                           reply:^(BOOL success, NSError *authenticationError) {
 4                               dispatch_async(dispatch_get_main_queue(), ^{
 5                                   if (success) {
 6                                       //push
 7                                   } else {
 8                                       //弹出输入框
 9                                   }
10                               });
11                           }];
时间: 2024-08-29 13:12:28

解决使用Touch ID API在回调时界面“长时间卡住”的问题的相关文章

安装npm install时,长时间停留在fetchMetadata: sill 解决方法——换npm的源

安装npm install时,长时间停留在fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetch处, 此处需要在对应的URL处下载一些文件,只要网络稳定,一般花不了多长时间 但是,最近两次操作都是长时间停留,在网上找了一些原因,才发现后面的URL地址可以由淘宝的源代替,原来是资源问题导致的 方法如下: 更换成淘宝的源 npm config set registry https://registry.

安装npm install时,长时间停留在fetchMetadata的解决方法

安装npm install时,长时间停留在fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetch处, 此处需要在对应的URL处下载一些文件,只要网络稳定,一般花不了多长时间 但是,最近两次操作都是长时间停留,在网上找了一些原因,才发现后面的URL地址可以由淘宝的源代替,原来是资源问题导致的 方法如下: 更换成淘宝的源 npm config set registry https://registry.

安装npm install时,长时间停留在fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetch处

安装npm install时,长时间停留在fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetch处, 此处需要在对应的URL处下载一些文件,只要网络稳定,一般花不了多长时间 但是,最近两次操作都是长时间停留,在网上找了一些原因,才发现后面的URL地址可以由淘宝的源代替,原来是资源问题导致的 方法如下: 更换成淘宝的源 npm config set registry https://registry.

Git Compare with base,比较大文件时,长时间等待,无法加载

问题 当使用Git比较一个大文件(几十兆数量级)版本见差异时,会一直等待加载,且内存消耗很大,导致其他进程很难执行.任务管理器中,可以看到此时的TortoiseGitMerge吃掉3G左右的内存. ? 原因 文件太大,加载很慢. ? 解决方法 其实,我们在使用[Compare with base]这个功能时,想要比较版本间文件的不同之处,因此,无需加载整个文件内容,只显示出文件中的不同内容即可.设置如下: 先使用[Compare with base]比较一个小文件,否则,肯能要等很长时间去加载一

访问国外技术网站时,长时间无法显示内容的解决办法

观察网站加载,可以看到在浏览器加载时,左下角显示:等待 fonts.googleapis.com...  或者 ajax.googleapis.com... 事实上,这些字体对网站内容并没有大的影响,浏览器会使用默认的字体,不要也罢. 解决办法: 修改HOSTS文件,增加  127.0.0.1  fonts.googleapis.com  127.0.0.1  ajax.googleapis.com 将其域名解析映射到本机即可.

关于Tomcat启动时,长时间停在Initializing Spring root webApplicationContext处的原因

1.大家肯定经常会遇到这样的问题,以前启动tomcat都不会出问题.现在一起动就会卡到Initializing Spring root webApplicationContext处,tomcat会报连接超时错误. 然后,发现改了timeout,之后还是不行,这你就应该看看是不是数据库连接出了问题.

iOS 8 中如何集成 Touch ID 功能

2013年9月,苹果为当时发布的最新iPhone产品配备了一系列硬件升级方案.在iPhone 5s当中,最具创新特性的机制无疑要数围绕Home按钮设计的超薄金属圈,也就是被称为Touch ID的指纹传感器.开发人员随后开始纷纷将其API作为突破口,希望能在自己的应用程序中引入这一最新功能.如今一年已经过去,iOS 8提供的新型框架则让开发者能够更加得心应手地使用这套指纹传感装置. 这套Local Authentication框架能够轻松实现用户身份验证,大家可以利用它来完成应用程序的登录机制或者

苹果5S指纹扫描识别传感器Touch ID有利于iPhone的安全性

iPhone5S新增的指纹扫描识别传感器 Touch ID,黑客花了大量的时间表明指纹验证是可以被破解的.即使它可能被黑客攻击,对iPhone5S的安全性而言,仍然具有极大的好处. 为什么一个容易被破解的生物特征验证方法对iPhone5S的安全性具有极大的好处呢?抛开Touch ID本身的优势和弱点,它主要是增强密码保护,并简化认证.从消费者的角度来看,Touch ID使许多消费者都懒得输入密码,但是使用Touch ID需同时设置一个密码.有一些安全总比没有安全要好些,Touch ID鼓励人们使

iOS用户数据安全:Keychain、Touch ID以及1Password

使用登录界面来保护APP用户数据是很好的方法--你可以使用Keychain(内嵌在iOS里的)来确保用户数据的安全.不过苹果现在使用Touch ID提供了另外一层保护,该功能适用于iPhone5.iPhone6. iPhone 6+.iPad Air2以及iPad mini 3. 如果这些都还不够,可以尝试iOS 8引入的扩展,你甚至可以使用AgileBits开发的1Password app来整合登录信息的存储和获取.这一切都要感谢AgileBits团队开发者开源了他们的扩展包.这样你就可以把管