canUseAccessControl()
Whether an item can be written with an access control on this device now, and why not when it can't. Ask before you offer Face ID in the UI; it never shows a prompt.
import { canUseAccessControl } from '@apexnative/keychain';
A write of an item whose protection the device can't give fails, and never stores the item with less. canUseAccessControl asks the same question first, without writing anything: a switch "Sign in with Face ID" shows only when the answer is available, and the reason says what to tell the user otherwise.
Usage
import { AccessControl, canUseAccessControl } from '@apexnative/keychain';
const check = await canUseAccessControl(AccessControl.BiometryCurrentSet);
if (check.available) {
showBiometricSwitch();
} else if (check.reason === 'notEnrolled') {
showHint('Add a face or a fingerprint in Settings to sign in with it.');
} else {
hideBiometricSwitch(); // 'noHardware', 'passcodeNotSet' or 'unsupportedOS'
}
Signature
function canUseAccessControl(accessControl: AccessControl): Promise<AccessControlAvailability>;
Promise<AccessControlAvailability>PromptNeverThrowsMISSING_USAGE_DESCRIPTION (iOS, a biometric value without NSFaceIDUsageDescription); INVALID_ARGUMENT for a value that isn't an AccessControlPlatformsiOSAndroidParameters
| Parameter | Type | Description |
|---|---|---|
| accessControlRequired | AccessControl | The protection to ask about, one of AccessControl. 'none' is always available. |
Returns
{ available: true }, or { available: false, reason }. See AccessControlAvailability.
The reasons
| Reason | Means | The write would throw |
|---|---|---|
unsupportedOS | The value needs a newer OS: a value with the passcode on Android 7–10 | UNSUPPORTED |
noHardware | No biometric sensor, or none that can unlock a key (Android: Class 3) | BIOMETRY_NOT_AVAILABLE |
passcodeNotSet | The device has no passcode, PIN or pattern, which every value but none needs | PASSCODE_NOT_SET |
notEnrolled | A sensor, but no face or finger enrolled | BIOMETRY_NOT_ENROLLED |
When several are true, the reason is the first of them in this order: unsupportedOS, noHardware, passcodeNotSet, notEnrolled. The answer for a value is the answer its write would get, on both platforms.
biometryCurrentSetandbiometryCurrentSetOrPasscodeneed enrolled biometrics: without them the answer isnotEnrolled, even when the passcode is set.biometryAnyOrPasscodeandpasscodeneed only the passcode.- A lockout is not a reason. After too many failed scans the biometrics is locked for a while, but an item can still be written: the answer is
available, and a read meets the lockout asLOCKOUT. MISSING_USAGE_DESCRIPTION. On an iPhone with Face ID and an app withoutNSFaceIDUsageDescriptionin its Info.plist, a biometric value can't be asked about: the call rejects, as the write would. It is a mistake in the app's setup, and it should be loud. Add the key, or the config plugin'sfaceIDPermission.
The answer is for now: the user can enroll a face or remove the passcode later. Ask again when the app comes to the foreground, and still handle the codes of the write.