Simon Simon - 1 year ago 110
iOS Question

Can I check whether the user has set a passcode?

We have an app that stores sensitive data. We've enabled file protection, but that only has an effect if the user has set a passcode. If the user hasn't set a passcode, we need to show an alert telling the user to do that, and then not to load the rest of the app.

Basically we're in the exact situation as in this question, and my question is exactly their question. But the accepted answer there is "enable file protection", which is not an answer to that question, or to this one; I'm already enabling file protection and it doesn't tell me whether they've set a passcode or not.

So is it possible to check, and if so, how? Ideally we'd like to check whether the user has set a long passcode or a simple one, and if they've only set a simple one we would warn them to set a proper one.


With iOS 8, there is now a way to check that the user has a passcode set. This code will crash on iOS 7.


-(BOOL) deviceHasPasscode {
    NSData* secret = [@"Device has passcode set?" dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *attributes = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: @"LocalDeviceServices",  (__bridge id)kSecAttrAccount: @"NoAccount", (__bridge id)kSecValueData: secret, (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly };

    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
    if (status == errSecSuccess) { // item added okay, passcode has been set            
        SecItemDelete((__bridge CFDictionaryRef)attributes);

        return true;

    return false;


func deviceHasPasscode() -> Bool {
    let secret = "Device has passcode set?".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
    let attributes = [kSecClass as String:kSecClassGenericPassword, kSecAttrService as String:"LocalDeviceServices", kSecAttrAccount as String:"NoAccount", kSecValueData as String:secret!, kSecAttrAccessible as String:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly]

    let status = SecItemAdd(attributes, nil)
    if status == 0 {
        return true

    return false