Liveness

Find out if the person on camera is alive

Liveness is a UI module that displays camera preview and analyzes video stream from user's device to guide them through a process of detection.

Display the Liveness

Liveness comes with the configuration allowing you to change the behavior and appearance of some UI elements. For more UI customization please check out UI Customization.

At the moment, the configuration is only available for iOS and Android platforms.

Start the Liveness process with configuration:

Swift
Objective-C
Kotlin
Java
React Native
Flutter
Cordova
Ionic
Swift
let configuration = LivenessConfiguration {
$0.cameraPosition = .front
$0.cameraSwitchEnabled = true
}
FaceSDK.service.startLiveness(
from: viewController,
animated: true,
configuration: configuration,
onLiveness: { response in
// ... check response.liveness for detection result.
},
completion: nil
)
Objective-C
RFSLivenessConfiguration *configuration = [RFSLivenessConfiguration configurationWithBuilder:^(RFSLivenessConfigurationBuilder * _Nonnull builder) {
builder.cameraPosition = RFSCameraPositionFront;
builder.cameraSwitchEnabled = YES;
}];
[RFSFaceSDK.service startLivenessFrom:viewController
animated:YES
configuration:configuration
onLiveness:^(RFSLivenessResponse * _Nonnull response) {
// ... check response.liveness for detection result.
} completion:nil];
Kotlin
val configuration = LivenessConfiguration.Builder()
.setCameraId(0)
.setCameraSwitchEnabled(true)
.build()
FaceSDK.Instance().startLiveness(this@MainActivity, configuration) { response ->
// ... check response.getLiveness(); for detection result.
}
Java
LivenessConfiguration configuration = new LivenessConfiguration.Builder()
.setCameraId(0)
.setCameraSwitchEnabled(true)
.build();
FaceSDK.Instance().startLiveness(MainActivity.this, configuration, livenessResponse -> {
// ... check livenessResponse.liveness for detection result.
});
React Native
FaceSDK.startLiveness(livenessResponse => {
const response = LivenessResponse.fromJson(JSON.parse(livenessResponse));
// ... check response.liveness for detection result.
}, e => { });
Flutter
FaceSDK.startLiveness().then((livenessResponse) {
var response = LivenessResponse.fromJson(jsonDecode(livenessResponse));
// ... check response.liveness for detection result.
});
Cordova
FaceSDK.startLiveness(livenessResponse => {
const response = FaceSDK.LivenessResponse.fromJson(JSON.parse(livenessResponse));
// ... check response.liveness for detection result.
}, e => { });
Ionic
FaceSDK.startLiveness().then(livenessResponse => {
const response = LivenessResponse.fromJson(JSON.parse(livenessResponse));
// ... check response.liveness for detection result.
});

When you want to keep the default configuration you can omit the configuration parameter.

If you decide to stop the Liveness processing programmatically there is a call:

Swift
Objective-C
Kotlin
Java
React Native
Flutter
Cordova
Ionic
Swift
FaceSDK.service.stopLivenessProcessing()
Objective-C
[RFSFaceSDK.service stopLivenessProcessing];
Kotlin
FaceSDK.Instance().stopLivenessProcessing(this@MainActivity)
Java
FaceSDK.Instance().stopLivenessProcessing(MainActivity.this);
React Native
FaceSDK.stopLivenessProcessing(() => {}, () => {});
Flutter
FaceSDK.stopLivenessProcessing();
Cordova
FaceSDK.stopLivenessProcessing();
Ionic
FaceSDK.stopLivenessProcessing();

Response

LivenessResponse contains the result of processing in a form of the liveness status and the error properties.

To determine the result of the detection check for the liveness property:

Swift
Objective-C
Kotlin
Java
React Native
Flutter
Cordova
Ionic
Swift
if case response.liveness = .passed {
// continue with successful path.
}
Objective-C
if (response.liveness == RFSLivenessStatusPassed) {
// continue with successful path.
}
Kotlin
if (response.liveness == LivenessStatus.PASSED) {
// continue with successful path.
}
Java
if (response.getLiveness() == LivenessStatus.PASSED) {
// continue with successful path.
}
React Native
if (response.liveness == LivenessStatus.PASSED) {
// continue with successful path.
}
Flutter
if (response?.liveness == LivenessStatus.PASSED) {
// continue with successful path.
}
Cordova
if (response.liveness == FaceSDK.Enum.LivenessStatus.PASSED) {
// continue with successful path.
}
Ionic
if (response.liveness == LivenessStatus.PASSED) {
// continue with successful path.
}

