Programmatically Checking if a Passcode Lock is Set Programmatically Checking if a Passcode Lock is Set ios ios

Programmatically Checking if a Passcode Lock is Set


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

Objective-C:

-(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;}

Swift:

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 {        SecItemDelete(attributes)        return true    }    return false}


Since iOS 9, there is a flag LAPolicyDeviceOwnerAuthentication in LocalAuthentication framework.

+ (BOOL)isPasscodeEnabled{    NSError *error = nil;    LAContext *context = [[LAContext alloc] init];    BOOL passcodeEnabled = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];    if(passcodeEnabled) {        NSLog(@"Passcode enabled.");        return YES;    }    NSLog(@"Passcode NOT enabled: %@", error.localizedDescription);    return NO;}

Since iOS 8 there have been another flag for checking if TouchID is enabled:

+ (BOOL)isTouchIdEnabled{    NSError *error = nil;    LAContext *context = [[LAContext alloc] init];    BOOL touchIDEnabled = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];    if(touchIDEnabled) {        NSLog(@"TouchID enabled.");        return YES;    }    NSLog(@"TouchID NOT enabled: %@", error.localizedDescription);    return NO;}


Take a look at the File Protection section on The Application Runtime Environment. File protection requires the user to have passcode lock setting enabled and a valid passcode set. If you your application writes/creates and file, use the NSDataWritingFileProtectionComplete option. If your application doesn't use any files, then create a dummy file and enable the protection.