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.