Error Handling

The errors and exceptions give you an insight into what happened to the Liveness processing from a user canceling the operation to a missing License on a web service.

Here is an example of how you can handle a failed LivenessResponse:

Swift
Objective-C
Kotlin
Java
React Native
Flutter
Cordova
Ionic
Swift
if let error = response.error {
// There is an error. Lets see what type is it.
switch error {
case LivenessError.cancelled:
print("User cancelled the processing.")
case LivenessError.noLicense:
print("Web Service is missing a valid License.")
case LivenessError.processingAttemptsEnded:
print("Reached the number of possible attempts. See `RFSLivenessConfiguration.attemptsCount` for more information.")
case LivenessError.processingFailed:
print("Bad input data.")
case LivenessError.processingTimeout:
print("Processing finished by timeout.")
case LivenessError.apiCallFailed:
print("Web Service API call failed due to networking error or backend internal error.")
default:
break
}
}
Objective-C
if (response.error) {
// There is an error. Lets see what type is it.
switch ((RFSLivenessError)response.error.code) {
case RFSLivenessErrorCancelled:
NSLog(@"User cancelled the processing.");
break;
case RFSLivenessErrorNoLicense:
NSLog(@"Web Service is missing a valid License.");
break;
case RFSLivenessErrorProcessingAttemptsEnded:
NSLog(@"Reached the number of possible attempts. See `RFSLivenessConfiguration.attemptsCount` for more information.");
break;
case RFSLivenessErrorProcessingFailed:
NSLog(@"Bad input data.");
break;
case RFSLivenessErrorProcessingTimeout:
NSLog(@"Processing finished by timeout.");
break;
case RFSLivenessErrorAPICallFailed:
NSLog(@"Web Service API call failed due to networking error or backend internal error.");
break;
}
}
Kotlin
val exception = response.exception
if (exception != null) {
when (exception.errorCode) {
LivenessErrorCode.CANCELLED ->
print("User cancelled the processing.")
LivenessErrorCode.NO_LICENSE ->
print("Web Service is missing a valid License.")
LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED ->
print("Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.")
LivenessErrorCode.PROCESSING_FAILED ->
print("Bad input data.")
LivenessErrorCode.PROCESSING_TIMEOUT ->
print("Processing finished by timeout.")
LivenessErrorCode.API_CALL_FAILED ->
print("Web Service API call failed due to networking error or backend internal error.")
LivenessErrorCode.CONTEXT_IS_NULL ->
print("Provided context is null.")
LivenessErrorCode.IN_PROGRESS_ALREADY ->
print("Liveness has already started.")
LivenessErrorCode.ZOOM_NOT_SUPPORTED ->
print("Camera zoom support is required.")
}
}
Java
LivenessErrorException exception = response.getException();
if (exception != null) {
switch (exeption.getErrorCode()) {
case LivenessErrorCode.CANCELLED:
Log.d("liveness", "User cancelled the processing.");
break;
case LivenessErrorCode.NO_LICENSE:
Log.d("liveness", "Web Service is missing a valid License.");
break;
case LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED:
Log.d("liveness", "Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.");
break;
case LivenessErrorCode.PROCESSING_FAILED:
Log.d("liveness", "Bad input data.");
break;
case LivenessErrorCode.PROCESSING_TIMEOUT:
Log.d("liveness", "Processing finished by timeout.");
break;
case LivenessErrorCode.API_CALL_FAILED:
Log.d("liveness", "Web Service API call failed due to networking error or backend internal error.");
break;
case LivenessErrorCode.CONTEXT_IS_NULL:
Log.d("liveness", "Provided context is null.");
break;
case LivenessErrorCode.IN_PROGRESS_ALREADY:
Log.d("liveness", "Liveness has already started.");
break;
case LivenessErrorCode.ZOOM_NOT_SUPPORTED:
Log.d("liveness", "Camera zoom support is required.");
break;
}
}
React Native
const exception = response.exception;
if (exception) {
switch (exception.errorCode) {
case LivenessErrorCode.CANCELLED:
console.log('liveness: User cancelled the processing.');
break;
case LivenessErrorCode.NO_LICENSE:
console.log('liveness: Web Service is missing a valid License.');
break;
case LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED:
console.log('liveness: Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.');
break;
case LivenessErrorCode.PROCESSING_FAILED:
console.log('liveness: Bad input data.');
break;
case LivenessErrorCode.PROCESSING_TIMEOUT:
console.log('liveness: Processing finished by timeout.');
break;
case LivenessErrorCode.API_CALL_FAILED:
console.log('liveness: Web Service API call failed due to networking error or backend internal error.');
break;
case LivenessErrorCode.CONTEXT_IS_NULL:
console.log('liveness: Provided context is null.');
break;
case LivenessErrorCode.IN_PROGRESS_ALREADY:
console.log('liveness: Liveness has already started.');
break;
case LivenessErrorCode.ZOOM_NOT_SUPPORTED:
console.log('liveness: Camera zoom support is required.');
break;
}
}
Flutter
var exception = response?.exception;
if (exception != null) {
switch (exception.errorCode) {
case LivenessErrorCode.CANCELLED:
print('liveness: User cancelled the processing.');
break;
case LivenessErrorCode.NO_LICENSE:
print('liveness: Web Service is missing a valid License.');
break;
case LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED:
print('liveness: Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.');
break;
case LivenessErrorCode.PROCESSING_FAILED:
print('liveness: Bad input data.');
break;
case LivenessErrorCode.PROCESSING_TIMEOUT:
print('liveness: Processing finished by timeout.');
break;
case LivenessErrorCode.API_CALL_FAILED:
print('liveness: Web Service API call failed due to networking error or backend internal error.');
break;
case LivenessErrorCode.CONTEXT_IS_NULL:
print('liveness: Provided context is null.');
break;
case LivenessErrorCode.IN_PROGRESS_ALREADY:
print('liveness: Liveness has already started.');
break;
case LivenessErrorCode.ZOOM_NOT_SUPPORTED:
print('liveness: Camera zoom support is required.');
break;
}
}
Cordova
const exception = response.exception;
if (exception) {
switch (exception.errorCode) {
case FaceSDK.Enum.LivenessErrorCode.CANCELLED:
console.log('liveness: User cancelled the processing.');
break;
case FaceSDK.Enum.LivenessErrorCode.NO_LICENSE:
console.log('liveness: Web Service is missing a valid License.');
break;
case FaceSDK.Enum.LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED:
console.log('liveness: Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.');
break;
case FaceSDK.Enum.LivenessErrorCode.PROCESSING_FAILED:
console.log('liveness: Bad input data.');
break;
case FaceSDK.Enum.LivenessErrorCode.PROCESSING_TIMEOUT:
console.log('liveness: Processing finished by timeout.');
break;
case FaceSDK.Enum.LivenessErrorCode.API_CALL_FAILED:
console.log('liveness: Web Service API call failed due to networking error or backend internal error.');
break;
case FaceSDK.Enum.LivenessErrorCode.CONTEXT_IS_NULL:
console.log('liveness: Provided context is null.');
break;
case FaceSDK.Enum.LivenessErrorCode.IN_PROGRESS_ALREADY:
console.log('liveness: Liveness has already started.');
break;
case FaceSDK.Enum.LivenessErrorCode.ZOOM_NOT_SUPPORTED:
console.log('liveness: Camera zoom support is required.');
break;
}
}
Ionic
const exception = response.exception;
if (exception) {
switch (exception.errorCode) {
case LivenessErrorCode.CANCELLED:
console.log('liveness: User cancelled the processing.');
break;
case LivenessErrorCode.NO_LICENSE:
console.log('liveness: Web Service is missing a valid License.');
break;
case LivenessErrorCode.PROCESSING_ATTEMPTS_ENDED:
console.log('liveness: Reached the number of possible attempts. See `LivenessConfiguration.attemptsCount` for more information.');
break;
case LivenessErrorCode.PROCESSING_FAILED:
console.log('liveness: Bad input data.');
break;
case LivenessErrorCode.PROCESSING_TIMEOUT:
console.log('liveness: Processing finished by timeout.');
break;
case LivenessErrorCode.API_CALL_FAILED:
console.log('liveness: Web Service API call failed due to networking error or backend internal error.');
break;
case LivenessErrorCode.CONTEXT_IS_NULL:
console.log('liveness: Provided context is null.');
break;
case LivenessErrorCode.IN_PROGRESS_ALREADY:
console.log('liveness: Liveness has already started.');
break;
case LivenessErrorCode.ZOOM_NOT_SUPPORTED:
console.log('liveness: Camera zoom support is required.');
break;
}
}

For more information on LivenessConfiguration and LivenessResponse please see the SDK Reference.