Skip to main content
‹ Device capabilities
Function

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
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​

src/auth/biometrics.ts
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>;
ReturnsPromise<AccessControlAvailability>PromptNeverThrowsMISSING_USAGE_DESCRIPTION (iOS, a biometric value without NSFaceIDUsageDescription); INVALID_ARGUMENT for a value that isn't an AccessControlPlatformsiOSAndroid

Parameters​

ParameterTypeDescription
accessControlRequiredAccessControlThe protection to ask about, one of AccessControl. 'none' is always available.

Returns​

{ available: true }, or { available: false, reason }. See AccessControlAvailability.

The reasons​

ReasonMeansThe write would throw
unsupportedOSThe value needs a newer OS: a value with the passcode on Android 7–10UNSUPPORTED
noHardwareNo biometric sensor, or none that can unlock a key (Android: Class 3)BIOMETRY_NOT_AVAILABLE
passcodeNotSetThe device has no passcode, PIN or pattern, which every value but none needsPASSCODE_NOT_SET
notEnrolledA sensor, but no face or finger enrolledBIOMETRY_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.

  • biometryCurrentSet and biometryCurrentSetOrPasscode need enrolled biometrics: without them the answer is notEnrolled, even when the passcode is set. biometryAnyOrPasscode and passcode need 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 as LOCKOUT.
  • MISSING_USAGE_DESCRIPTION. On an iPhone with Face ID and an app without NSFaceIDUsageDescription in 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's faceIDPermission.

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.

See also​