Prueba de Vida (DicioLiveness)
The SDK enables real-time validation of the user's physical presence and authenticity (3D liveness detection), preventing identity spoofing attempts using photos, videos, or masks in a fast and secure manner.
When the Liveness module is invoked, the SDK guides the user step-by-step:
- Initialization and Validation: Credential/token verification with the Dicio backend and secure provisioning of the biometric session.
- Guided and Interactive Capture: Face framing using a smart oval with real-time visual feedback and voice guidance.
- Verification and Result: Processing of the encrypted 3D facial scan and return of a structured result—such as JSON, success status, and the user's photograph in Base64 format.
Compatibilidad y Requisitos
Installation via Swift Package Manager (SPM)
The SDK is distributed as a Swift Package Manager package, which automatically manages all business logic and its associated flows.
Follow these steps to add it to your Xcode project:
Open your project in Xcode.
Go to the top menu and select File > Add Package Dependencies... (or select your project in the navigator, go to the Package Dependencies tab, and press the
+button).In the search bar at the top right, enter the URL of the package repository:
Repositorio SPM
https://bitbucket.org/juarezsdco/dicioliveness-packageConfigure the version rule to Up to Next Major Version and click Add Package.
In the product selection pop-up, select DicioLiveness and ensure you assign it to your host app target.
Click Add Package to complete the integration.
Prerequisites and Permissions
1. Camera permission in Info.plist
The SDK requires access to the device's front-facing camera for biometric detection and scanning. Add the NSCameraUsageDescription key to your application's Info.plist file or to the Info section of the target:
Info.plist
<key>NSCameraUsageDescription</key>
<string>Camera access is required to perform the liveness check and identity validation.</string>
2. Importing the Module
In the Swift files where you intend to use the Liveness interface, import the framework:
Import
import SwiftUI
import DicioLivenessUI
Appearance Customization (LivenessUIConfig)
The LivenessUIConfig structure allows you to configure the color palette (in hexadecimal format) and the institutional logo to be displayed on the liveness test interface:
LivenessUIConfig
let uiConfig = LivenessUIConfig(
outerColorFondo: "#FFFFFF", // Interface outer background color
colorFrame: "#F5F5F5", // Central frame/subview color
colorBorde: "#FF5733", // Frame divider border color
colorOvalo: "#AABBCC", // Face-framing oval color
colorSpinnerDual: "#0080FF", // Detection spinner color
colorTexto: "#000000", // Instruction text color
colorBtnYFeedbackBar: "#4D21B2", // Action button and feedback bar color
colorBtnAndFeedbackBarText: "#FFFFFF", // Button and feedback bar text color
colorBtnHighlight: "#2B0877", // Button color (pressed state)
colorBtnDisabled: "#EFEFEF", // Button color (disabled state)
livenessLogo: "logoInstitucional" // Resource name in Assets.xcassets
)
Detalle de Parámetros:
outerColorFondo(String): General background color of the liveness check interface.colorFrame(String): Color of the inner container holding the instructions and preview.colorBorde(String): Color of the dividing line or border of the capture frame.colorOvalo(String): Color of the guide oval outline used for face positioning.colorSpinnerDual(String): Color of the loading/processing animation during the face scan.colorTexto(String): Color of text labels with on-screen instructions.colorBtnYFeedbackBar(String): Background color for the main action button and the status bar.colorBtnAndFeedbackBarText(String): Text color for the action button and the status bar.colorBtnHighlight(String): Button color when pressed by the user.colorBtnDisabled(String): Button color when inactive or disabled.livenessLogo(String): Name of the image file in your app'sAssets.xcassetscatalog for branding.
- All colors must be specified in a valid hexadecimal format.(
#RRGGBB). - The resource assigned to
livenessLogomust exist within the host app'sAssets.xcassets.
Liveness View Invocation (LivenessLaunchView)
The main entry point for the liveness check flow is LivenessLaunchView. It is initialized with connection parameters, visual configuration, retry settings, audio settings, and the delegate for receiving the result:
LivenessLaunchView Init
LivenessLaunchView(
config: uiConfig,
urlVerify: "https://api.devdicio.net:8444/v1/sec_dev_fintech_pagos_middleware",
token: "TOKEN_BEARER_PROVIDED_BY_DICIO",
showCancelButton: false,
maxAttempts: 3,
soundEnable: true,
delegate: self
)
Parámetros de Inicialización:
config(LivenessUIConfig): Object containing visual customizations for colors and the logo.urlVerify(String): Dicio service endpoint responsible for credential verification and dynamic license provisioning.token(String): Authorization Bearer token generated by the Dicio backend.showCancelButton(Bool): Indicates whether the button to cancel the flow should be displayed.maxAttempts(Int): Maximum number of attempts allowed for the liveness check (e.g.,3).soundEnable(Bool): Enables (true) or disables (false) voice guidance and assistive sounds.delegate(CaptureFaceResultsDelegate?): Delegate object that receives the final scan result.
Implementation of the CaptureFaceResultsDelegate protocol
To receive the status, response data, and resulting facial image, the corresponding class or structure must conform to the CaptureFaceResultsDelegate protocol.
Protocolo CaptureFaceResultsDelegate
public protocol CaptureFaceResultsDelegate {
func finishedLiveness(isSuccessfull: Bool, JSONResults: String, picBase64: String)
}
Método del Delegado:
finishedLiveness
It executes upon completion of the liveness check flow (whether approved, failed, or cancelled).
finishedLiveness
func finishedLiveness(isSuccessfull: Bool, JSONResults: String, picBase64: String) {
// isSuccessfull: true if the 3D liveness check was successfully passed, false otherwise
// JSONResults: JSON string containing the response and verification metadata from the backend
// picBase64: Facial photograph (audit selfie) in Base64 format
}
Text Customization (Optional - FaceTec.strings)
If you need to override or translate the default text in the FaceTec biometric interface, you can add a file named FaceTec.strings to your application's main bundle (Copy Bundle Resources):
FaceTec.strings (Ejemplo)
"FaceTec_instructions_header_ready_1" = "Prepárate para";
"FaceTec_instructions_header_ready_2" = "tu videoselfie";
"FaceTec_instructions_message_ready_1" = "Encuadra tu rostro en el óvalo";
"FaceTec_instructions_message_ready_2" = "Presiona Estoy listo y acércate";
"FaceTec_action_im_ready" = "Estoy listo";
"FaceTec_action_try_again" = "Intentar nuevamente";
"FaceTec_feedback_center_face" = "Centra tu rostro";
"FaceTec_feedback_face_not_found" = "Encuadra tu rostro";
"FaceTec_feedback_move_phone_closer" = "Acércate";
"FaceTec_feedback_move_phone_away" = "Apártate";
"FaceTec_result_facescan_upload_message" = "Subiendo\nel escaneo facial 3D\ncifrado";
"FaceTec_result_success_message" = "Listo";
Complete Integration Example in SwiftUI
Below is a complete SwiftUI integration based on a container presented using .fullScreenCover:
Ejemplo de Integración SwiftUI
import SwiftUI
import DicioLivenessUI
struct HostLivenessView: View {
@State private var showLivenessScanner = false
@State private var statusMessage: String = "Presiona el botón para iniciar la prueba de vida"
var body: some View {
VStack(spacing: 24) {
Text("Validación de Identidad")
.font(.title2)
.fontWeight(.bold)
Text(statusMessage)
.font(.body)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
.padding(.horizontal)
Button(action: {
showLivenessScanner = true
}) {
Text("Iniciar Prueba de Vida")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.frame(height: 48)
.background(Color.blue)
.cornerRadius(12)
}
.padding(.horizontal, 30)
}
.fullScreenCover(isPresented: $showLivenessScanner) {
let uiConfig = LivenessUIConfig(
outerColorFondo: "#FFFFFF",
colorFrame: "#F5F5F5",
colorBorde: "#FF5733",
colorOvalo: "#AABBCC",
colorSpinnerDual: "#0080FF",
colorTexto: "#000000",
colorBtnYFeedbackBar: "#4D21B2",
colorBtnAndFeedbackBarText: "#FFFFFF",
colorBtnHighlight: "#2B0877",
colorBtnDisabled: "#EFEFEF",
livenessLogo: "logoInstitucional"
)
DicioLivenessContainerView(
config: uiConfig,
urlVerify: "https://api.devdicio.net:8444/v1/sec_dev_fintech_pagos_middleware",
token: "TOKEN_PROPORCIONADO_POR_DICIO",
onFinish: { isSuccess in
showLivenessScanner = false
statusMessage = isSuccess ? "✅ Prueba de vida completada con éxito" : "❌ Prueba de vida no aprobada"
}
)
}
}
}
struct DicioLivenessContainerView: View, CaptureFaceResultsDelegate {
let config: LivenessUIConfig
let urlVerify: String
let token: String
let onFinish: (Bool) -> Void
// MARK: - CaptureFaceResultsDelegate
func finishedLiveness(isSuccessfull: Bool, JSONResults: String, picBase64: String) {
print("🧑🦱 [DicioLiveness] Resultado: éxito=\(isSuccessfull), longitud json=\(JSONResults.count)")
if isSuccessfull {
print("📸 [DicioLiveness] Foto Base64 recibida: \(picBase64.prefix(30))...")
}
onFinish(isSuccessfull)
}
var body: some View {
LivenessLaunchView(
config: config,
urlVerify: urlVerify,
token: token,
showCancelButton: false,
maxAttempts: 3,
soundEnable: true,
delegate: self
)
.ignoresSafeArea()
}
}
Consideraciones Adicionales y Buenas Prácticas
- Manejo de Red y Conectividad: The SDK features automatic connectivity monitoring (
NetworkMonitor). If the connection is lost during token verification or credential downloading, the flow will reactively wait and retry as soon as the network becomes available. - Gestión de Permisos de Cámara: If the user has not granted camera permissions, the SDK will automatically request them. If permissions have been previously denied, it will display an alert informing the user of the need to enable them in iOS settings.
- Presentación en SwiftUI: It is recommended to present
LivenessLaunchViewin full-screen mode using.fullScreenCover(isPresented:)and.ignoresSafeArea()to ensure an immersive visual experience and correct biometric framing. - Seguridad de Tokens: The verification Bearer token must be generated dynamically by your application's backend for each session and should not be statically stored in the production source code.