以编程方式检测iOS是否启用了密码

32

我觉得直接在我的应用程序中设置密码可能会要求用户输入两次密码(一次是设备密码,一次是应用程序密码),所以我想通过以下方式来避免这个问题:

if (device has passcode)
    continue into my app
else
    make user enter my app passcode

我不想设置设备密码,也不想强制启用屏幕锁定,不加密任何东西——我真正想要的只是一个API来检测设备是否启用了密码。类似这样:

BOOL notReally = [UIDevice isUserSlightlyMoreSecureBecauseTheySetDeviceLockOn];

或许如果我感觉幸运的话:

BOOL isPasscodeEnabled = [UIDevice isPasscodeEnabled];
BOOL isSimplePasscode = [UIDevice isSimplePasscode];
NSInteger minutes = [UIDevice requirePasscodeAfter];

根据这个问题(但已经几年过去了)我猜不出来:" programmatically check for iPhone's Passcode in settings bundle" 或者这可能是答案;"Lock Unlock events iphone" 这并不完全是我想要的,但在“事后”可能有用。


1
什么都没有改变。仍然无法完成。 - rmaddy
2
不用担心。在你的应用程序中给用户设置密码选项。让用户决定是否要使用它,无论用户是否有设备级别的密码。 - rmaddy
2
UIApplication.protectedDataAvailable 能不能满足你的需求呢?https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006728-CH3-SW84 - Krumelur
如果我没有设置密码,则这对我来说是正确的,如果我设置了密码,则也是正确的。 - jimpic
3个回答

49

针对 iOS 9 及以上版本,您可以使用新的LocalAuthentication类进行检测,它可以在模拟器和设备上正常工作:

import LocalAuthentication

private func devicePasscodeSet() -> Bool {
    //checks to see if devices (not apps) passcode has been set
    return LAContext().canEvaluatePolicy(.deviceOwnerAuthentication, error: nil)
  }

32

更新

从iOS 9开始,您可以使用LocalAuthentication.framework实现此目的。如果针对iOS 9+ ,请阅读此处的评论或查看此答案

如果您仍需要面向iOS 8,那么请继续阅读 :)


从iOS 8开始,您可以!
我编写了一个简单的分类,用于轻松检查状态:https://github.com/liamnichols/UIDevice-PasscodeStatus

它是如何工作的

该分类通过使用添加到iOS 8中的Security.Framework的新访问控制特性来工作。 它尝试使用kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly保护级别向关键链添加项。

文档说明如下:

只有在设备解锁时才能访问项目数据。只有在设备上设置密码时才能使用此类。建议仅对前台应用程序可访问的项目使用此属性。带有此属性的项永远不会迁移到新设备,因此,在将备份还原到新设备后,这些项目将丢失。 在没有密码的设备上无法存储任何项。禁用设备密码将导致删除此类中的所有项目。

由于这个原因,当您使用此级别的访问控制向关键链添加或读取项时,会返回错误。如果我们看到这个错误,passcodeStatus将返回为LNPasscodeStatusDisabled

如果我们能够以这种访问控制的级别成功读取或写入钥匙串,则返回LNPasscodeStatusEnabled

如果设备不支持或钥匙串出现非相关错误,则返回LNPasscodeStatusUnknown


以前的版本有没有办法呢? - puntofisso
很抱歉,@puntofisso,不行。 - liamnichols
@Federico 我没有测试过,所以我不知道... 显然它在扩展中不起作用,但如果iOS/watchOS API相同,那么我不明白为什么不能使用... 如果实际手表启用了密码而不是iPhone,则会出现这种情况。 - liamnichols
我认为它在IOS9上不起作用,当它被启用时,代码运行良好,但当它未启用时,始终是未知的... - Kasas

1
我不知道有直接获取此信息的方法,但我认为您可以通过使用苹果对磁盘加密支持的副作用来实现您想要的结果。请参见使用磁盘加密保护数据以获取详细信息。
然而,这是一种黑客行为而不是设计行为,而且有一些边缘情况它无法意识到。我建议将此功能作为用户明确控制而不是启用启发式算法的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接