iOS - Face Module¶
The Face Module performs liveness detection and compares the user's face with the photo on the identification card. Additionally, video recording can be optionally captured during the flow.
Introduction¶
The Face Module analyzes whether a person is a real individual using images taken from the front camera. The module can detect facial expressions and movements such as smiling, blinking, turning the head to the right or left, and looking upward.
It is important for the face to be correctly aligned with the camera during the analysis process. Additionally, the analysis duration may vary depending on the device's performance and camera quality. This module provides an effective and reliable solution, especially in authentication processes that require liveness detection.
Warning
When the Face Module is to be used, the Core Module must be included in the project. This is necessary to provide the basic functionalities of the modules.
EnQualifyFace SDK Project Integration Steps¶
This guide explains how to integrate the EnQualifyFace SDK into your project. You can quickly and easily complete the integration by following the steps below.
What is Core Module¶
Before adding the Face Module, the Core Module must be included in the project. To learn how to add the core module, you can visit the Core Module document.
What is EnQualifyFace¶
EnQualifyFace is a module designed as a face recognition and verification (liveness detection) SDK. This module is designed to perform liveness detection in remote identity verification processes.
EnQualifyFace can perform the following:
- Face Detection: Detects the user's face in front of the camera.
-
Liveness Control: Confirms that the person is a living human by prompting different movements:
-
Smile detection
- Eye closure detection
- Turning the face right, left, and upwards
- Face Comparison: Can compare the captured face image with the face photo on the ID card or NFC chip.
Quick Implementation¶
To achieve quick integration in your project, you can refer to the section How is the Face Module Implemented?.
Adding Face Module to the Project¶
EnQualify iOS SDK can be directly integrated into the project:
- Method: Add the SDK directly by embedding the xcframework into your project and install the required dependencies via CocoaPods.
// target 'MySampleProject' do
use_frameworks!
pod 'GoogleMLKit/FaceDetection', '7.0.0' # Face and Liveness Detection
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = ""
config.build_settings['VALID_ARCHS'] = "arm64 x86_64"
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
end
end
end
Explanation of Build Settings After Installation¶
BUILD_LIBRARY_FOR_DISTRIBUTION = YES:¶
Ensures that the framework is built for distribution, allowing it to be used as a binary or shared framework in other projects. This is particularly useful when creating XCFrameworks.
EXPANDED_CODE_SIGN_IDENTITY = "":¶
Clears the Code Signing Identity; thus ensuring that no specific certificate is used during the build process.
CODE_SIGNING_REQUIRED = NO:¶
Disables the code signing requirement during the build process. This is useful for testing or situations where signing is not necessary.
CODE_SIGNING_ALLOWED = NO:¶
Ensures that code signing is completely disabled.
EXCLUDED_ARCHS[sdk=iphonesimulator*] = "":¶
Removes any architectures that are pre-excluded for the iPhone simulator. This setting ensures compatibility during the build process.
VALID_ARCHS = "arm64 x86_64":¶
Specifies valid architectures for the build. Here, it's used for arm64 (M Series) and x86_64 (Intel chip) Macs.
IPHONEOS_DEPLOYMENT_TARGET = 14.0:¶
Sets the minimum iOS version supported by the application or framework. This ensures compatibility with devices running iOS 14.0 and above.
ONLY_ACTIVE_ARCH = YES:¶
Limits the build process to the architecture of the active build device or simulator only. This can speed up the build duration during development.
XCFrameworks¶
- To directly integrate the EnQualify SDK into your project, you can add the essential SDK files -
OCRModule.xcframework,NFCModule.xcframework,FaceModule.xcframework,CoreModule.xcframework, andVideoCallModule.xcframework- directly to your project files. - Alternatively, if you have already copied the XCFrameworks to your project, you can go to Project Settings > General and select the Embed and Sign option to add these frameworks to your project.
- For the dependencies of the EnQualify SDK added this way, you need to include them in your project with the version numbers specified in the "podspec" file of the relevant version or defined by the provider.
How to Implement Face Module?¶
1. Adding Modules¶
1.1 Implementation of Core Module¶
The Core Module must be included in the project before using the EnQualifyFace Module. If you have not added it yet, you can refer to the Core Module documentation for details.
1.2 Adding Face Module to the Project¶
You can find the necessary instructions for integrating the Face Module under the heading Adding Face Module to the Project. Follow these steps to include the Face module in your project.
2. Permissions¶
2.1 Adding Camera Permission to Info.plist File¶
First, you need to add camera permission to the Info.plist file. This allows your application to access the camera hardware.
2.2 Requesting Runtime Permission¶
Camera permission is requested within the initialize function.
EnQualifyFace.initialize(_ sender: Any?,
sessionModel: SessionModelFace? = nil,
baseModel: BaseModelFace? = nil)
If camera permission is not granted, the initializeFailed(with key: CustomNSError) delegate is triggered. If permission is granted, the initializeCompleted(moduleName: String) delegate is triggered.
3. Adding EnQualifyFaceDelegate Interface¶
EnQualifyFaceDelegate includes the necessary delegate methods to manage Face operations. By implementing this interface, you can listen to and manage events related to Face. For detailed information, you can review the section EnQualifyFace User Guide.
3.1 Adding EnQualifyFaceDelegate to the Class¶
3.2 Overriding Delegate Functions¶
class ViewController: EnQualifyFaceDelegate {
func faceDetected() {}
func smileDetected() {}
func eyeCloseDetected() {}
func faceLeftDetected() {}
func faceRightDetected() {}
func faceUpDetected() {}
func faceCompleted() {}
func livenessFailed(error: EnQualifyFaceError) {}
func faceFailed(error: EnQualifyFaceError) {}
func faceDetectFailed(error: EnQualifyFaceError) {}
func faceCompareCompleted() {}
func faceCompareFailed(error: EnQualifyFaceError) {}
func initializeCompleted(moduleName: String) {}
func initializeFailed(with key: CustomNSError) {}
func tokenCreateCompleted() {}
func tokenCreateFailed() {}
func integrationAddCompleted() {}
func integrationAddFailed() {}
func sessionAddFailed() {}
func settingGetFailed() {}
}
4. Initializing EnQualifyFace and Token, Settings, and Session Operations¶
Note
Before initializing core;
- The methods of EnQualifyFaceDelegate should be added to the delegate property of the UIViewController where it will be used.
- SessionModelFace is the model containing the parameters to be used to initialize Face and this model should be added to the relevant field during the initialization process. For detailed information, please refer to the SessionModelFace section.
- BaseModelFace is the model that contains the certificate and basic URL information necessary for Face and this model should be added to the relevant field during the initialization process. For detailed information, please refer to the BaseModelFace section.
Before starting Face operations, the EnQualifyFace class must be initialized. This process ensures the initialization of the necessary token, settings, and session operations. It is also important to inform the user that the preparations for the Face operation are complete and then to start the processing.
func initialize(_ sender: Any?,
sessionModel: SessionModelFace? = nil,
baseModel: BaseModelFace? = nil) {
Parameters¶
| Parameter | Type | Description |
|---|---|---|
delegate | Any? | Determines which UIViewController the application will be used in. |
sessionModel | SessionModelFace | Contains session information to be used during the Face operation. |
baseModel | BaseModelFace | The model that carries the basic data for the validation process. |
After EnQualifyFace is initialized, an EnQualifyFace instance is created and then it initiates the necessary operations to create the token, settings, and session. After initialization, the token, settings, and session are managed by the SDK.
After the EnQualifyFace instance is created, the following steps are carried out in order:
-
Token Creation
-
EnQualifyFace initiates the token creation process.
- If an error occurs during the token creation process, the tokenCreateFailed delegate is triggered.
- When the token is successfully created, the process proceeds to the next step, which is the session operation.
-
Starting the Session Operation
-
After the token is successfully obtained, the session initialization process begins.
- If an error occurs during session initialization, the sessionAddFailed delegate is triggered.
- When the session operation is successfully completed, the SDK establishes a connection with the backoffice and becomes ready to initiate the process.
-
Retrieving Settings
-
After the session is successfully created, the process of retrieving the defined settings from the backoffice is initiated.
- If an error occurs during this process, the settingsGetFailed delegate is triggered, and the error message is communicated to the client side.
- When the settings are successfully retrieved, the SDK makes the necessary configurations and initiates the session operation.
-
Completing the Operation
-
When all steps are completed without issues, the initializeCompleted delegate is triggered. This indicates that the SDK has been successfully initialized and is ready for Face operations.
This process is designed to ensure the robust operation of EnQualifyFace. Any potential errors can be communicated to the client or user through the relevant delegates, facilitating the necessary actions.
5. Starting the Face Process¶
In this section, we step-by-step explain how to start and manage Face processes.
5.1 User Information¶
Before starting the face process, it is recommended to provide user information. For this, a FaceInfo page can be created.
This page informs the user about the face process and provides a better experience.
5.2 Face Processes¶
For detailed information about face functions and delegates, you can refer to the EnQualifyFace User Guide. The reference liveliness flow is smile → eyeClose → (randomly right, left, or up) → complete; all three directions are not applied together in a single flow.
- setTotalSteps(_ steps: Int)
- faceDetect(in viewController: UIViewController, cameraPosition: AVCaptureDevice.Position = .front)
- eyeCloseDetect()
- smileDetect()
- faceRightDetect()
- faceLeftDetect()
- faceUpDetect()
- faceComplete(withDelay delay: TimeInterval = 0.0)
5.2.1. Adding Step Count¶
In the reference flow, a total of 3 steps are shown for liveliness control: first a smile, then eye closing, and finally a single direction movement (to the right, left, or up) is randomly selected. All three directional steps are not performed consecutively. To specify the number of steps, setTotalSteps(_ steps: Int) is called.
5.2.3 Performing Face Detection¶
To initiate the face detection process, the faceDetect(in viewController: UIViewController, cameraPosition: AVCaptureDevice.Position = .front) function is used. This process is managed by the EnQualify Face API and is called as follows:
Delegate Mechanism
When the face detection process is successfully completed, the faceDetected delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.4 Performing Smile Detection¶
To initiate the smile detection process, the smileDetect() function is used. This process is managed by EnQualifyFace and is called as follows:
Delegate Mechanism
When the smile detection process is successfully completed, the smileDetected() delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.5 Performing Eye Closing Detection¶
To initiate the eye closing detection process, the eyeCloseDetect() function is used. This process is managed by EnQualifyFace and is called as follows:
Delegate Mechanism
When the eye closing detection process is successfully completed, the eyeCloseDetected() delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.6 Performing Head Turn to the Right¶
To initiate the head turn to the right process, the faceRightDetect() function is used. This process is managed by EnQualifyFace and is called as follows:
Delegate Mechanism
When the head turn to the right process is successfully completed, the faceRightDetected() delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.7 Performing Head Turn to the Left¶
To initiate the head turn to the left process, the faceLeftDetect() function is used. This process is managed by EnQualifyFace and is called as follows:
Delegate Mechanism
When the head turn to the left process is successfully completed, the faceLeftDetected() delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.8 Performing Head Raise¶
To initiate the head raise process, the faceUpDetect() function is used. This process is managed by EnQualifyFace and is called as follows:
Delegate Mechanism
When the head raise process is successfully completed, the faceUpDetected() delegate is triggered. Within this delegate, other processes that need to be executed after the process can be handled.
5.2.9. Notifying Completion of the Liveliness Flow¶
When all face recognition steps are completed, the faceComplete(withDelay delay: TimeInterval = 0.0) function is used to notify the SDK that the processes have ended. This function also stops the analyses from the camera, finalizes the process, and initiates the backoffice sending process of the data read.
When the data sent to the backoffice is completed, the faceCompleted***()*** delegate is triggered, and the faceCompare function initiates the comparison process.
5.2.10. Comparing the Liveliness Image¶
The similarity ratios can be calculated between the biometric photos obtained from NFC, OCR and the liveliness photo taken during the liveliness step. To initiate this calculation, the faceCompare() function is used, which in turn triggers the faceCompareCompleted(), faceCompareFailed() delegates.
If an error occurs during the comparison, the faceCompareFailed delegate is triggered. This delegate is used to manage the actions to be taken in the event of an error. When the comparison process is successfully completed, the analysis results are automatically transmitted to the backoffice system. After the data transmission is completed, the faceCompareCompleted() delegate is triggered to indicate that the process has been successfully completed.
After the liveliness process is completed, the result page can be opened or proceed to the next operation.
5.2.11. Terminating the SDK Lifecycle¶
To terminate the SDK lifecycle, simply use deinitialize(deinitializeCore:).
If the SDK is to be reused, it must be re-initialized after the deinitialization.
Note:¶
To display the read data on the result page, you can check the CustomerFace section. This section ensures that the read data is presented to the user in a clear and understandable manner.
EnQualifyFace Usage Guide¶
EnQualifyFace is used for facial recognition and liveness detection processes. Below, the relevant functions and delegates are explained.
Functions¶
initialize(...) : EnQualifyFace
func initialize(_ sender: Any?,
sessionModel: SessionModelFace? = nil,
baseModel: BaseModelFace? = nil) {
- sender: Any : Determines which class will handle the application's delegate methods.
- sessionModel: SessionModelFace : Contains session information to be used during the face operation.
- baseModel: BaseModelFace : The model that carries the base data during the verification process.
It can be given. Since the API operates in a singleton structure, operations are carried out through the same instance throughout the application session. This not only saves resources but also increases process consistency. The initialization process automatically performs the following operations:
- Token creation
- Settings configuration
- Session initiation If there is an existing session, a new session will not be created, and the existing session will continue to be used.
faceDetect()
Determines whether a face is detected in the camera. The acceptance mechanism has two stages: First, a clarity (blur) pre-filter is applied, and at least 4 out of the last 5 frames must be clear. Then, a single frame quality control is performed. In this control, the head angles must respectively be <15° / <15° / <10°, the eye openness must be >0.8, and at least 5 landmarks must be detected. When these conditions are met, the face detection process is considered successful.
smileDetect()
Detects whether there is a smile on the face. A smile is a common gesture in liveness detection. Default control value: If there is no backend calibration, it is expected that the smile value is greater than 0.5.
eyeCloseDetect()
Detects whether the eyes are closed. Blinking or keeping the eyes closed is a common criterion in liveness detection. Default control value: If there is no backend calibration, it is expected that one of the right or left eye openness values is less than 0.5.
faceRightDetect()
Detects whether the person has turned their head to the right. This movement is an optional verification step in the liveness check. Default control value: If there is no backend calibration, it is expected that the head is turned to the right by 20° or more.
faceLeftDetect()
Detects whether the person has turned their head to the left. It works similarly to turning to the right. Default control value: If there is no backend calibration, it is expected that the head is turned to the left by 20° or more.
faceUpDetect()
Detects whether the person has lifted their head upward. This movement is a common verification method during liveness detection. Default control value: If there is no backend calibration, it is expected that the head is raised by 25° or more.
faceComplete()
This function informs the SDK that all facial recognition steps have been completed; it stops the analysis from the camera and initiates the process of transmitting the read data to the back office.
faceCompare()
Compares the face detected by the camera with the biometric photo within the identity chip data from OCR, NFC. It is used during identity verification processes.
Delegates¶
Token / Session / Settings Delegates¶
tokenCreateCompleted()
- Triggered when the token creation process is completed.
- If there is an existing token, it is not recreated, and the existing token is used.
tokenCreateFailed()
- Triggered if an error occurs while creating the token.
settingsGetFailed()
- Triggered if an error occurs while fetching settings information.
sessionAddFailed()
- Triggered if an error occurs while creating a new session.
integrationAddCompleted()
- Triggered when the request to the IntegrationAdd service is completed.
integrationAddFailed()
- Triggered if an error occurs when a request to the IntegrationAdd service is made.
initializeCompleted(module: String)
- Triggered after the EnQualifyFace module has been initialized and the processes for token, settings, and session have been successfully completed.
The flow of operations should be defined according to the module started. * Parameter:
module: The name of the module that was initialized.
Face Callbacks
faceDetected()
- Triggered when a face is detected by the camera. This event is the fundamental step to start the liveness detection process.
smileDetected()
- Triggered when the user's smiling action is detected. This is one of the expected actions during liveness detection.
eyeCloseDetected()
- Triggered when the situation of closed eyes is detected. This function is used in situations where the user is expected to blink or keep their eyes closed for a specific period.
faceRightDetected()
- Triggered when it is detected that the user has turned their head to the right. It is used for direction verification within the liveness detection framework.
faceLeftDetected()
- Triggered when it is detected that the user has turned their head to the left. It is used for direction verification within the liveness detection framework.
faceUpDetected()
- Triggered when it is detected that the user has lifted their head upwards. It is used for direction verification within the liveness detection framework.
faceCompareCompleted()
- Triggered when the face comparison process is successfully completed. This indicates that a sufficient match has been achieved between the real-time face and the recorded face data.
faceCompareFailed(error: EnQualifyFaceError)
- Triggered when the face comparison process fails.
-
Parameter:
-
error: A detailed message regarding the comparison error.
livenessFailed(error: EnQualifyFaceError)
- Triggered when the liveness analysis fails.
-
Parameter:
-
error: Error code
faceDetectFailed(error: EnQualifyFaceError)
- Triggered when the face detection process fails.
-
Parameter:
-
error: Error code
faceCompleted()
- Triggered when the face comparison and liveness detection processes are successfully completed. This event indicates that there is a successful match between the real-time face and the recorded face data and that the entire process has been completed.
faceFailed(error: EnQualifyFaceError)
public enum EnQualifyFaceError: Error {
case timeout(FaceState, String)
case detection(String)
case liveness(String)
case comparison(String)
case camera(String)
case luminosityFailed(String)
case backgroundInterruption(String)
public var faceLocalizedDescription: String {
switch self {
case .timeout(let state, let message):
return "Timeout during \(state) state: \(message)"
case .detection(let message),
.liveness(let message),
.comparison(let message),
.camera(let message),
.luminosityFailed(let message),
.backgroundInterruption(let message):
return message
}
}
}
- Triggered when an error is encountered or a failure occurs during face operations.
-
Parameters:
-
faceLocalizedDescription: Error message.
Models¶
BaseModelFace¶
BaseModelFace is the data model that contains the certificate information, certificate public key values, and server connection address used in verification processes. Signaling and MAPI (Mobile-Application Programming Interface) certificates can be stored in file (.der) format, Base64 text format, or as a public key list.
Model¶
class BaseModelFace(
var signallingCertificateList: [String]? = nil
var mapiCertificateList: [String]? = nil
var signallingCertificateBase64List: [String]? = nil
var mapiCertificateBase64List: [String]? = nil
var signallingCertificatePublicKeyList: [String]? = nil
var mapiCertificatePublicKeyList: [String]? = nil
var baseURL: String?
var locale: String? = nil
var mobileUser: String? = nil
var countryCode: String? = nil
)
Features¶
| Feature | Type | Description |
|---|---|---|
signallingCertificateList | [String]? | An array of signalling certificates. Certificates are stored in file format. |
mapiCertificateList | [String]? | An array of MAPI certificates. Certificates are stored in file format. |
signallingCertificateBase64List | [String]? | Encoded forms of signalling certificates in Base64 text format. |
mapiCertificateBase64List | [String]? | Encoded forms of MAPI certificates in Base64 text format. |
signallingCertificatePublicKeyList | [String]? | A list containing the values of signalling certificates in public key format. |
mapiCertificatePublicKeyList | [String]? | A list containing the values of MAPI certificates in public key format. |
*baseURL | String | The base server address used for API authentication processes. |
locale | String | Determines the language of the voice guidance messages. |
mobileUser | String? | Represents the anonymous user information used during authorization. |
countryCode | String? | Used to ensure that the necessary data is obtained regionally when verification is done specifically for a country or region. |
Usage Example¶
In the following example, a BaseModelFace object is created, defining the certificate information and server address:
var baseModelFace = BaseModelFace(
signallingCertificateList: ["AI_CERT_1", "AI_CERT_2"],
mapiCertificateList: ["MAPI_CERT_1", "MAPI_CERT_2"],
signallingCertificateBase64List: ["QUlDRVJU...", "Q0VSVF8y..."],
mapiCertificateBase64List: ["TU9SRSB...", "Q0VSVF8z..."],
signallingCertificatePublicKeyList: ["SIGNALLING_PUBLIC_KEY_1", "SIGNALLING_PUBLIC_KEY_2"],
mapiCertificatePublicKeyList: ["MAPI_PUBLIC_KEY_1", "MAPI_PUBLIC_KEY_2"],
baseURL: "API_SERVER_URL",
locale: "tr",
mobileUser: "mobile",
countryCode: "TUR"
)
Explanations¶
- Certificates (
signallingCertificateList,mapiCertificateList): Certificate information is stored in file format. - Base64 Certificates (
signallingCertificateBase64List,mapiCertificateBase64List): Forms of certificates converted to Base64 text format. - Public Key Certificates (
signallingCertificatePublicKeyList,mapiCertificatePublicKeyList): Lists containing the public key values of signalling and MAPI certificates. - Server Connection (
baseURL): The server URL where verification or certificate processes will be carried out.
SessionModelFace¶
SessionModelFace is the data model that includes user and identity information during a call session. It contains call type, user details, credentials, and additional parameters related to the session.
Model Definition¶
class SessionModelFace(
var callType: String?,
var name: String? = nil,
var surname: String? = nil,
var phone: String? = nil,
var email: String? = nil,
var identityType: String? = nil,
var identityNo: String? = nil,
var reference: String?,
var canAutoClose: NSNumber?,
var _continue: NSNumber?,
var category: String? = nil,
var taxNumber: String? = nil,
var businessReference: String? = nil,
var handicapped: NSNumber?
)
Features¶
| Feature | Type | Description |
|---|---|---|
*callType | String | Mandatory. The parameter indicating the type of call (e.g., "NewCustomer"). |
name | String? | The user's first name. Can be empty. |
surname | String? | The user's last name. Can be empty. |
phone | String? | The user's phone number. Can be empty. |
email | String? | The user's email address. Can be empty. |
identityType | String? | Identity type (e.g., "I"(Turkish ID Card), "P"(Passport)). Can be empty. |
identityNo | String? | The user's identity number. Can be empty. |
*reference | String | Mandatory. Reference ID for the session. |
canAutoClose | NSNumber? | Indicates whether the session can automatically close. Can be set to 0 or 1. |
_continue | NSNumber? | Indicates whether the session will continue. Can be set to 0 or 1. |
category | String? | The category to which the session belongs. Can be empty. |
taxNumber | String? | The tax number of the user. Can be empty. |
businessReference | String? | Reference information related to the business. Can be empty. |
handicapped | NSNumber? | A flag indicating whether the user is disabled. Can be set to 0 or 1. |
Usage Example¶
In the following example, a SessionModelFace object is created, defining the session information:
var sessionModelFace = SessionModelFace(
callType: "NewCustomer",
name: "Enqura",
surname: "Information",
phone: "+905551234567",
email: "enqualifyplus@enqura.com",
identityType: "TC. Kimlik Kartı",
identityNo: "12345678901",
reference: "REF123456",
canAutoClose: 1,
_continue: 1,
category: "category",
taxNumber: "9876543210",
businessReference: "COMPANY",
handicapped: 0
)
Explanations¶
- Mandatory Fields: The
callTypeandreferenceparameters must be specified. - User Information: Fields such as
name,surname,phone,emailare optional. - Identity Information:
identityTypeandidentityNocan be used in NFC verification or identity identification processes. - Disability Status: The
handicappedparameter indicates whether the user has special needs. - Automatic Closure:
canAutoClosemay allow the session to close automatically when a certain condition occurs. - Continuation Status:
_continuechecks whether the session is an ongoing process.
CustomerFace¶
These values are various parameters and criteria used for a face recognition and liveness detection process. Each one is used to monitor features such as face recognition, motion detection, eye detection, and authentication.
@objc public class CustomerFace: NSObject {
@objc public static let shared = CustomerFace()
// MARK: - Image Getters
@objc public func getFaceDetectedImage() -> UIImage? {}
@objc public func getSmilingDetectedImage() -> UIImage? {}
@objc public func getFaceLeftDetectedImage() -> UIImage? {}
@objc public func getFaceRightDetectedImage() -> UIImage? {}
@objc public func getFaceUpDetectedImage() -> UIImage? {}
@objc public func getEyeCloseDetectedImage() -> UIImage? {}
@objc public func getEyeCloseIntervalDetectedImage() -> UIImage? {}
@objc public func getEyeOpenIntervalDetectedImage() -> UIImage? {}
// MARK: - Angle Getters
@objc public func getFaceLeftAngle() -> CGFloat {}
@objc public func getFaceRightAngle() -> CGFloat {}
@objc public func getFaceUpAngle() -> CGFloat {}
// MARK: - Eye Measurement Getters
@objc public func getOpennessOfLeftEye() -> Float {}
@objc public func getOpennessOfRightEye() -> Float {}
// MARK: - Confidence and Distance Getters
@objc public func getChipConfidence() -> Int {}
@objc public func getChipDistance() -> Double {}
@objc public func getIdDocConfidence() -> Int {}
@objc public func getIdDocDistance() -> Double {}
@objc public func getAntiSpoofing() -> Double {}
// MARK: - Eye Confidence Getters
@objc public func getLeftEyeCloseConfidence() -> CGFloat {}
@objc public func getRightEyeCloseConfidence() -> CGFloat {}
@objc public func getSmilingConfidence() -> CGFloat {}
// MARK: - Validity Level Getters
@objc public func getIdDocDistanceValidityLevel() -> Int {}
@objc public func getChipDistanceValidityLevel() -> Int {}
@objc public func getAntiSpoofingValidityLevel() -> Int {}
// MARK: - Eye Close Capture Getters
@objc public func getEyeCloseCaptureAntispoofing() -> Float {}
@objc public func getEyeCloseCaptureConfidence() -> Float {}
@objc public func getEyeCloseCaptureDistance() -> Float {}
@objc public func getEyeCloseCaptureDistanceValidityLevel() -> Int {}
@objc public func getEyeCloseCaptureAntispoofingValidityLevel() -> Int {}
// MARK: - Eye Close Capture Setters
@objc public func setEyeCloseCaptureAntispoofing(_ value: Float) {}
@objc public func setEyeCloseCaptureConfidence(_ value: Float) {}
@objc public func setEyeCloseCaptureDistance(_ value: Float) {}
@objc public func setEyeCloseCaptureDistanceValidityLevel(_ value: Int) {}
@objc public func setEyeCloseCaptureAntispoofingValidityLevel(_ value: Int) {}
// MARK: - Smiling Capture Getters
@objc public func getSmilingCaptureAntispoofing() -> Float {}
@objc public func getSmilingCaptureConfidence() -> Float {}
@objc public func getSmilingCaptureDistance() -> Float {}
@objc public func getSmilingCaptureDistanceValidityLevel() -> Int {}
@objc public func getSmilingCaptureAntispoofingValidityLevel() -> Int {}
// MARK: - Smiling Capture Setters
@objc public func setSmilingCaptureAntispoofing(_ value: Float) {}
@objc public func setSmilingCaptureConfidence(_ value: Float) {}
@objc public func setSmilingCaptureDistance(_ value: Float) {}
@objc public func setSmilingCaptureDistanceValidityLevel(_ value: Int) {}
@objc public func setSmilingCaptureAntispoofingValidityLevel(_ value: Int) {}
}
Image Getters¶
These functions return the image of the moment when a specific action is successfully detected during the face authentication flow.
- The image of the moment when the user’s face is validly detected by the system for the first time.
- The image captured when the user is detected to be smiling.
- The image captured when the user turns their face to the left.
- The image captured when the user turns their face to the right.
- The image captured when the user lifts their face up.
- The image captured when the user closes their eyes.
- The image captured during the interval when the eyes are closed for a certain duration.
- The image captured during the interval when the eyes are opened again.
Face Angle Getter Functions¶
With this function, information about the angle at which the facial movement occurs can be obtained.
- The angle of the face turning to the left.
- The angle of the face turning to the right.
- The angle of the face looking up.
Eye Measurement Functions¶
With these functions, you can obtain the value information of the eye-closing actions performed.
0.0 → closed, 1.0 → fully open
- The openness value of the left eye.
- The openness value of the right eye.
Liveness / Confidence / Distance Functions¶
- This function provides a comparison value between the visual captured during face detection and the visuals obtained from the identity chip.
- This function provides a similarity distance value between the visual captured during face detection and the visuals obtained from the identity chip.
Identity Document Values¶
- This function provides a comparison value between the visual captured during face detection and the visuals on the identity document.
- This function provides a similarity distance value between the visual captured during face detection and the visuals on the identity document.
Anti-Spoofing¶
- This function provides a value indicating whether the image is a real user or fake (photo/video).
Eye / Smile Confidence Functions¶
- This function provides a value representing the level of detection of the left eye closing action by the facial analysis system.
- This function provides a value representing the level of detection of the right eye closing action by the facial analysis system.
- This function provides a value indicating the level of detection of the smiling action by the facial analysis system.
Validity Level Functions¶
With these functions, you can obtain information about whether the measurement matches the system's acceptance criteria.
0 measurement value is below the minimum threshold value defined by the system. 1 measurement value is above the maximum threshold value defined by the system. 2 measurement value is between the minimum and maximum threshold values.
- Represents the conformity of the distance measurement between the face on the identity document and the live captured face image to the system's acceptance criteria.
- Indicates the validity status of the distance measurement between the facial data obtained from the chip (NFC) and the live captured face image.
- Indicates whether the liveness validation (anti-spoofing) analysis is acceptable in terms of fraud detection mechanisms. This value is used to assess whether the face validation is belonging to a real user.
Eye Close Capture Getter Functions¶
These functions are measurements specific to the eye-closing moment.
- Represents the singular image measurements obtained during the eye-closing action.
getEyeCloseCaptureAntispoofing()
getEyeCloseCaptureConfidence()
getEyeCloseCaptureDistance()
getEyeCloseCaptureDistanceValidityLevel()
getEyeCloseCaptureAntispoofingValidityLevel()
Eye Close Capture Setter Functions¶
- Used to set the measurement values related to the eye-closing capture.
setEyeCloseCaptureAntispoofing(_:)
setEyeCloseCaptureConfidence(_:)
setEyeCloseCaptureDistance(_:)
setEyeCloseCaptureDistanceValidityLevel(_:)
setEyeCloseCaptureAntispoofingValidityLevel(_:)
Smiling Capture Getter Functions¶
- These functions provide singular capture measurement information related to the smiling moment.
getSmilingCaptureAntispoofing()
getSmilingCaptureConfidence()
getSmilingCaptureDistance()
getSmilingCaptureDistanceValidityLevel()
getSmilingCaptureAntispoofingValidityLevel()
Smiling Capture Setter Functions¶
- Used to manually set the smiling capture measurements.
setSmilingCaptureAntispoofing(_:)
setSmilingCaptureConfidence(_:)
setSmilingCaptureDistance(_:)
setSmilingCaptureDistanceValidityLevel(_:)
setSmilingCaptureAntispoofingValidityLevel(_:)
EnQualifyFace Video Recording User Guide¶
Video Recording Features¶
The video recording feature works completely automatically. There is no need for manual start or stop operations. After the InitializeCompleted delegate is triggered, the value of the screenRecord parameter returned from the Setting/Get service is checked. After the video recording is successfully completed, it is sent to the Backoffice. During the sending process, operations are performed based on the values of screenRecordUploadRetryCount and screenRecordUploadTimeout returned from the Setting/Get service.
ScreenRecord¶
- This parameter determines whether screen recording will be done via the mobile application.
ScreenRecordUploadRetryCount¶
- This parameter indicates the number of retries in case an error occurs during the upload of the screen recording obtained via the mobile application.
ScreenRecordUploadTimeout¶
- This parameter indicates the timeout duration for the upload of the screen recording obtained via the mobile application.
1. How Does Video Recording Work?¶
1.1 Starting Conditions¶
Video recording automatically starts under the following conditions:
- The
screenRecordparameter from the Backoffice must betrue - It must be running in self-service mode (not in video call mode)
- The camera must have been successfully started
1.2 Video Recording Flow¶
1. EnQualifyFace.faceDetect() is called
↓
2. The camera is started
↓
3. Video recording automatically starts (if screenRecord = true)
↓
4. Liveness checks are performed (recording continues)
↓
5. Video recording stops when faceComplete() is called
↓
6. Submission is made to the Backend
↓
7. faceCompleted() or faceFailed() delegate is triggered
2. Delegate Methods and Video Recording¶
2.1 Functions Related to Video Recording¶
// The video recording starts after the camera is opened. (if screenRecord = true)
func faceDetect(in viewController: UIViewController,
cameraPosition: AVCaptureDevice.Position = .front) {}
2.2 Delegates Related to Video Recording¶
protocol EnQualifyFaceDelegate {
// When the video recording is stopped and successfully sent to the backend
func faceCompleted()
// When the video recording or submission fails
func faceFailed(error: EnQualifyFaceError)
}
2.3 Video Recording Lifecycle¶
| Delegate Method | Video Recording Status | Description |
|---|---|---|
initializeCompleted() | Not started yet | Backend settings obtained |
faceDetect(in: viewController) | Started | Video recording process started |
faceCompleted() | Stopped and sent | Process successful |
faceFailed() | Canceled | An error occurred |
3. Implementation¶
3.1 Usage Example in ViewController¶
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the Face module
EnQualifyFace.initialize(
self,
sessionModel: sessionModel,
baseModel: baseModel
)
}
// Start face detection
func startFaceVerification() {
// Video recording will start automatically (if screenRecord = true)
EnQualifyFace.setTotalSteps(2)
EnQualifyFace.faceDetect(in: self)
}
}
// MARK: - EnQualifyFaceDelegate
extension ViewController: EnQualifyFaceDelegate {
func initializeCompleted(moduleName: String) {
// Backend settings received, video recording setting determined
print("Module initialized: \(moduleName)")
if moduleName == "EnQualifyFace" {
startFaceVerification()
}
}
func faceDetected() {
// Face detected, video recording in progress
print("Face detected - video recording in progress")
}
func smileDetected() {
// Smile detected and recorded in video
print("Smile detected - recorded in video")
}
func faceCompleted() {
// Video recording stopped and successfully sent to backend
print("Face verification completed - video saved and uploaded")
}
func faceFailed(error: EnQualifyFaceError) {
// Video recording cancelled or submission failed
print("Face verification failed: \(error.faceLocalizedDescription)")
switch error {
case .timeout(let state, let message):
print("Timeout at state: \(state)")
case .detection(let message):
print("Detection error: \(message)")
case .liveness(let message):
print("Liveness error: \(message)")
case .comparison(let message):
print("Comparison error: \(message)")
case .camera(let message):
print("Camera error: \(message)")
case .luminosityFailed(let message):
print("Luminosity error: \(message)")
}
}
}
4. Video Call Mode¶
4.1 Video Call vs Self-Service¶
| Feature | Self-Service | Video Call |
|---|---|---|
| Video Recording | ✅ Yes (if screenRecord = true) | ❌ No |
| Photo Recording | ✅ Yes | ✅ Yes |
| Backend Submission | ✅ Video + Photos | ✅ Only Photos |
4.2 Video Call Control¶
The SDK checks if it is in a video call for video recording. Video recording can only be done during the Self-Service phase.
5. Log System¶
5.1 Video Recording Logs¶
Logs generated during the video recording process:
| Log Code | Description | When |
|---|---|---|
I_FACE_DETECT | Face detection started | When faceDetect() is called |
I_VIDEO_RECORDING_START | Video recording started | After the camera starts |
I_SET_FACE_COMPLETED | Face process completed | When faceComplete() is called |
I_VIDEO_RECORDING_STOP | Video recording stopped | When video recording ends |
I_FACE_VIDEO_UPLOAD_SUCCESS | Video sent to backend | Upload successful |
I_FACE_VIDEO_UPLOAD_FAILURE | Video could not be sent | Upload failed |
I_VIDEO_FILE_REMOVAL_ERROR | Old video file could not be deleted | Video recording file could not be removed |
I_FACE_VIDEO_READ_FAILURE | Video file could not be read | Upload failed |
6. Error Handling¶
6.1 Video Recording Errors¶
func faceFailed(error: EnQualifyFaceError) {
switch error {
case .liveness("Face save failed"):
// Video could not be sent to backend
print("Video upload failed")
case .timeout(_, _):
// Timeout - video cancelled
print("Timeout - video recording cancelled")
case .detection(_):
// No face found - video cancelled
print("No face - video recording cancelled")
case .luminosityFailed(_):
// Insufficient light - video cancelled
print("Low light - video recording cancelled")
default:
print("Error: \(error.faceLocalizedDescription)")
}
}
6.2 Security Checks¶
When the application goes to the background or if the Picture in Picture (PiP) stream is interrupted, video recording is automatically cancelled. In this case, the faceFailed(error: .backgroundInterruption(...)) callback is triggered:
func faceFailed(error: EnQualifyFaceError) {
if case .backgroundInterruption(let message) = error {
// Cancelled for security reasons
print("Security: App went to background or PiP was interrupted - recording cancelled")
print(message)
}
}
7. Important Notes¶
7.1 Automatic Management¶
- Video recording is fully automatic
- No intervention from the developer is required
- Starts/Stops automatically based on backend settings
7.2 Backend Integration¶
- When video recording is completed, it is automatically sent to the backend
- On successful submission,
faceCompleted()is triggered - On failed submission,
faceFailed(error: EnQualifyFaceError)is triggered; the reason for the error is evaluated through theEnQualifyFaceErrorcase.
7.3 Video Call Support¶
- Video recording is not done in video call mode
Summary¶
Things to be done for video recording feature:
- Implement the EnQualifyFaceDelegate protocol
- Handle the Delegate methods
- Manage Error states
The video recording process is automatically managed based on backend settings. There is no need for the developer to perform any operations related to starting or stopping video recording.