> This is part 1 of 11 of the full documentation (pages 1–100 of 1001).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.facephi.com/llms-full.txt/1
> Page index: https://docs.facephi.com/llms.txt

# Documentación

Este portal es tu centro de referencia para todo lo relacionado con la tecnología de Facephi. Ya seas desarrollador, partner, cliente o parte de nuestro equipo, aquí encontrarás los recursos que necesitas para desarrollar, integrar y mantenerte al día.

Desde documentación técnica y guías de implementación hasta novedades de producto y materiales formativos: todo está diseñado para ayudarte a sacar el máximo provecho de nuestras soluciones.

El Hub de Facephi cubre todas las etapas del ciclo de vida de la identidad.

### Accesos directos

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Bienvenida y conceptos básicos</strong></td><td>Conceptos básicos y primeros pasos para integradores.</td><td><a href="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-44aaba7a64b7a2394e943b48eb58bbdfc53c6caf%2FPrimeros%20pasos%403x.png?alt=media">Primeros pasos@3x.png</a></td><td></td><td><a href="/primeros-pasos/quickstart">Bienvenida y conceptos básicos</a></td></tr><tr><td><strong>SDKs</strong></td><td>Documentación completa de SDKs (Mobile y Web)</td><td><a href="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-4067555034fbde2df45f4113db3864634164d662%2Fcontent.webp?alt=media">content.webp</a></td><td></td><td><a href="/sdks/sdk-mobile">SDKs</a></td></tr><tr><td><strong>API Rest</strong></td><td>Documentación detallada de los endpoints y recursos de la API.</td><td><a href="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-893f6652daa112a074df0a5928e30a9038668f09%2F05_SDK-Mobile.webp?alt=media">05_SDK-Mobile.webp</a></td><td></td><td><a href="/api-rest/identity-api">API Rest</a></td></tr><tr><td><strong>Productos</strong></td><td>Documentación detallada de los productos de Facephi.</td><td><a href="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-5c4338e72f193cd9d120755fe098d52960016472%2FSoluciones%20y%20SDKs%403x.png?alt=media">Soluciones y SDKs@3x.png</a></td><td></td><td><a href="/productos/idv-suite">PRODUCTOS</a></td></tr></tbody></table>


# Bienvenida y conceptos básicos

Te damos la bienvenida a la documentación de **Facephi**.\
Aquí encontrarás todo lo necesario para integrar nuestras soluciones de **verificación biométrica de identidad** en tus productos de forma **segura, eficiente y escalable**.

Esta documentación está pensada para ayudarte a:

* Entender qué problemas resolvemos.
* Conocer las soluciones disponibles.
* Elegir el tipo de integración que mejor encaja con tu producto.
* Empezar a integrar paso a paso.

### ¿A quién va dirigida esta documentación?

Esta guía está orientada a perfiles técnicos que trabajan con las soluciones de Facephi:

* **Desarrolladores** que integran APIs o SDKs en aplicaciones web o móviles.
* **Equipos técnicos** de clientes o partners.
* **QA y testing** para validación de flujos biométricos.
* **Integradores** que implementan soluciones en entornos productivos.

No es necesario un conocimiento previo de biometría, pero sí experiencia técnica en integración de software.

***

### Qué puedes construir con Facephi

Nuestra tecnología te permite implementar soluciones completas de **identidad digital**, adaptadas a diferentes casos de uso.

#### Verificación biométrica de identidad

Verifica que una persona es quien dice ser mediante:

* Autenticación facial.
* Pruebas de vida (**Liveness Detection**).
* Comparación biométrica segura.

***

#### Validación de documentos

Automatiza la captura y validación de documentos de identidad mediante IA:

* Documentos nacionales (DNI, pasaporte, licencias).
* Extracción de datos (OCR).
* Validación de autenticidad.

***

#### Integraciones flexibles

Accede a la tecnología de Facephi a través de:

* **APIs REST**.
* **SDKs nativos** para iOS y Android.
* Soluciones híbridas para otros entornos.

Esto te permite adaptar la integración al stack tecnológico de tu producto.

***

#### Detección de fraude

Protege tus flujos frente a intentos de suplantación mediante:

* Controles biométricos avanzados.
* Detección de ataques y comportamientos anómalos.
* Monitorización de eventos en tiempo real.

***

### Seguridad y cumplimiento

La seguridad y la privacidad son pilares fundamentales de nuestras soluciones.

* **Cifrado extremo a extremo**\
  Los datos sensibles nunca se almacenan ni se transmiten en claro.
* **Cumplimiento normativo**\
  Alineados con estándares y regulaciones como:
  * GDPR
  * eIDAS
  * ISO 27001
  * Normativas locales aplicables
* **Privacy by Design**\
  Diseñado desde el origen para minimizar el uso y exposición de datos personales.


# Mobile SDK

Integra las soluciones biométricas de Facephi de forma nativa en tus aplicaciones móviles Android e iOS, o mediante frameworks híbridos.

Esta sección te guiará paso a paso para:

* Conocer los requisitos mínimos de integración.
* Descargar e instalar los SDKs para Android y iOS.
* Configurar y ejecutar tus primeros flujos de verificación.
* Acceder a plugins oficiales para entornos híbridos como Cordova, Flutter, React Native y Capacitor.

***

### ¿Qué soluciones están disponibles para Mobile?

* Verificación biométrica de identidad.
* Validación de documentos de identidad.
* Pruebas de vida (Liveness Detection).
* Autenticación facial segura.

Nuestra tecnología está pensada para ofrecer máxima seguridad y experiencia de usuario fluida en entornos móviles.

***

### ¿Cómo empezar?

Te recomendamos:

1. Revisar los Requisitos mínimos.
2. Elegir la integración que se adapta a tu proyecto:
   * [Android SDK](/sdks/sdk-mobile/android-sdk)
   * [iOS SDK](/sdks/sdk-mobile/ios-sdk)
   * [Framework Plugins](/sdks/sdk-mobile/framework-plugins)
3. Probar los flujos en entorno Sandbox antes de ir a producción.

Para cualquier duda, nuestro equipo de Soporte Técnico está disponible.


# Android SDK

Esta sección agrupa toda la información necesaria para implementar, configurar y personalizar los flujos biométricos en aplicaciones Android.

### Qué puedes hacer con este SDK

* Instalar e inicializar el SDK en tu proyecto Android.
* Ejecutar flujos biométricos como **IDV Mobile** y **lanzamiento simplificado**.
* Configurar componentes y módulos según tus necesidades.
* Personalizar la experiencia (UI, textos y comportamientos).
* Consultar ejemplos funcionales en **Kotlin** y **Java**.
* Revisar los cambios incluidos en cada versión.

***

### Índice de contenidos

Accede directamente al apartado que necesites:

* [**Requisitos mínimos**](/sdks/sdk-mobile/android-sdk/requisitos-minimos)\
  Requisitos mínimos necesarios para integrar el SDK.
* [**Instalación**](/sdks/sdk-mobile/android-sdk/instalacion)\
  Integra el SDK en tu proyecto y prepara el entorno.
* [**Inicialización**](/sdks/sdk-mobile/android-sdk/inicializacion)\
  Inicialización y uso del SDK
  * [**Integración IDV Mobile**](/sdks/sdk-mobile/android-sdk/inicializacion/integracion-idv-mobile)\
    Implementa flujos de verificación de identidad.
  * [**Lanzamiento simplificado**](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado)\
    Ejecuta procesos biométricos con configuración mínima.
* [**Componentes y módulos**](/sdks/sdk-mobile/android-sdk/componentes-modulos)\
  Configura y combina los módulos disponibles del SDK.
* [**Manejo de errores**](/sdks/sdk-mobile/android-sdk/manejo-de-errores)\
  Detalle de los distintos errores que puede retornar el SDK.
* [**Personalización del SDK**](/sdks/sdk-mobile/android-sdk/personalizacion)\
  Ajusta la interfaz, los textos y el comportamiento.
* [**Aplicaciones de ejemplo**](/sdks/sdk-mobile/android-sdk/aplicaciones-de-ejemplo)\
  Ejemplos funcionales listos para ejecutar.
* [**Ajustes avanzados**](/sdks/sdk-mobile/android-sdk/ajustes-avanzados)\
  Configuraciones adicionales y casos especiales.
* [**Changelog**](/productos/idv-suite/flujos-and-integraciones/configuracion-tecnica-del-cliente/sdk-mobile/android-sdk/changelog)\
  Cambios, mejoras y correcciones por versión.


# Requisitos mínimos

Antes de integrar el SDK Mobile de Facephi, asegúrate de cumplir los siguientes requisitos:

* Sistema operativo Android 7.0 (API 24) o superior.
* Arquitecturas compatibles: ARM64, x86.
* Permisos requeridos:
  * Acceso a la cámara.
  * Conexión a internet.
* Android Studio actualizado.


# Instalación

Integra el SDK Mobile de Facephi en tu aplicación Android para ejecutar procesos de verificación biométrica de forma rápida y segura.

## Qué incluye el SDK

El SDK Mobile está compuesto por un conjunto de **librerías modulares (componentes)** que te permiten construir una solución biométrica adaptada a cada caso de uso.

## Requisitos mínimos

Antes de empezar, asegúrate de que tu proyecto cumple estos requisitos:

* **Android minSdk:** 24
* **Android API:** 35
* **Kotlin:** 2.2.21
* **Android Gradle Plugin:** 8.13.1

***

## 1. Configurar el repositorio privado

Por motivos de seguridad y mantenimiento, los componentes del SDK Mobile se distribuyen a través de un **repositorio privado**.

Para acceder a él necesitas credenciales, que debes solicitar al **equipo de soporte de Facephi**.

Una vez las tengas, añade el repositorio en el archivo `settings.gradle`:

```kts
mavenCentral()
maven {
    Properties props = new Properties()
    def propsFile = new File('local.properties')
    if(propsFile.exists()){
        props.load(new FileInputStream(propsFile))
    }
    name="external"
    url = uri("https://facephicorp.jfrog.io/artifactory/maven-pro-fphi")
    credentials {
        username = props["artifactory.user"] ?: System.getenv("USERNAME_ARTIFACTORY")
        password = props["artifactory.token"] ?: System.getenv("TOKEN_ARTIFACTORY")
    }
}
```

## **2. Añadir las credenciales**

Incluye las credenciales en el archivo `local.properties`

```kts
artifactory.user=YOUR_CREDENTIALS_USERNAME
artifactory.token=YOUR_CREDENTIALS_TOKEN
```

## 3. Declarar la dependencia base

La dependencia **obligatoria** para usar el SDK es la siguiente:

```kts
implementation "com.facephi.androidsdk:sdk:$version"
```

A partir de aquí, añade las dependencias de los **componentes** que vayas a utilizar según tu caso de uso.

***

## Soporte

Si tienes dudas o problemas durante la instalación, contacta con el **Soporte Técnico de Facephi**.


# Inicialización

El SDK puede ser utilizado para capturas biométricas:

* [Orquestadas](/sdks/sdk-mobile/android-sdk/inicializacion/integracion-idv-mobile): Mediante el uso de IDV Suite y la configuración de flujos y comportamientos en un backoffice.
* [Invididuales](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado): Mediante el uso y gestión de los componentes desde una aplicación móvil.


# Integración IDV Mobile

## Qué es IDV Mobile

**IDV (Identity Verification)** es el flujo que permite verificar y autenticar la identidad de una persona mediante la captura y validación de **rasgos biométricos**.

El flujo se configura previamente en la **plataforma de Facephi** y se ejecuta en la aplicación mediante su identificador (`flowId`).

## Dependencias necesarias

Para ejecutar flujos de IDV en Android debes añadir, además del SDK base, los **componentes específicos** que participen en el proceso.

```kotlin
implementation("com.facephi.androidsdk:sdk:$version") 
implementation("com.facephi.androidsdk:tracking_component:$version") 
implementation("com.facephi.androidsdk:selphi_component:$version") 
implementation("com.facephi.androidsdk:selphid_component:$version")
implementation("com.facephi.androidsdk:video_recording_component:$version")
implementation("com.facephi.androidsdk:capture_component:$version")
```

> Añade únicamente los componentes necesarios según el flujo configurado en plataforma.

## Inicializar del SDK <a href="#iniciacion-de-sdk" id="iniciacion-de-sdk"></a>

El SDK se gestiona a través de un controlador principal (`SDKController`) que debe inicializarse antes de lanzar cualquier flujo.

El **apiKey de licencia** lo proporciona el equipo de Facephi.

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOnline(EnvironmentLicensingData(
        apiKey = "..."
    )),
    trackingController = TrackingController()
)
val result = SDKController.initSdk(sdkConfig)
when (result) {
    is SdkResult.Error -> {
        Log.d("INIT SDK ERROR: ${result.error}")
    }
    is SdkResult.Success -> {
        Log.d("INIT SDK OK")
    }
}
```

Tras una inicialización correcta, el SDK queda preparado para ejecutar los flujos configurados.

## Lanzar un flujo de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El flujo de IDV se lanza mediante un `FlowController`, indicando:

* El **ID del flujo** configurado en plataforma (`flowId`).
* El **ID del cliente** (`customerId`).
* La lista de **controladores** que participan en el proceso.
* Opcionalmente, el **ID de autenticación** (`authenticationId`) para asociar el flujo a una autenticación concreta.
* Opcionalmente, los identificadores `resumeOperationId` y `resumeSessionId` para continuar una operación o sesión ya existente.

Ejemplos de controladores habituales:

* `FSelphiController` → Captura facial.
* `FSelphIDController` → Captura de documentos.
* `FStartVideoRecordingController` / `FStopVideoRecordingController` → Grabación del proceso.

```kotlin
val flowController = FlowController (
     FlowConfigurationData(
            id = "flowId",
            controllers = listOf(FSelphiController(), FSelphIDController()),
            customerId = "customerId",
            authenticationId = "authenticationId",
            resumeOperationId = "operationId",
            resumeSessionId = "sessionId",
        ))
SDKController.launch(flowController)

```

Si no necesitas reanudar una operación, puedes omitir `authenticationId`, `resumeOperationId` y `resumeSessionId`. El SDK creará los identificadores internos durante el inicio del flujo.

Para recibir la salida del flujo, observa `stateFlow` antes o durante el lanzamiento:

```kotlin
viewModelScope.launch {
    flowController.stateFlow.collect { flowResult ->
        val result = flowResult.result
        when (result) {
            is SdkResult.Success -> {
                val step = flowResult.step
                val data = result.data
                val isFlowFinished = flowResult.flowFinish
            }
            is SdkResult.Error -> {
                val error = result.error
            }
        }
    }
}
```

Cada emisión devuelve un `SdkFlowResult` con el paso (`step`), el resultado del paso u operación (`result`) y el indicador `flowFinish`, que informa si el flujo ha finalizado.

## Consultar flujos disponibles

Si necesitas obtener los flujos disponibles antes de lanzar uno de ellos, utiliza:

```kotlin
val list = SDKController.getFlowIntegrationData()
```

La función devuelve un listado con los **ID de flujo** y su **tipo de operación**.


# Lanzamiento simplificado

Esta sección muestra ejemplos prácticos para integrar y utilizar el SDK de Facephi en aplicaciones móviles Android, adaptados a los flujos de verificación más comunes.

## Inicializar el SDK <a href="#id-22-inicializar-el-sdk" id="id-22-inicializar-el-sdk"></a>

El SDK funciona a través de un **controlador principal (`SDKController`)**. Facephi proporcionará el `apiKey` de la licencia necesario para la inicialización.

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOnline(EnvironmentLicensingData(
            apiKey = "...")
      )),
)

val result = SDKController.initSdk(sdkConfig)

when (result) {
  is SdkResult.Success -> Log.d("APP: INIT SDK: OK")
  is SdkResult.Error -> Log.d(
          "APP: INIT SDK: KO - ${result.error.name}"
        )
}

if (BuildConfig.DEBUG) {
    SDKController.enableDebugMode()
}
```

## Iniciar operación <a href="#id-23-iniciar-operacion" id="id-23-iniciar-operacion"></a>

Antes de lanzar cualquier componente, es obligatorio **iniciar una operación**.

Este método tiene los siguientes parámetros de entrada:

1. **operationType**: Indica si se va a hacer un proceso de ONBOARDING o de AUTHENTICATION.
2. **customerId**: Identificador del usuario (controlado a nivel de aplicación).
3. **steps**: Lista de pasos de la operación si se han definido previamente.
4. **enableTracking**: Indica si la operación debe enviar eventos de tracking. Por defecto es `true`.

```kotlin
val result = SDKController.newOperation(
        operationType = OperationType.ONBOARDING,
        customerId = "customer_id",
        steps = listOf(Step.SELPHI_COMPONENT, Step.SELPHID_COMPONENT),
        enableTracking = true)
when (result) {
    is SdkResult.Success -> {
        Timber.d("APP: NEW OPERATION OK")
        Timber.d("Session ID: ${result.data.sessionId}")
        Timber.d("Operation ID: ${result.data.operationId}")
    }
    is SdkResult.Error -> {
        Timber.d("APP: NEW OPERATION ERROR: ${result.error.name}")
    }
}
```

Cuando la operación se crea correctamente, `result.data` contiene un `OperationResult` con `sessionId`, `operationId`, `type` y `customerId`. Estos valores identifican la sesión y la operación activa, y pueden usarse para trazabilidad o para enlazar llamadas posteriores con la plataforma.

{% hint style="info" %}
Si la creación de una nueva operación devuelve un error del tipo **INTERNAL\_ERROR** se debe principalmente a un problema de **seguridad**. Para poder investigar la causa, es posible recuperar el token asociado al error, el cual proporciona información adicional para su análisis.

```
if (result.error is SdkError.INTERNAL_ERROR){
    val token = (result.error as SdkError.INTERNAL_ERROR).error
}
```

{% endhint %}

## Lanzamiento de componentes <a href="#id-24-lanzamiento-de-los-componentes" id="id-24-lanzamiento-de-los-componentes"></a>

Cada componente tiene su propio controlador y se lanza desde `SDKController`.

```kotlin
val result = SDKController.launch(ExampleController(ConfigurationData()))
when (result) {
    is SdkResult.Success -> {
        //Result OK
        result.data
    }
    is SdkResult.Error -> {
        //Result KO
        result.error.name
    }
}
```

El resultado de `launch` mantiene la estructura común `SdkResult`: en `Success`, `data` contiene la salida propia del componente lanzado; en `Error`, `error` contiene el error específico del componente o del SDK.

***

## Seguridad <a href="#id-24-lanzamiento-de-los-componentes" id="id-24-lanzamiento-de-los-componentes"></a>

El SDK de Android incorpora un sistema de seguridad destinado a detectar y bloquear entornos potencialmente poco fiables o que puedan indicar intentos de ataque.<br>

Este mecanismo está habilitado por defecto, permite identificar situaciones que podrían comprometer la seguridad y previene la ejecución del SDK en contextos que no se consideran seguros:

```
SDKController.securityMode(enable: Boolean) 
```

***


# Componentes


# Conexión con plataforma

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

El envío de eventos a la plataforma se realiza con el ***Tracking Component***.

Éste se encarga de realizar el trackeo y la monitorización de la información obtenida durante la ejecución de las operaciones. Se podrá realizar el seguimiento en tiempo real de estos datos en la **Plataforma**, mientras se está ejecutando el proceso en el dispositivo del cliente.

Al contrario que ocurre con el resto, este componente no funciona individualmente, trabaja de forma transversal al resto de componentes instalados en la *SDKMobile*.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kts
implementation "com.facephi.androidsdk:tracking_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

<table data-header-hidden><thead><tr><th width="239.2734375"></th><th></th></tr></thead><tbody><tr><td><strong>Controlador</strong></td><td><strong>Descripción</strong></td></tr><tr><td>TrackingController</td><td>Controlador principal de tracking</td></tr><tr><td>TrackingErrorController</td><td>Controlador para <strong>gestionar</strong> los posibles <strong>errores</strong> que ocurran</td></tr><tr><td>ExtraDataController</td><td>Controlador para obtener el <strong>ExtraData</strong> que permite la <strong>comunicación</strong> desde cliente con el servidor con <strong>SelphIDSdk</strong> instalado.</td></tr></tbody></table>

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Se debe incluir el controlador durante la inicialización de la SDK.

```kotlin
SDKController.initSdk(
    ...
    trackingController = TrackingController(),
)
```

### Control de errores <a href="#id-41-control-de-errores" id="id-41-control-de-errores"></a>

Se podrá configurar el callback para controlar los errores de tracking:

```kotlin
SDKController.launch(
     TrackingErrorController {
        Napier.d("Tracking Error: ${it.name} - ${it.error} - ${it.stepType}")
     }
)
```

## Información avanzada <a href="#id-5-informacion-avanzada" id="id-5-informacion-avanzada"></a>

### Controladores Adicionales <a href="#id-51-controladores-adicionales" id="id-51-controladores-adicionales"></a>

#### **ExtraDataController**

Este controlador (*ExtraDataController*) permite obtener un identificador de la operación actual. Este dato se enviará con al backend donde se realizarán las verificaciones pertinentes.

La llamada para obtener al extraData, **necesita la información de la operación en curso,** lo cual **obliga** a que se haya **realizado** con anterioridad un ***newOperation***.

```kotlin
val result = SDKController.launch(
    ExtraDataController()
)
when (result) {
    is SdkResult.Success -> logs.add("ExtraData: OK")
    is SdkResult.Error -> logs.add(
        "ExtraData: KO - ${result.error.name}"
    )
}
```

### Recepción de errores <a href="#id-52-recepcion-de-errores" id="id-52-recepcion-de-errores"></a>

En la parte del error, dispondremos de la clase TrackingError. La clase devolverá 3 campos:

* name: String con el nombre del error
* error: Información addicional en el caso de que sea necesaria
* stepType: Componente del SDK en el que ha fallado el envío del evento

Listado de errores:

* **APPLICATION\_CONTEXT\_ERROR**: Error en la inicialización del contexto
* **ASSET\_LINK**: Error al enviar el enlace del recurso
* **ASSET\_UPLOAD**: Error durante la carga del recurso
* **COMPONENT\_LICENSE\_ERROR**: Licencia del componente ausente o no válida
* **CUSTOMER\_ID**: Error al obtener o validar el ID del cliente
* **DEVICE\_EVENT\_ERROR**: Fallo durante un evento relacionado con el dispositivo
* **EMPTY\_LICENSE**: Datos de licencia vacíos o inexistentes
* **FLOW**: Error durante el flujo de ejecución
* **INITIALIZATION\_ERROR**: Fallo general en la inicialización
* **INIT\_IDS\_ERROR**: Error al generar o asignar IDs durante la inicialización
* **INIT\_OPERATION**: Operación fallida en la fase de inicialización
* **LICENSE\_ERROR**: Licencia inválida o corrupta
* **MANAGER\_NOT\_INITIALIZED**: Se intentó usar el gestor sin inicializarlo
* **NETWORK\_CONNECTION**: Problema con la conexión de red
* **NETWORK\_ERROR**: Falla genérica de red
* **NO\_OPERATION\_CREATED\_ERROR**: No se creó ninguna operación cuando se esperaba
* **OCR\_DATA**: Error al procesar los datos de OCR
* **OPERATION\_NOT\_CREATED**: No se generó la operación esperada
* **OPERATION\_ID**: ID de operación inválido o ausente
* **SESSION\_ID**: Error con la identificación de sesión
* **SIGNATURE\_RESULT**: Fallo en el proceso o resultado de firma
* **STEP\_CHANGE**: Transición de paso inesperada o inválida
* **STEP\_RESULT\_CANCELLED**: El paso fue cancelado de forma inesperada
* **STEP\_RESULT\_ERROR**: El paso finalizó con un error
* **STEP\_RESULT\_EXPIRED**: El resultado del paso expiró antes de completarse
* **STEP\_RESULT\_SUCCEEDED**: El paso tuvo éxito pero generó un problema inesperado
* **TOKEN\_ERROR**: Token ausente, expirado o inválido
* **ADVANCED\_TRACKING\_UPLOAD**: Fallo al subir los datos de seguimiento avanzado
* **TENANT\_ID\_EMPTY\_ERROR**: El ID del tenant estaba vacío o ausente
* **ADVANCED\_TRACKING\_SERIALIZATION\_ERROR**: Error al serializar los datos de seguimiento avanzado
* **ADVANCED\_TRACKING\_VALIDATION\_ERROR**: Fallo en la validación de los datos de seguimiento
* **TOKENIZER\_ERROR**: Error durante el proceso de tokenización


# Captura facial - Selphi

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza mediante el **Selphi Component**.

Este componente se encarga de capturar un selfie del usuario y extraer sus características faciales más relevantes. Durante el proceso se realizan, entre otros, los siguientes pasos:

* Gestión interna de cámaras y permisos.
* Asistencia guiada durante la captura facial.
* Generación de plantillas biométricas e imágenes del usuario.

En la sección [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se describen los pasos básicos para la integración del SDK. En esta página se detalla la información específica necesaria para lanzar y configurar este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kotlin
implementation "com.facephi.androidsdk:selphi_component:$version"
```

***

## Controladores disponibles

Este componente incluye varios controladores, cada uno orientado a una funcionalidad concreta.

| Controlador                 | Descripción                                           |
| --------------------------- | ----------------------------------------------------- |
| `SelphiController`          | Controlador principal de reconocimiento facial        |
| `RawTemplateController`     | Generación de un `RawTemplate` a partir de una imagen |
| `SignatureSelphiController` | Firma de un proceso utilizando una captura facial     |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación el componente puede lanzarse utilizando cualquiera de sus controladores.

```kotlin
val response = SDKController.launch(
    SelphiController(SelphiConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("Selphi: ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente es necesario crear un objeto `SelphiConfigurationData`, que define el comportamiento del widget.

```kotlin
SelphiConfigurationData(
  resourcesPath = "resources_file.zip",
  livenessMode = SelphiFaceLivenessMode.NONE
)
```

El componente permite los siguientes modos de detección de vida:

* `SelphiFaceLivenessMode.NONE`
* `SelphiFaceLivenessMode.PASSIVE`
* `SelphiFaceLivenessMode.MOVE`

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El resultado del lanzamiento se devuelve como un objeto `SdkResult`, que puede indicar un resultado correcto o un error.

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'SelphiError'.

Listado de errores:

* SPI\_ACTIVITY\_RESULT\_ERROR: El resultado de la actividad es incorrecto.
* SPI\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad recibido en el msg es incorrecto.
* SPI\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* SPI\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Configuración del extractor incorrecta.
* SPI\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* SPI\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* SPI\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK.
* SPI\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* SPI\_CONTROL\_NOT\_INITIALIZATED\_ERROR: Widget: Error de inicialización.
* SPI\_EMPTY\_LICENSE: El String de licencia está vacío.
* SPI\_EXTRACTION\_LICENSE\_ERROR: Widget: Error de licencia.
* SPI\_FETCH\_DATA\_ERROR: Error en la recogida del resultado.
* SPI\_FLOW\_ERROR: Error en el proceso de flow.
* SPI\_HARDWARE\_ERROR: Widget: Error de hardware.
* SPI\_INITIALIZATION\_ERROR: Error de inicialización.
* SPI\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos.
* SPI\_NO\_DATA\_ERROR: Los datos de entrada son nulos.
* SPI\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* SPI\_RESOURCES\_NOT\_FOUND: No se ha encontrado el zip de recursos.
* SPI\_SETTINGS\_PERMISSION\_ERROR: Widget: Error de permisos.
* SPI\_TEMPLATE\_ERROR:
* SPI\_TIMEOUT: Timeout en el proceso.
* SPI\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Error en la captura.
* SPI\_UNKNOWN\_ERROR: Error desconocido.
* SPI\_WIDGET\_RESULT\_DATA\_ERROR: Error en los datos de salida del widget.

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

Cuando el resultado es correcto (`SdkResult.Success`), se obtiene un objeto `SelphiResult`.

Las imágenes se devuelven en formato `SdkImage`. Es posible acceder al bitmap mediante `image.bitmap`.\
Para convertir una imagen a Base64:

```kotlin
Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)
```

#### Campos devueltos

* `templateRaw`\
  Plantilla en bruto generada tras la extracción. Válida para procesos de matching.
* `template`\
  Plantilla procesada tras la extracción. Válida para procesos de matching.
* `bestImage`\
  Mejor imagen capturada en resolución original. Esta imagen tiene el tamaño original extraída de la cámara. Válida para el proceso de liveness.
* `bestImageCropped`\
  Imagen recortada centrada en la cara del usuario. Se obtiene a partir de la *bestImage*.
* `logImages`\
  Lista con las 5 mejores imágenes (requiere `logImages = true`).
* `bestImageTokenized`\
  Mejor imagen cifrada del proceso. Válida para el proceso de liveness.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

### Controladores Adicionales <a href="#id-71-controladores-adicionales" id="id-71-controladores-adicionales"></a>

**SignatureSelphiController**

Funciona de forma equivalente a `SelphiController`, con la diferencia de que genera un fichero de firma en la plataforma.

**RawTemplateController**

Permite generar un `RawTemplate` a partir de una imagen (`Bitmap`).

Ejemplo de uso:

```kotlin
val result = SDKController.launch(
    RawTemplateController(SdkImage(image))
)
when (result) {
    is SdkResult.Error -> Napier.d("GenerateRaw: KO - ${result.error}")
    is SdkResult.Success -> result.data
}
```

### Configuración avanzada

El comportamiento del componente se define mediante `SelphiConfigurationData`.

#### Parámetros disponibles

* `resourcesPath`\
  Nombre del archivo ZIP de recursos (ubicado en `assets`). Ejemplo: “resources-selphi-2-0.zip“.

<div align="center"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-15ce71837bf3d4cff1f1509e00d49ef3c005ef31%2Fassets.png?alt=media" alt=""><figcaption></figcaption></figure></div>

* `cropPercent`\
  Porcentaje de recorte de la cara. Cuanto mayor sea el número mayor será el recorte del rectángulo con respecto a la cara.
* `cropImageDebug`\
  Muestra información de depuración del recorte.
* `showResultAfterCapture`\
  Muestra una pantalla de confirmación tras la captura. Se le da al usuario la posibilidad de repetir el proceso de captura si la imagen que se obtuvo no fuera correcta.
* `showTutorial`\
  Activa la pantalla de tutorial. Se explica de forma intuitiva cómo se realiza la captura.
* `livenessMode`\
  Modo de detección de vida (`NONE`, `PASSIVE`, `MOVE`).
  * SelphiFaceLivenessMode.NONE: Indica que no debe activarse el modo detección de foto en los procesos de autenticación.
  * SelphiFaceLivenessMode.PASSIVE: Indica que la prueba de vida pasiva se realiza en el servidor, enviando para tal fin la “BestImage” o el “TemplateRaw” correspondiente.
  * SelphiFaceLivenessMode.MOVE: Indica que el test de liveness es activo, mostrando unas instrucciones durante la captura, y devolviendo el correspondiente resultado del proceso.
* `stabilizationMode`\
  Obliga al usuario a mantener la cabeza estable antes de capturar, mirando al frente y sin mover la cabeza.
* `cameraFlashEnabled`\
  Activa el flash de la cámara.
* `fullscreen`\
  Prioriza la visualización a pantalla completa.
* `templateRawOptimized`\
  Optimiza el `templateRaw` generado.
* `qrMode`\
  Activa la lectura de QR previa al proceso de autenticación.
* `videoFilename`\
  Ruta absoluta para grabar vídeo del proceso. La aplicación es la responsable de solicitar los permisos necesarios al teléfono en caso de requerirlos.
* `viewsContent`\
  Configuración avanzada de vistas mediante XML. Esta propiedad no altera el contenido del archivo de recursos.
* `showDiagnostic`\
  Muestra pantallas de diagnóstico.
* `logImages`\
  Devuelve las 5 mejores imágenes capturadas.
* `showPreviousTip`\
  Muestra una pantalla informativa previa a la captura.
* `extractionDuration`\
  Duración del proceso de extracción.
* `cameraPreferred`\
  Cámara preferida (`FRONT`, `BACK`).
* `vibrationEnabled`\
  Feedback de vibración al finalizar.
* `moveSuccessfulAttempts`\
  Reintentos permitidos en capturas correctas (por defecto 1).
* `moveFailedAttempts`\
  Reintentos permitidos en capturas incorrectas (por defecto 2).

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (explicados en [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente permite su propia personalización.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse sobrescribiendo los valores en un fichero XML de strings.

| **Name**                                        | **Value**                                                                                                            |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| selphi\_component\_timeout\_title               | Tiempo superado                                                                                                      |
| selphi\_component\_timeout\_desc                | No hemos podido identificarte. Inténtalo de nuevo                                                                    |
| selphi\_component\_internal\_error\_title       | Hubo un problema técnico                                                                                             |
| selphi\_component\_internal\_error\_desc        | Pedimos disculpas. No se ha podido hacer la captura                                                                  |
| selphi\_component\_tip\_message                 | Coloca tu cara en el centro del círculo                                                                              |
| selphi\_component\_tip\_message\_alt            | Coloca tu cara en el centro del círculo                                                                              |
| selphi\_component\_tip\_anim\_alt               | Una persona muestra su cara dentro del círculo y la aplicación le hace una foto.                                     |
| selphi\_component\_tip\_title                   | Reconocimiento facial                                                                                                |
| selphi\_component\_tip\_button                  | COMENZAR                                                                                                             |
| selphi\_component\_tip\_button\_alt             | Comenzar captura de rostro                                                                                           |
| selphi\_component\_tip\_move\_message           | Coloca tu cara en el centro del círculo y sigue las indicaciones                                                     |
| selphi\_component\_tip\_move\_message\_alt      | Coloca tu cara en el centro del círculo y sigue las indicaciones                                                     |
| selphi\_component\_tip\_move\_anim\_alt         | Una persona muestra su cara dentro del círculo, la mueve ligeramente hacia un lado y la aplicación le hace una foto. |
| selphi\_component\_tip\_move\_title             | Reconocimiento facial                                                                                                |
| selphi\_component\_tip\_move\_button            | COMENZAR                                                                                                             |
| selphi\_component\_qr\_tip\_title               | Escanea el código QR                                                                                                 |
| selphi\_component\_qr\_tip\_message             | Enfoca el código QR dentro del recuadro                                                                              |
| selphi\_component\_qr\_tip\_anim\_alt           | Enfoca el código QR dentro del recuadro                                                                              |
| selphi\_component\_qr\_tip\_button              | Comenzar                                                                                                             |
| selphi\_component\_tip\_close\_button\_alt      | Volver                                                                                                               |
| selphi\_component\_tip\_info\_button\_alt       | Ver consejos                                                                                                         |
| selphi\_component\_tutorial\_message\_1         | Coloca tu cara en el centro y mira de frente a la cámara.                                                            |
| selphi\_component\_tutorial\_message\_2         | Retira cualquier elemento que cubra tu cara.                                                                         |
| selphi\_component\_tutorial\_message\_3         | Busca un entorno bien iluminado, sin sombras sobre tu rostro.                                                        |
| selphi\_component\_tutorial\_1\_anim\_alt       | La foto se realiza cuando la persona está en el centro.                                                              |
| selphi\_component\_tutorial\_2\_anim\_alt       | Una persona se quita las gafas de sol y se retira el pelo de los ojos.                                               |
| selphi\_component\_tutorial\_3\_anim\_alt       | La imagen aparece oscura y una persona enciende la luz.                                                              |
| selphi\_component\_tutorial\_close\_button\_alt | Volver al tutorial previo                                                                                            |

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Las animaciones Lottie pueden sobrescribirse añadiendo los archivos con el mismo nombre en `res/raw/`.

```
selphi_anim_prev_tip.json
selphi_anim_prev_tip_move.json
selphi_anim_tuto_m_1.json
selphi_anim_tuto_m_2.json
selphi_anim_tuto_m_3.json
```


# Captura facial con IAD - Selphi

> #### **Diferencias con la captura facial estándar**
>
> El **Selphi IAD Component** es funcionalmente equivalente al **Selphi Component** estándar, incorporando controles adicionales de seguridad orientados a la detección de ataques de inyección de vídeo y entornos de captura no confiables.
>
> La integración, configuración y flujo de uso del componente son los mismos. La principal diferencia funcional es la inclusión del campo `iad` en el resultado (`SelphiResult`), que contiene la información del análisis antifraude preparada para su verificación en servidor.
>
> Para su uso es necesaria una nueva licencia y sustituir la dependencia del componente estándar por:
>
> ```java
> implementation "com.facephi.androidsdk:selphi_iad_component:$version"
> ```

{% hint style="info" %}
Este componente tiene dos restricciones importantes:

* Dispositivos con **mínimo 3 GB de RAM**.
* **Cámara delantera** con preview de **1920x1080 o superior**.
  {% endhint %}

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial con detección de ataques de inyección de vídeo se realiza mediante el **Selphi IAD Component**.

Este componente se encarga de capturar un selfie del usuario y extraer sus características faciales más relevantes incorporando un conjunto de controles de seguridad preventivos orientados a detectar entornos no confiables. Durante el proceso se realizan, entre otros, los siguientes pasos:

* Gestión interna de cámaras y permisos.
* Detección de intentos de suplantación mediante vídeos o fuentes de cámara manipuladas.
* Asistencia guiada durante la captura facial.
* Generación de plantillas biométricas e imágenes del usuario.

En la sección [Lanzamiento simplificado](#id-4-lanzamiento-simplificado) se describen los pasos básicos para la integración del SDK. En esta página se detalla la información específica necesaria para lanzar y configurar este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kotlin
implementation "com.facephi.androidsdk:selphi_iad_component:$version"
```

***

## Controladores disponibles

Este componente incluye varios controladores, cada uno orientado a una funcionalidad concreta.

| Controlador                 | Descripción                                           |
| --------------------------- | ----------------------------------------------------- |
| `SelphiController`          | Controlador principal de reconocimiento facial        |
| `RawTemplateController`     | Generación de un `RawTemplate` a partir de una imagen |
| `SignatureSelphiController` | Firma de un proceso utilizando una captura facial     |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación el componente puede lanzarse utilizando cualquiera de sus controladores.

```kotlin
val response = SDKController.launch(
    SelphiController(SelphiConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("Selphi: ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente es necesario crear un objeto `SelphiConfigurationData`, que define el comportamiento del widget.

```kotlin
SelphiConfigurationData(
  resourcesPath = "resources_file.zip",
  livenessMode = SelphiFaceLivenessMode.NONE
)
```

El componente permite los siguientes modos de detección de vida:

* `SelphiFaceLivenessMode.NONE`
* `SelphiFaceLivenessMode.PASSIVE`
* `SelphiFaceLivenessMode.MOVE`

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El resultado del lanzamiento se devuelve como un objeto `SdkResult`, que puede indicar un resultado correcto o un error (en los datos del resultado vendrá el campo que lleva la información asociada al IAD [Recepción del resultado correcto - data](https://app.gitbook.com/o/-M73Nx_oBKHNUEMhXiku/s/Uo71Qbj6jZQDavjc0U5X/~/edit/~/changes/537/soluciones-y-sdks/sdk-mobile/android-sdk/componentes-modulos/captura-facial-con-iad#id-62-recepcion-del-resultado-correcto-data))

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'SelphiError'.

Listado de errores:

* SPI\_ACTIVITY\_RESULT\_ERROR: El resultado de la actividad es incorrecto.
* SPI\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad recibido en el msg es incorrecto.
* SPI\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* SPI\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Configuración del extractor incorrecta.
* SPI\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* SPI\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* SPI\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK.
* SPI\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* SPI\_CONTROL\_NOT\_INITIALIZATED\_ERROR: Widget: Error de inicialización.
* SPI\_EMPTY\_LICENSE: El String de licencia está vacío.
* SPI\_EXTRACTION\_LICENSE\_ERROR: Widget: Error de licencia.
* SPI\_FETCH\_DATA\_ERROR: Error en la recogida del resultado.
* SPI\_FLOW\_ERROR: Error en el proceso de flow.
* SPI\_HARDWARE\_ERROR: Widget: Error de hardware.
* SPI\_INITIALIZATION\_ERROR: Error de inicialización.
* SPI\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos.
* SPI\_NO\_DATA\_ERROR: Los datos de entrada son nulos.
* SPI\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* SPI\_RESOURCES\_NOT\_FOUND: No se ha encontrado el zip de recursos.
* SPI\_SETTINGS\_PERMISSION\_ERROR: Widget: Error de permisos.
* SPI\_TEMPLATE\_ERROR:
* SPI\_TIMEOUT: Timeout en el proceso.
* SPI\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Error en la captura.
* SPI\_UNKNOWN\_ERROR: Error desconocido.
* SPI\_WIDGET\_RESULT\_DATA\_ERROR: Error en los datos de salida del widget.

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

Cuando el resultado es correcto (`SdkResult.Success`), se obtiene un objeto `SelphiResult`.

Las imágenes se devuelven en formato `SdkImage`. Es posible acceder al bitmap mediante `image.bitmap`.\
Para convertir una imagen a Base64:

```kotlin
Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)
```

#### Campos devueltos

* `templateRaw`\
  Plantilla en bruto generada tras la extracción. Válida para procesos de matching.
* `template`\
  Plantilla procesada tras la extracción. Válida para procesos de matching.
* `bestImage`\
  Mejor imagen capturada en resolución original. Esta imagen tiene el tamaño original extraída de la cámara. Válida para el proceso de liveness.
* `bestImageCropped`\
  Imagen recortada centrada en la cara del usuario. Se obtiene a partir de la *bestImage*.
* `logImages`\
  Lista con las 5 mejores imágenes (requiere `logImages = true`).
* `bestImageTokenized`\
  Mejor imagen cifrada del proceso. Válida para el proceso de liveness.
* `bestImageTokenized`\
  Mejor imagen cifrada del proceso. Válida para el proceso de liveness.
* `iad`\
  Información obtenida en el análisis de ataques de inyección de vídeo preparada para su envío al servicio de verificación.
* `livenessDiagnostic`\
  Información del proceso de verificación que confirma que la persona está físicamente presente y es real.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

### Controladores Adicionales <a href="#id-71-controladores-adicionales" id="id-71-controladores-adicionales"></a>

**SignatureSelphiController**

Funciona de forma equivalente a `SelphiController`, con la diferencia de que genera un fichero de firma en la plataforma.

**RawTemplateController**

Permite generar un `RawTemplate` a partir de una imagen (`Bitmap`).

Ejemplo de uso:

```kotlin
val result = SDKController.launch(
    RawTemplateController(SdkImage(image))
)
when (result) {
    is SdkResult.Error -> Napier.d("GenerateRaw: KO - ${result.error}")
    is SdkResult.Success -> result.data
}
```

### Configuración avanzada

El comportamiento del componente se define mediante `SelphiConfigurationData`.

#### Parámetros disponibles

* `resourcesPath`\
  Nombre del archivo ZIP de recursos (ubicado en `assets`). Ejemplo: “resources-selphi-2-0.zip“.

<div align="center"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-15ce71837bf3d4cff1f1509e00d49ef3c005ef31%2Fassets.png?alt=media" alt=""><figcaption></figcaption></figure></div>

* `cropPercent`\
  Porcentaje de recorte de la cara. Cuanto mayor sea el número mayor será el recorte del rectángulo con respecto a la cara.
* `cropImageDebug`\
  Muestra información de depuración del recorte.
* `showResultAfterCapture`\
  Muestra una pantalla de confirmación tras la captura. Se le da al usuario la posibilidad de repetir el proceso de captura si la imagen que se obtuvo no fuera correcta.
* `showTutorial`\
  Activa la pantalla de tutorial. Se explica de forma intuitiva cómo se realiza la captura.
* `livenessMode`\
  Modo de detección de vida (`NONE`, `PASSIVE`, `MOVE`).
  * SelphiFaceLivenessMode.NONE: Indica que no debe activarse el modo detección de foto en los procesos de autenticación.
  * SelphiFaceLivenessMode.PASSIVE: Indica que la prueba de vida pasiva se realiza en el servidor, enviando para tal fin la “BestImage” o el “TemplateRaw” correspondiente.
  * SelphiFaceLivenessMode.MOVE: Indica que el test de liveness es activo, mostrando unas instrucciones durante la captura, y devolviendo el correspondiente resultado del proceso.
* `stabilizationMode`\
  Obliga al usuario a mantener la cabeza estable antes de capturar, mirando al frente y sin mover la cabeza.
* `cameraFlashEnabled`\
  Activa el flash de la cámara.
* `fullscreen`\
  Prioriza la visualización a pantalla completa.
* `templateRawOptimized`\
  Optimiza el `templateRaw` generado.
* `qrMode`\
  Activa la lectura de QR previa al proceso de autenticación.
* `videoFilename`\
  Ruta absoluta para grabar vídeo del proceso. La aplicación es la responsable de solicitar los permisos necesarios al teléfono en caso de requerirlos.
* `viewsContent`\
  Configuración avanzada de vistas mediante XML. Esta propiedad no altera el contenido del archivo de recursos.
* `showDiagnostic`\
  Muestra pantallas de diagnóstico.
* `logImages`\
  Devuelve las 5 mejores imágenes capturadas.
* `showPreviousTip`\
  Muestra una pantalla informativa previa a la captura.
* `extractionDuration`\
  Duración del proceso de extracción.
* `cameraPreferred`\
  Cámara preferida (`FRONT`, `BACK`).
* `vibrationEnabled`\
  Feedback de vibración al finalizar.
* `moveSuccessfulAttempts`\
  Reintentos permitidos en capturas correctas (por defecto 1).
* `moveFailedAttempts`\
  Reintentos permitidos en capturas incorrectas (por defecto 2).

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (explicados en [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente permite su propia personalización.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse sobrescribiendo los valores en un fichero XML de strings.

| **Name**                                        | **Value**                                                                                                            |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| selphi\_component\_timeout\_title               | Tiempo superado                                                                                                      |
| selphi\_component\_timeout\_desc                | No hemos podido identificarte. Inténtalo de nuevo                                                                    |
| selphi\_component\_internal\_error\_title       | Hubo un problema técnico                                                                                             |
| selphi\_component\_internal\_error\_desc        | Pedimos disculpas. No se ha podido hacer la captura                                                                  |
| selphi\_component\_tip\_message                 | Coloca tu cara en el centro del círculo                                                                              |
| selphi\_component\_tip\_message\_alt            | Coloca tu cara en el centro del círculo                                                                              |
| selphi\_component\_tip\_anim\_alt               | Una persona muestra su cara dentro del círculo y la aplicación le hace una foto.                                     |
| selphi\_component\_tip\_title                   | Reconocimiento facial                                                                                                |
| selphi\_component\_tip\_button                  | COMENZAR                                                                                                             |
| selphi\_component\_tip\_button\_alt             | Comenzar captura de rostro                                                                                           |
| selphi\_component\_tip\_move\_message           | Coloca tu cara en el centro del círculo y sigue las indicaciones                                                     |
| selphi\_component\_tip\_move\_message\_alt      | Coloca tu cara en el centro del círculo y sigue las indicaciones                                                     |
| selphi\_component\_tip\_move\_anim\_alt         | Una persona muestra su cara dentro del círculo, la mueve ligeramente hacia un lado y la aplicación le hace una foto. |
| selphi\_component\_tip\_move\_title             | Reconocimiento facial                                                                                                |
| selphi\_component\_tip\_move\_button            | COMENZAR                                                                                                             |
| selphi\_component\_qr\_tip\_title               | Escanea el código QR                                                                                                 |
| selphi\_component\_qr\_tip\_message             | Enfoca el código QR dentro del recuadro                                                                              |
| selphi\_component\_qr\_tip\_anim\_alt           | Enfoca el código QR dentro del recuadro                                                                              |
| selphi\_component\_qr\_tip\_button              | Comenzar                                                                                                             |
| selphi\_component\_tip\_close\_button\_alt      | Volver                                                                                                               |
| selphi\_component\_tip\_info\_button\_alt       | Ver consejos                                                                                                         |
| selphi\_component\_tutorial\_message\_1         | Coloca tu cara en el centro y mira de frente a la cámara.                                                            |
| selphi\_component\_tutorial\_message\_2         | Retira cualquier elemento que cubra tu cara.                                                                         |
| selphi\_component\_tutorial\_message\_3         | Busca un entorno bien iluminado, sin sombras sobre tu rostro.                                                        |
| selphi\_component\_tutorial\_1\_anim\_alt       | La foto se realiza cuando la persona está en el centro.                                                              |
| selphi\_component\_tutorial\_2\_anim\_alt       | Una persona se quita las gafas de sol y se retira el pelo de los ojos.                                               |
| selphi\_component\_tutorial\_3\_anim\_alt       | La imagen aparece oscura y una persona enciende la luz.                                                              |
| selphi\_component\_tutorial\_close\_button\_alt | Volver al tutorial previo                                                                                            |

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Las animaciones Lottie pueden sobrescribirse añadiendo los archivos con el mismo nombre en `res/raw/`.

```
selphi_anim_prev_tip.json
selphi_anim_prev_tip_move.json
selphi_anim_tuto_m_1.json
selphi_anim_tuto_m_2.json
selphi_anim_tuto_m_3.json
```


# Captura de documentos - SelphID

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura de documentos se realiza mediante el **SelphID Component**.

Este componente se encarga de capturar documentos de identidad y analizar la información obtenida. Durante el proceso se realizan, entre otros, los siguientes pasos:

* Gestión interna de cámaras y permisos.
* Asistencia guiada durante la captura del **anverso y reverso** del documento.
* Extracción de la información contenida en el documento.
* Obtención de imágenes del documento y de elementos asociados:
  * Cara del usuario.
  * Firma del usuario.
* Alto nivel de configuración:
  * Países.
  * Idiomas.
  * Tipos de documento.

En la sección [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se describen los pasos básicos para la integración del SDK.\
En esta página se detalla la información específica necesaria para lanzar y configurar este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**   | **Descripción**                                       |
| ----------------- | ----------------------------------------------------- |
| SelphIDController | Controlador principal de reconocimiento de documentos |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación, el componente puede lanzarse utilizando su controlador.

Lanzamiento de la captura facial:

```kotlin
val response = SDKController.launch(
    SelphIDController(SelphIDConfiguration(..))
)
when (response) {
    is SdkResult.Error -> Napier.d("SelphID: ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente es necesario crear un objeto **SelphIDConfigurationData**, que define el comportamiento del widget.

En la configuración básica:

* Es obligatorio definir el **país** y el **tipo de documento**.
* En el campo `specificData` se debe indicar el código de país correspondiente (por ejemplo, `ES` para España).

```kotlin
SelphIDConfiguration(
  resourcesPath = "resources_file.zip",
  wizardMode = true,
  specificData = "ES|<ALL>",
  documentType = SelphIDDocumentType.ID_CARD,
)
```

**Tipos de documento disponibles**

```
SelphIDDocumentType.ID_CARD
SelphIDDocumentType.PASSPORT
SelphIDDocumentType.DRIVERS_LICENSE
SelphIDDocumentType.FOREIGN_CARD
SelphIDDocumentType.CREDIT_CARD
SelphIDDocumentType.CUSTOM
SelphIDDocumentType.VISA
```

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El resultado del lanzamiento se devuelve como un objeto **SdkResult**, que puede indicar un resultado correcto o un error.

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devuelven como un objeto **SelphIdError**.

**Listado de errores**

* SPD\_ACTIVITY\_RESULT\_ERROR: El resultado de la actividad es incorrecto.
* SPD\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad recibido en el msg es incorrecto.
* SPD\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* SPD\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Configuración del extractor incorrecta
* SPD\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* SPD\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* SPD\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK.
* SPD\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* SPD\_CONTROL\_NOT\_INITIALIZATED\_ERROR: Widget: Error de inicialización
* SPD\_EMPTY\_LICENSE: El String de licencia está vacío.
* SPD\_EXTRACTION\_LICENSE\_ERROR: Widget: Error de licencia
* SPD\_FETCH\_DATA\_ERROR: Error en la recogida del resultado.
* SPD\_FLOW\_ERROR: Error en el proceso de flow.
* SPD\_HARDWARE\_ERROR: Widget: Error de hardware
* SPD\_INITIALIZATION\_ERROR: Error de inicialización.
* SPD\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos.
* SPD\_MOVE\_FAIL: El usuario no se ha movido como se le ha especificado en el proceso.
* SPD\_NO\_DATA\_ERROR: Los datos de entrada son nulos.
* SPD\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* SPD\_RESOURCES\_NOT\_FOUND: No se ha encontrado el zip de recursos
* SPD\_SETTINGS\_PERMISSION\_ERROR: Widget: Error de permisos
* SPD\_TIMEOUT: Timeout en el proceso.
* SPD\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Error en la captura
* SPD\_UNKNOWN\_ERROR: Error desconocido
* SPD\_WIDGET\_RESULT\_DATA\_ERROR: Error en los datos de salida del widget

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

Cuando el resultado es correcto (`SdkResult.Success`), se obtiene un objeto **SelphIDResult**.

Las imágenes se devuelven en formato **SdkImage**.\
Es posible acceder al bitmap mediante `image.bitmap`.

Para convertir una imagen a Base64:

```kotlin
Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)
```

**Campos devueltos**

**frontDocument / tokenFrontDocument:**

La imagen frontal del documento procesada, limpiada y recortada por los bordes y su token correspondiente.

**backDocument / tokenBackDocument**

La imagen trasera del documento procesada, limpiada y recortada por los bordes y su token asociado.

**faceImage / tokenFaceImage**

La imagen del rostro que se ha encontrado en el documento, en caso de que exista y su token asociado.

Válida para el proceso de MATCHING FACIAL.

**documentCaptured**

Esta propiedad indica el modelo de documento que se ha capturado cuando se realiza una busqueda en modo SMSearch. De esta forma la aplicación puede conocer qué modelo, de entre todos los permitidos, se ha detectado.

**matchingSidesScore**

Esta propiedad devuelve un cálculo de la similitud de los datos leídos entre el front y el back del documento. El cálculo se realiza comprobando la similitud entre los campos comunes leídos en ambas caras. El resultado del cálculo será un valor entre 0.0 y 1.0 para el caso de que existan campos comunes en el documento. Cuanto mayor es el valor, más similares son los datos comparados. Si el cálculo devuelve -1.0 es que el documento no contiene campos comunes o aún no se tiene información de las dos caras.

**Propiedad captureProgress**

Esta propiedad devuelve el estado en el que se encontraba el proceso de captura cuando el widget terminó. Estos son los posibles valores:

```
Front_Detection_None = 0
Front_Detection_Uncertain = 1
Front_Detection_Completed = 2
Front_Document_Analyzed = 3
Back_Detection_None = 4
Back_Detection_Uncertain = 5
Back_Detection_Completed = 6
Back_Document_Analyzed = 7
```

* **0**: En la lectura del Front, el widget termino sin poder haber detectado nada. Generalmente cuando no se pone ningún documento.
* **1**: En la lectura del Front, el widget termino habiendo detectado parcialmente un documento. En este caso algunos de los elementos esperados se han conseguido detectar, pero no todos los necesarios.
* **2**: En la lectura del Front, el widget termino habiendo completado la detección de todos los elementos del documento. Si el widget acaba en este estado es porque el análisis de OCR no se ha podido completar con éxito.
* **3**: En la lectura del Front, el widget termino habiendo analizado y extraído todo el OCR del documento. Este es el estado en el que acabaría una lectura correcta del Front de un documento.

Los estados del **4** al **7** son exactamente iguales solo que se refieren al resultado del proceso cuando se analiza el back.

**ocrResults**

Este diccionario contiene todos los datos detectados en el documento. Las claves de cada campo están codificadas de tal forma que la propia clave contiene información de donde se ha obtenido el valor. Así, por ejemplo, la clave `Front/MRZ/DocumentNumber` indica el valor del DocumentNumber que se ha leído en el Front del documento y en la región del MRZ. Estas claves dependen del documento capturado y por tanto serán diferentes entre distintos países y modelos de documento. El diccionario también contiene claves con nombres más genéricos y que no llevan información relativa a la ubicación. Estas claves contienen el dato más completo de todos los leídos para dicho campo.

Estas claves son los siguientes:

* **FirstName**: El valor asociado a esta clave contiene el nombre del usuario.
* **LastName**: El valor asociado a esta clave contiene los apellidos del usuario.
* **DateOfBirth**: El valor asociado a esta clave contiene la fecha de nacimiento detectada en el documento.
* **Gender**: El valor asociado a esta clave contiene el sexo del usuario detectado en el documento.
* **Nationality**: El valor asociado a esta clave contiene la nacionalidad del usuario detectado en el documento.
* **DocumentNumber**: El valor asociado a esta clave contiene el número de documento.
* **DateOfExpiry**: El valor asociado a esta clave contiene la fecha de expiración del documento.
* **Issuer**: El valor asociado a esta clave contiene el editor del documento.
* **DateofIssue**: El valor asociado a esta clave contiene la fecha de expedición del documento.
* **PlaceOfBirth**: El valor asociado a esta clave contiene el lugar de nacimiento del usuario.
* **Address**: El valor asociado a esta clave contiene la dirección detectada en el documento.

Adicionalmente se añaden claves del propio objeto results para hacer más fácil su búsqueda:

* **DocumentCaptured**: Valor del modelo de documento que se ha capturado según el .xml de modelos. Corresponde a la propiedad documentCaptured.
* **MatchingSidesScore**: Valor que indica la correspondencia entre las caras leídas del documento. Corresponde a la propiedad matchingSidesScore.

**timeoutDiagnostic**

Esta propiedad devuelve una cadena de texto que explica por qué se ha agotado el tiempo de espera del widget. Esta cadena puede ser utilizada en una pantalla de tiempo de espera posterior donde la aplicación principal puede dar más información al usuario sobre lo ocurrido durante la captura del documento.

**countryCaptured**

País del documento.

**documentTypeCaptured**

Tipo de documento. Se corresponde con los del apartado 5.1.10.

**personalData**

Conjunto reducido de datos obtenidos del usuario:

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

**encodedDataImages**

Listado de imagenes obtenidas del modo de extracción de códigos de barra (versión mbsdr encodedDataFocusEnabled activo)

**tokenEncodedDataImages**

Listado de imgaenes tokenizadas obtenidas del modo de extracción de códigos de barra (versión mbsdr encodedDataFocusEnabled activo)

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

### Selector de documentos - OPCIONAL

**showDocumentSelector**

Activación de la vista de selector de documentos. Se presentará nada más lanzar el controlador.

**enabledCountries**

Listado de países en ISO2 que aparecerán en el selector. Si su valor es nulo o no contiene valores válidos, se mostrarán todos los disponibles por el SDK.

**enabledDocumentTypes**

Listado de tipos de documentos que aparecerán en el selector de tipos de documentos. Si su valor es nulo o no contiene valores, se mostrarán todos los disponibles por el SDK.

#### Configuración avanzada del componente

El comportamiento del componente se define mediante **SelphIDConfigurationData**.

**resourcesPath**

Indica el nombre de los recursos en formato zip del componente. Ejemplo: “resources-selphid-2-0.zip“.

Este nombre irá a buscar el fichero a la ruta de *assets*.

<div align="left"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-15ce71837bf3d4cff1f1509e00d49ef3c005ef31%2Fassets.png?alt=media" alt=""><figcaption></figcaption></figure></div>

**wizardMode**

Indica si el widget queda configurado para realizar la captura de ambas partes (frontal y trasera) del documento una a continuación de la otra. En este modo el widget solo se lanzaría una vez y al terminar de capturar el front, continuaría seguidamente con el back.

**showResultAfterCapture**

Indica si mostrar o no una pantalla con la imagen capturada del documento después del proceso de análisis. En esta pantalla se le da al usuario la posibilidad de repetir el proceso de captura si la imagen que se obtuvo del documento no fuera correcta.

**showTutorial**

Indica si el widget activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**tutorialOnly**

Indica si el widget se quiere lanzar solo para mostrar el tutorial.

**scanMode**

Indica el modo de escaneo OCR de los documentos. Dependiendo de la elección, se escanearán y buscarán varios tipos de documentos o uno en concreto. Este modo puede ser de tres tipos:

* **SelphIDScanMode.MODE\_GENERIC**: El modo genérico que permite escanear cualquier tipo de documento independiente del país o el tipo de documento. El resultado de este modo no es tan preciso como los siguientes pero permite escanear varios documentos estándar.
* **SelphIDScanMode.MODE\_SEARCH**: El modo de búsqueda permitirá utilizar una whitelist y blacklist, y buscará en los documentos que cumplan dichas condiciones. Estas condiciones se indican en la variable "specificData". De este modo se permite realizar la búsqueda acotando el número de plantillas, y haciendo que la búsqueda sea mucho más afinada que en el caso genérico.
* **SelphIDScanMode.MODE\_SPECIFIC**: Búsqueda de un documento específico. Estas condiciones se indican en la propiedad "specificData" que se muestra en lo sucesivo.

**specificData**

Esta propiedad permite definir qué documentos se escanearán durante el proceso, en caso de declarar el modo de escaneo (scanMode) a **MODE\_SEARCH** o **MODE\_SPECIFIC**.

Un ejemplo de configuración que permita escanear todos los documentos de nacionalidad española sería el siguiente:

```
val selphIDConfiguration = SelphIDConfigurationData(
    scanMode = SelphIDScanMode.MODE_SEARCH,
    specificData = "ES|<ALL>",  // Código ISO de España (ES)
)
```

**fullscreen**

Indica si la vista va a tener prioridad para mostrarse en pantalla completa, si el sistema lo permite.

**tokenImageQuality**

Indica la cantidad de calidad que se quiere recibir en las imágenes tokenizadas. Valor entre 0 y 1.

**documentType**

Los valores permitidos son los siguientes:

* **SelphIDDocumentType.ID\_CARD**: El widget queda configurado para realizar la captura de documentos de identidad.
* **SelphIDDocumentType.PASSPORT**: El widget queda configurado para realizar la captura de pasaportes.
* **SelphIDDocumentType.DRIVERS\_LICENSE**: El widget queda configurado para realizar la captura de licencias de conducción.
* **SelphIDDocumentType.FOREIGN\_CARD**: El widget queda configurado para realizar la captura de documentos extranjeros.
* **SelphIDDocumentType.CUSTOM**: El widget queda configurado para realizar la captura de otro tipo de documentos que no corresponden a ninguna de las categorías anteriores.
* **WidgetSelphIDDocumentType.VISA**: El widget queda configurado para realizar la captura del visado de un país. (SDK min 2.1.2)

**documentSide**

Los valores permitidos son los siguientes:

* **SelphIDDocumentSide.FRONT**: El widget queda configurado para realizar la captura de la parte frontal del documento.
* **SelphIDDocumentSide.BACK**: El widget queda configurado para realizar la captura de la parte trasera del documento.

**timeout**

Es un enumerado que define el timeout de la captura de un lado del documento. Tiene 3 posibles valores:

* SelphIDTimeout.SHORT: 15 segundos.
* SelphIDTimeout.MEDIUM: 20 segundos.
* SelphIDTimeout.LONG: 25 segundos.
* SelphIDTimeout.VERY\_LONG: 60 segundos.

**videoFilename**

Establece la ruta absoluta del nombre del archivo en el que se grabará un video del proceso de captura. La aplicación es la responsable de solicitar los permisos necesarios al teléfono en caso de que esa ruta requiera de permisos adicionales. El widget, por defecto, no realizará ningún proceso de grabación a menos que se especifique una ruta de archivo mediante este método.

**DocumentModels**

Esta propiedad permite, mediante una cadena en formato xml, configurar modelado de los documentos que el widget va a tratar de capturar. La definición de este modelado se encentra, por defecto, en un .xml de modelos que se encuentra en el .zip de recursos. Con esta propiedad se permite a una aplicación actualizar, en caliente, los modelados de los documentos.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**generateRawImages**

Esta propiedad configura el widget para devolver la imagen completa de la cámara que se utilizó para capturar el documento. Estas imágenes se devuelven en las propiedades `rawFrontDocument` y `rawBackDocument` del objeto `results` respectivamente.

**tokenPreviousCaptureData**

Cuando la captura del documento se realiza en 2 llamadas, esta propiedad permite pasar un diccionario con la información de la captura previa. De esta manera el widget puede combinar los resultados de ambas lecturas de una manera inteligente y así devolver la información combinada de ambas capturas. También permite al widget calcular un grado de similitud de los datos de ambas caras.

En el caso que la captura de ambas caras del documento se realice en una única llamada esto no es necesario ya que el widget internamente hace este proceso.

**translationsContent**

Esta propiedad avanzada permite, mediante una cadena en formato xml, configurar la traducción de los literales que se muestran durante el proceso.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**viewsContent**

Esta propiedad avanzada permite, mediante una cadena en formato xml, configurar las vistas del widget.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

**vibrationEnabled**

Indica si se desea un feedback de vibración al acabar el proceso.

**encodedDataFocusEnabled**

**Activa el modo de la fase de extracción de códigos de barra (versión mbsdr)**

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de la [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion) este componente permite modificar su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse sobrescribiendo los valores en un archivo XML de strings incluido en la aplicación cliente.

Ejemplos de claves disponibles:

#### Diagnóstico

| Name                                     | Value                                                                                    |
| ---------------------------------------- | ---------------------------------------------------------------------------------------- |
| `selphid_component_timeout_title`        | Tiempo superado                                                                          |
| `selphid_component_timeout_desc`         | Comprueba que el documento está dentro del recuadro y los datos son visibles.            |
| `selphid_component_timeout_front_desc`   | Comprueba que el frente del documento está dentro del recuadro y los datos son visibles. |
| `selphid_component_timeout_back_desc`    | Comprueba que el dorso del documento está dentro del recuadro y los datos son visibles.  |
| `selphid_component_internal_error_title` | Hubo un problema técnico                                                                 |
| `selphid_component_internal_error_desc`  | Pedimos disculpas. No se ha podido hacer la captura                                      |

#### Tip Previo

| Name                                      | Value                                                                                          |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `selphid_component_tip_message`           | Enfoca tu documento dentro del recuadro. La foto se hará automáticamente.                      |
| `selphid_component_tip_message_alt`       | Enfoca tu documento dentro del recuadro. La foto se hará automáticamente.                      |
| `selphid_component_tip_anim_id_alt`       | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical. |
| `selphid_component_tip_anim_passport_alt` | Coloca tu pasaporte en horizontal, y apunta con tu teléfono en posición vertical.              |
| `selphid_component_tip_anim_driving_alt`  | Coloca tu licencia de conducir en horizontal, y apunta con tu teléfono en posición vertical.   |
| `selphid_component_tip_title`             | Foto del documento                                                                             |
| `selphid_component_tip_button`            | COMENZAR                                                                                       |
| `selphid_component_tip_button_alt`        | Comenzar captura de documento                                                                  |
| `selphid_component_tip_close_button_alt`  | VOLVER                                                                                         |
| `selphid_component_tip_info_button_alt`   | Ver consejos                                                                                   |

#### Tutorial

| Name                                            | Value                                                                                          |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `selphid_component_tutorial_message_1`          | Busca un fondo con buen contraste.                                                             |
| `selphid_component_tutorial_message_2`          | Coloca el documento dentro del recuadro.                                                       |
| `selphid_component_tutorial_message_3`          | Evita brillos que dificulten la lectura del documento.                                         |
| `selphid_component_tutorial_1_anim_id_alt`      | Coloca el documento en una superficie con un color distinto al documento.                      |
| `selphid_component_tutorial_2_anim_id_alt`      | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical. |
| `selphid_component_tutorial_3_anim_id_alt`      | Aparecen reflejos sobre el documento.                                                          |
| `selphid_component_tutorial_1_anim_pass_alt`    | Coloca el pasaporte en una superficie con un color distinto al documento.                      |
| `selphid_component_tutorial_2_anim_pass_alt`    | Coloca tu pasaporte en horizontal, y apunta con tu teléfono en posición vertical.              |
| `selphid_component_tutorial_3_anim_pass_alt`    | Aparecen reflejos sobre el documento.                                                          |
| `selphid_component_tutorial_1_anim_driving_alt` | Coloca el documento en una superficie con un color distinto al documento.                      |
| `selphid_component_tutorial_2_anim_driving_alt` | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical. |
| `selphid_component_tutorial_3_anim_driving_alt` | Aparecen reflejos sobre el documento.                                                          |
| `selphid_component_tip_health_alt`              | Coloca tu tarjeta sanitaria en horizontal, y apunta con tu teléfono en posición vertical.      |
| `selphid_component_tutorial_1_anim_health_alt`  | Coloca la tarjeta sanitaria en una superficie con un color distinto al documento.              |
| `selphid_component_tutorial_2_anim_health_alt`  | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical. |
| `selphid_component_tutorial_3_anim_health_alt`  | Aparecen reflejos sobre el documento.                                                          |
| `selphid_component_tip_custom_alt`              | --                                                                                             |
| `selphid_component_tutorial_1_anim_custom_alt`  | --                                                                                             |
| `selphid_component_tutorial_2_anim_custom_alt`  | --                                                                                             |
| `selphid_component_tutorial_3_anim_custom_alt`  | --                                                                                             |
| `selphid_component_tutorial_close_button_alt`   | Volver al tutorial previo                                                                      |

#### Selector de Documento y País

| Name                                          | Value                         |
| --------------------------------------------- | ----------------------------- |
| `selphid_selector_title`                      | Realiza tu onboarding         |
| `selphid_selector_country_label`              | ¿De qué país es tu documento? |
| `selphid_selector_country_placeholder`        | Selecciona un país            |
| `selphid_selector_country_search_label`       | Elige un país                 |
| `selphid_selector_country_search_placeholder` | Busca un país                 |
| `selphid_selector_country_search_clear`       | Limpiar búsqueda              |
| `selphid_selector_country_no_results`         | Sin resultados                |
| `selphid_selector_document_label`             | ¿Qué documento utilizarás?    |
| `selphid_selector_document_placeholder`       | Selecciona un documento       |
| `selphid_selector_document_dialog_title`      | Elige el documento            |
| `selphid_selector_document_dialog_cancel`     | CANCELAR                      |
| `selphid_selector_document_dialog_select`     | SELECCIONAR                   |
| `selphid_selector_continue`                   | Continuar                     |
| `selphid_selector_type_id_card`               | Documento de identidad        |
| `selphid_selector_type_passport`              | Pasaporte                     |
| `selphid_selector_type_drivers_license`       | Licencia de conducir          |
| `selphid_selector_type_foreign_card`          | Tarjeta de residencia         |
| `selphid_selector_type_credit_card`           | Tarjeta de crédito            |
| `selphid_selector_type_custom`                | Personalizado                 |
| `selphid_selector_type_visa`                  | Visado                        |

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

El componente utiliza animaciones **Lottie** (`.json`) tanto en el *tip previo* como en los *tutoriales*.

Si se desea modificar las animaciones de la SDK, se deberán incluir los archivos con **el mismo nombre** en la carpeta `res/raw/`

```
selphid_anim_tip_driver_h.json
selphid_anim_tip_driver_m.json
selphid_anim_tip_health.json
selphid_anim_tip_id_h.json
selphid_anim_tip_id_m.json
selphid_anim_tip_mrz.json
selphid_anim_tip_pass_h.json
selphid_anim_tip_pass_m.json

selphid_anim_tuto_driver_h_1.json
selphid_anim_tuto_driver_h_2.json
selphid_anim_tuto_driver_h_3.json
selphid_anim_tuto_driver_m_1.json
selphid_anim_tuto_driver_m_2.json
selphid_anim_tuto_driver_m_3.json

selphid_anim_tuto_id_h_1.json
selphid_anim_tuto_id_h_2.json
selphid_anim_tuto_id_h_3.json
selphid_anim_tuto_id_m_1.json
selphid_anim_tuto_id_m_2.json
selphid_anim_tuto_id_m_3.json

selphid_anim_tuto_pass_h_1.json
selphid_anim_tuto_pass_h_2.json
selphid_anim_tuto_pass_h_3.json
selphid_anim_tuto_pass_m_1.json
selphid_anim_tuto_pass_m_2.json
```


# Captura de huellas - Phingers

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura de huellas se realiza mediante el **Phingers Component**.

Este componente se encarga de capturar las huellas dactilares del usuario (*fingerprints*) y extraer las plantillas biométricas asociadas. Sus principales procesos son:

* Gestión interna de cámara y permisos.
* Diferentes modos de extracción: mano completa (cuatro dedos sin pulgar), pulgar, o dedos individuales.
* Detección de vivacidad integrada.
* Asistencia guiada durante el proceso de captura.
* Generación de plantillas biométricas, imágenes y métricas de calidad.

En el apartado [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se describen los pasos necesarios para la integración básica del SDK. En esta página se añade la información específica para el uso de este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kotlin
implementation "com.facephi.androidsdk:phingers_tf_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**       | **Descripción**                                                        |
| --------------------- | ---------------------------------------------------------------------- |
| PhingersTFController  | Controlador principal de captura de huellas                            |
| FPhingersTFController | Controlador principal de captura de huellas para integraciones de flow |

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación, se puede lanzar el componente de captura de huellas utilizando su controlador.

Lanzamiento de la captura:

```kotlin
val response = SDKController.launch(
    PhingersTFController(PhingersConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica

Para lanzar el componente es necesario crear un objeto `PhingersConfigurationData`, que define la configuración del proceso de captura.

La configuración básica necesaria es la siguiente:

```kotlin
PhingersConfigurationData(
    reticleOrientation = CaptureOrientation.LEFT,
    fingerFilter       = FingerFilter.SLAP,
    templateType       = TemplateType.NIST_TEMPLATE
)
```

**Orientación de captura**

Define la mano a capturar:

* `CaptureOrientation.LEFT`
* `CaptureOrientation.RIGHT`

**Filtros de dedos**

Permite definir qué dedos se capturan durante el proceso:

* `FingerFilter.SLAP`
* `FingerFilter.ALL_4_FINGERS_ONE_BY_ONE`
* `FingerFilter.ALL_5_FINGERS_ONE_BY_ONE`
* `FingerFilter.INDEX_FINGER`
* `FingerFilter.MIDDLE_FINGER`
* `FingerFilter.RING_FINGER`
* `FingerFilter.LITTLE_FINGER`
* `FingerFilter.THUMB_FINGER`

**Opciones de TemplateType**:

* `NIST_TEMPLATE`
* `ISO_TEMPLATE`
* `NIST_T5_TEMPLATE`

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento del componente devuelve un resultado en formato `SdkResult`, que puede corresponder a una ejecución correcta o a un error.

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

***

## Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devuelven como un objeto `PhingersError`.

**Listado de errores**

* PHG\_ACTIVITY\_RESULT\_ERROR: El resultado de la actividad es incorrecto.
* PHG\_ACTIVITY\_RESULT\_MSG\_ERROR: El mensaje del resultado de la actividad es incorrecto.
* PHG\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación es nulo.
* PHG\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* PHG\_CANCEL\_LAUNCH: Cancelación general del SDK.
* PHG\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* PHG\_EMPTY\_LICENSE: El string de licencia está vacío.
* PHG\_FETCH\_DATA\_ERROR: Error en la recogida del resultado.
* FLOW\_ERROR: Error en el proceso de flow.
* PHG\_INITIALIZATION\_ERROR: Error de inicialización.
* PHG\_INTERNAL\_ERROR: Error interno.
* PHG\_LOW\_QUALITY: Baja calidad de la imagen.
* PHG\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos o no están inicializados.
* PHG\_NO\_DATA\_ERROR: No se han recibido datos de la captura.
* PHG\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* PHG\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* PHG\_AUTOFOCUS\_FAILURE: Fallo del autofocus.
* PHG\_CAMERA\_FAILURE: Fallo de la cámara.
* PHG\_CAPTURE\_FAILURE: Fallo en la captura.
* PHG\_CONFIGURATION\_FAILURE: Error de configuración.
* PHG\_FINGERPRINT\_CAPTURE\_FAILURE: Fallo en la captura de huellas.
* PHG\_FINGERPRINT\_TEMPLATE\_IO\_ERROR: Fallo IO de plantilla.
* PHG\_LICENSING\_FAILURE: Error de licencia.
* PHG\_LIVENESS\_FAILURE: Error en la prueba de vida.
* PHG\_NO\_FINGERS\_DETECTED: No se han detectado huellas.
* PHG\_UNIQUE\_USER\_ID\_NOT\_SPECIFIED: Usuario no especificado.
* PHG\_TIMEOUT: Timeout en el proceso.
* PHG\_FLOW\_VIDEO\_RECORDING\_ERROR: Error en la grabación de vídeo del flow.
* PHG\_FLOW\_TRACKING\_ERROR: Error de tracking en el flow.
* PHG\_TRACKING\_STEP\_ERROR: Error en el paso de tracking.

***

## Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

En caso de éxito, el campo `data` contiene un objeto `PhingersResult`.

Las imágenes se devuelven como `SdkImage`. Es posible obtener el `Bitmap` mediante `image.bitmap`. Para convertir una imagen a Base64 se puede utilizar:

```
Base64.encodeToString(byteArray, Base64.NO_WRAP)
```

**Campos devueltos**

* **fingers**: Lista de `FingerResponse` (una entrada por dedo capturado)
* **slapImages**: Lista de `SlapResponse` (capturas slap cuando aplique)
* **livenessScore**: Media del score de vivacidad (nullable)
* **recording**: Metadatos de la grabación local opcional cuando `videoRecordingEnabled=true` y el widget genera un fichero MP4. Puede ser `null`.

**FingerResponse**

* **position**: Índice de posición del dedo
* **wsq**: Imagen WSQ (`ByteArray`)
* **displayImage**: Imagen de visualización (`ByteArray`, PNG)
* **minutiaesNumber**: Número de minutias detectadas
* **quality**: Puntuación de calidad
* **nistQuality**: Puntuación de calidad NIST
* **nist2Quality**: Puntuación de calidad NIST2
* **template**: Plantilla de huella (`ByteArray`)
* **proprietaryQuality**: Calidad propietaria del proveedor
* **templateType**: Identificador del tipo de plantilla
* **imageWidth**: Ancho de la imagen en píxeles
* **imageHeight**: Alto de la imagen en píxeles

**SlapResponse**

* **position**: Índice de posición del slap
* **image**: Imagen slap (`ByteArray`)

**VideoRecordingResult**

* **path**: Ruta completa del fichero de vídeo generado.
* **fileName**: Nombre del fichero de vídeo.
* **mimeType**: Tipo MIME del fichero. Por defecto `video/mp4`.
* **sizeBytes**: Tamaño del fichero en bytes, cuando el widget lo informa.
* **durationMs**: Duración del vídeo en milisegundos, cuando el widget la informa.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

El objeto `PhingersConfigurationData` permite personalizar el comportamiento del componente.

**Parámetros disponibles**

**reticleOrientation**

Establece el modo de detección de huellas e indica qué dedos se van a detectar durante el proceso. Los valores permitidos son:

* **LEFT**: Se activa la captura **de la mano izquierda**.
* **RIGHT**: Se activa la captura **de la mano derecha**.

**fingerFilter**

Filtro para elegir la mano entera o un dedo en concreto: SLAP, INDEX\_FINGER, MIDDLE\_FINGER, RING\_FINGER, LITTLE\_FINGER, THUMB\_FINGER.

**templateType**

Define el formato de plantilla a generar (variantes NIST/ISO).

**useLiveness**

Activa o desactiva el detector de vivacidad durante el proceso de captura de huellas. Por defecto se encuentra a **true**.

**extractionTimeout**

Establece un tiempo de extracción.

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

**showTutorial**

Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso.

**threshold**

El parámetro configura un captureQualityThreshold, para definir un threshold de calidad para realizar la captura. El SDK limita este valor al rango `0.0-1.0`.

**showEllipses**

Muestra las elipses durante la captura.

**cropWidth**

Indica un ancho para realizar un recorte de la captura.

**cropHeight**

Indica una altura para realizar un recorte de la captura.

**vibrationEnabled**

Activa la vibración. Por defecto `true`.

**enableFlash**

Activa o desactiva el flash de la cámara durante el proceso de captura de huellas. Por defecto se encuentra a **true**.

**reticle**

Identificador opcional del retículo. Por defecto `"R_S"`.

**showPreviousFingerSelector**

Muestra el selector de dedos antes de la captura.

**fingerSelectorHandOrientation**

Define qué mano(s) se muestran en el selector (`LEFT`, `RIGHT`, `BOTH`).

**fingerSelectorOptions**

Define la lista de filtros que se muestran en el selector. Si está vacía, el SDK usa: `ALL_4_FINGERS_ONE_BY_ONE`, `SLAP`, `INDEX_FINGER`.

**licenseKey**

Clave de licencia opcional que se traslada al widget Phingers TF cuando se usa activación o licenciamiento específico.

**product**

Producto opcional asociado a la activación o licenciamiento del widget.

**operationId**

Identificador de operación opcional que se envía al widget para trazabilidad y asociación de la captura.

**videoRecordingEnabled**

Activa la grabación local opcional durante la captura de huellas. Por defecto `false`.

**videoRecordingDirectoryPath**

Directorio de destino opcional para el fichero de vídeo generado.

**videoRecordingFileName**

Nombre de fichero opcional para la grabación generada.

**videoRecordingQuality**

Calidad de grabación local. Los valores permitidos son `LOW`, `MEDIUM` y `HIGH`. Por defecto `MEDIUM`.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse añadiendo un fichero XML de recursos en la aplicación cliente y sobrescribiendo los valores por defecto.

```kotlin
<!-- Previous Tip -->
    <string name="phingers_widget_tip_title">Captura de huellas</string>
    <string name="phingers_widget_tip_message">Coloca tu dedo dentro de la marca</string>
    <string name="phingers_widget_tip_message_alt">Coloca tu dedo dentro de la marca</string>
    <string name="phingers_widget_tip_button">Comenzar</string>
    <string name="phingers_widget_tip_button_alt">Comenzar captura de huellas</string>
    <string name="phingers_widget_tip_close_button_alt">Volver</string>
    <string name="phingers_widget_tip_info_button_alt">Ver consejos</string>
    <string name="phingers_widget_tip_anim_desc">Animación de instrucciones para la captura de huella</string>
    <!-- Previous Tip (tipos específicos) -->
    <string name="phingers_widget_tip_title_left_slap">Huellas mano izquierda</string>
    <string name="phingers_widget_tip_message_left_slap">Junta tus dedos. Acerca o aleja la mano hasta que se enfoquen tus huellas.</string>
    <string name="phingers_widget_tip_title_right_slap">Huellas mano derecha</string>
    <string name="phingers_widget_tip_message_right_slap">Junta tus dedos. Acerca o aleja la mano hasta que se enfoquen tus huellas.</string>
    <string name="phingers_widget_tip_title_left_finger">Huellas mano izquierda</string>
    <string name="phingers_widget_tip_message_left_finger">Enfoca el dedo índice en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <string name="phingers_widget_tip_title_right_finger">Huellas mano derecha</string>
    <string name="phingers_widget_tip_message_right_finger">Enfoca el dedo índice en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <string name="phingers_widget_tip_title_thumb">Huella dedo pulgar</string>
    <string name="phingers_widget_tip_message_thumb">Enfoca el dedo pulgar en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <!-- Selector de dedos -->
    <string name="phingers_widget_selector_hand_question">¿Qué mano utilizarás?</string>
    <string name="phingers_widget_selector_hand_left">Izquierda</string>
    <string name="phingers_widget_selector_hand_right">Derecha</string>
    <string name="phingers_widget_selector_secondary_question">¿Qué huellas quieres escanear?</string>
    <string name="phingers_widget_selector_option_index">Dedo índice</string>
    <string name="phingers_widget_selector_option_middle">Dedo corazón</string>
    <string name="phingers_widget_selector_option_ring">Dedo anular</string>
    <string name="phingers_widget_selector_option_little">Dedo meñique</string>
    <string name="phingers_widget_selector_option_thumb">Dedo pulgar</string>
    <string name="phingers_widget_selector_option_all4">4 dedos (índice, corazón, anular y meñique)</string>
    <string name="phingers_widget_selector_option_all4_sequence">4 dedos (uno a uno)</string>
    <string name="phingers_widget_selector_option_all5_sequence">5 dedos (uno a uno)</string>
    <string name="phingers_widget_selector_primary_button">Continuar</string>
    <!-- Capture -->
    <string name="phingers_widget_capture_close_button_alt">Volver</string>
    <!-- Tutorial -->
    <string name="phingers_widget_tutorial_message_1">Coloca tu cara en el centro y mira de frente a la cámara.</string>
    <string name="phingers_widget_tutorial_message_2">Retira cualquier elemento que cubra tu cara.</string>
    <string name="phingers_widget_tutorial_message_3">Busca un entorno bien iluminado, sin sombras sobre tu rostro.</string>
    <string name="phingers_widget_tutorial_message_1_anim_desc">La foto se realiza cuando la persona está en el centro.</string>
    <string name="phingers_widget_tutorial_message_2_anim_desc">Una persona se quita las gafas de sol y se retira el pelo de los ojos.</string>
    <string name="phingers_widget_tutorial_message_3_anim_desc">La imagen aparece oscura y una persona enciende la luz.</string>
    <string name="phingers_widget_tutorial_close_button_alt">Volver al tutorial previo</string>
    <!-- Confirmation -->
    <string name="phingers_widget_image_captured">Imagen capturada</string>
    <string name="phingers_widget_confirmation_message">¿Tu foto se ve de forma clara y nítida?</string>
    <string name="phingers_widget_confirmation_retry">Reintentar</string>
    <string name="phingers_widget_confirmation_continue">Continuar</string>

    <!-- Camera status (ES) -->
    <string name="phingers_widget_camera_status_position_fingers">Coloca tus dedos dentro de la marca</string>
    <string name="phingers_widget_camera_status_processing">Procesando…</string>
    <string name="phingers_widget_camera_status_too_far">Acerca la mano</string>
    <string name="phingers_widget_camera_status_too_close">Aleja la mano</string>
    <string name="phingers_widget_camera_status_low_focus">Mueve el dedo para enfocar</string>
    <string name="phingers_widget_camera_status_good_focus">Mantén el dedo quieto</string>
    <string name="phingers_widget_camera_status_wrong_angle">Coloca el dedo en vertical</string>
    <string name="phingers_widget_camera_status_too_few">No se ha detectado el dedo</string>
    <string name="phingers_widget_camera_status_too_many">Varios dedos detectados</string>
    <string name="phingers_widget_camera_status_wrong_hand_left">Debes poner el dedo de la mano izquierda</string>
    <string name="phingers_widget_camera_status_wrong_hand_right">Debes poner el dedo de la mano derecha</string>
    <string name="phingers_widget_camera_status_error">Error en la captura</string>
    <string name="phingers_widget_camera_status_timeout">Tiempo de captura agotado</string>
    <string name="phingers_widget_camera_status_success">¡Huella capturada!</string>
    <string name="phingers_widget_camera_status_keep_hand_steady">Mantén tu mano firme</string>
    <string name="phingers_widget_timeout_desc">La captura ha superado el tiempo. Inténtalo de nuevo.</string>

    <!-- Dynamic finger hint (ES) -->
    <!-- %1$s = lado (izquierdo/derecho), %2$s = dedo (índice/medio/anular/meñique/pulgar) -->
    <string name="phingers_widget_hint_place_finger_mark">Coloca tu %2$s %1$s dentro de la marca</string>
    <string name="phingers_widget_side_left">izquierdo</string>
    <string name="phingers_widget_side_right">derecho</string>
    <string name="phingers_widget_finger_index">índice</string>
    <string name="phingers_widget_finger_middle">medio</string>
    <string name="phingers_widget_finger_ring">anular</string>
    <string name="phingers_widget_finger_little">meñique</string>
    <string name="phingers_widget_finger_thumb">pulgar</string>
```

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Las animaciones del componente son **Lottie (JSON)**.

Para sustituirlas, añade los archivos con el mismo nombre en la carpeta `res/raw/` de la aplicación:

```
phingers_anim_left.json
phingers_anim_left_finger.json
phingers_anim_right.json
phingers_anim_right_finger.json
phingers_anim_success.json
phingers_anim_thumb.json
phingers_anim_thumb_left.json
phingers_anim_thumb_right.json
phingers_anim_thumbs.json
```

Si no se incluyen animaciones personalizadas, se utilizarán las animaciones por defecto.

***


# Captura de voz - VoiceID

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***Voice Component***.

Este componente se encarga de realizar la captura de voz del usuario y la posterior extracción de las plantillas correspondientes. Sus principales procesos son:

* Gestión interna del micrófono y permisos.
* Entrada de cierto número de frases para posteriormente leer cada una en un paso.
* Análisis de los silencios.
* Análisis del progreso.
* Asistente en los procesos de captura.
* Generación de las plantillas con las características de la voz y puntuaciones.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```
implementation "com.facephi.androidsdk:voice_component:$version"
```

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

<table data-header-hidden><thead><tr><th width="193.87109375"></th><th></th></tr></thead><tbody><tr><td><strong>Controlador</strong></td><td><strong>Descripción</strong></td></tr><tr><td>VoiceController</td><td>Controlador principal de captura de voz</td></tr></tbody></table>

\
Lanzamiento simplificado
------------------------

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura:

```kotlin
val response = SDKController.launch(
    VoiceController(VoiceConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *VoiceConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```kotlin
VoiceConfigurationData(
  phrases = arrayOf(
            "Tu nombre complet y tu dirección",
            "Tu número de documento con letra",
        )
)
```

Se puede editar el listado de frases que se van a mostrar al usuario.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'VoiceError'.

Listado de errores:

* VOC\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad es incorrecto
* VOC\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo
* VOC\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VOC\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VOC\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VOC\_EMPTY\_LICENSE: El String de licencia está vacío
* VOC\_FETCH\_DATA\_ERROR: Error en la recogida del resultado
* VOC\_FLOW\_ERROR: Error en el proceso de flow
* VOC\_INITIALIZATION\_ERROR: Error de inicialización
* VOC\_INTERNAL\_LICENSE\_ERROR: Error interno relacionado con la licencia
* VOC\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* VOC\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VOC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VOC\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* VOC\_TIMEOUT: Timeout en el proceso

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

En la parte de SdkResult.Success - *data*, dispondremos de la clase *VoiceResult*.

Los campos devueltos en el resultado son los siguientes:

**audios**

Contiene un listado de audios capturados en formato ByteArray.

**tokenizedAudios**

Contiene el listado de audios capturados en formato tokenizado de Facephi.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *VoiceConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `phrases`: Indica la/las frases necesarias para capturar..
* `vibrationEnabled`: Indica la activación de la vibración cuando el widget termine satisfactoriamente.
* `showTutorial`: Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.
* `showDiagnostic`: Mostrar pantallas de diagnóstico al final del proceso.
* `enableQualityCheck`: Activa o desactiva la comprobación de calidad del audio. Se recomienda tenerla siempre activa.
* `showPreviousTip`: Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse añadiendo un fichero XML de recursos en la aplicación cliente y sobrescribiendo los valores por defecto.

```kotlin
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Previous Tip -->
    <string name="voice_widget_tip_message">Speak clearly and loudly.<br/><br/>Make sure you are in a quiet environment.</string>
    <string name="voice_widget_tip_message_alt">Speak clearly and loudly. Make sure you are in a quiet environment.</string>
    <string name="voice_widget_tip_title">Speech recognition</string>
    <string name="voice_widget_tip_button">Continue</string>
    <string name="voice_widget_tip_anim_alt">Animation in which a person appears holding the phone in front of their face and speaking directly to it. Before you begin, if you are using a screen reader, use headphones.</string>
    <!-- Process -->
    <string name="voice_widget_success_message">Recorded recording</string>
    <string name="voice_widget_speech_message">Speak clearly and close to the microphone</string>
    <string name="voice_widget_speech_more_message">Keep talking</string>
    <string name="voice_widget_speech_empty_message" translatable="false"></string>
    <string name="voice_widget_read_message">Say out loud:</string>
    <string name="voice_widget_speech_noisy_message">There is too much background noise, try to go to a quiet environment</string>
    <string name="voice_widget_success_records_message">successful recordings</string>
    <string name="voice_widget_phrase_generic_error_message">Please repeat the phrase.</string>
    <string name="voice_widget_phrase_long_silence_message">Speak for 2 seconds or more.</string>
    <string name="voice_widget_phrase_long_reverberation_message">Too much echo. Try a different environment.</string>
    <string name="voice_widget_quality_check_error_message">Audio quality is insufficient.</string>
    <string name="voice_widget_multiple_speakers_error_message">Background voices detected. Make sure you are in a quiet environment.</string>
    <!-- Diagnostic -->
    <string name="voice_widget_timeout_title">Time exceeded</string>
    <string name="voice_widget_timeout_desc">We were unable to identify you. Please try again.</string>
    <string name="voice_widget_internal_error_title">There was a technical problem</string>
    <string name="voice_widget_internal_error_desc">We apologize. The capture could not be made</string>
    <string name="voice_widget_exit_alert_accept">Accept</string>
    <string name="voice_widget_exit_alert_cancel">Cancel</string>
    <string name="voice_widget_exit_alert_question">Are you sure you want to finish the process?</string>
    <string name="voice_widget_back_button_alt">Back</string>
    <string name="voice_widget_close_button_alt">Close</string>
    <string name="voice_widget_logo_alt">Logo</string>

</resources>

```

```
                                                                                    |
```

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
voice_anim_enroll_ko.json
voice_anim_enroll_ok.json
voice_anim_enroll_progress.json
voice_anim_intro.json
```

### Vistas externas <a href="#id-83-vistas-externas" id="id-83-vistas-externas"></a>

Es posible modificar completamente las pantallas del componente manteniendo su funcionalidad y navegación. Para ello deben implementarse los interfaces siguientes:

Pantalla de tip previo:

```kotlin

interface IVoicePreviousTipView {
    @Composable
    fun Content(
        onContinue: () -> Unit,
        onClose: () -> Unit
    )
}

```

Pantalla de diagnóstico de error:

```kotlin

interface IVoiceErrorDiagnosticView {
    @Composable
    fun Content(
        error: VoiceError,
        onRetry: () -> Unit,
        onClose: () -> Unit,
    )
}

```

Pantallas de captura:

```kotlin

interface IVoiceEnrollRecordingView {
    @Composable
    fun Content(
        phrase: String,
        numberRecordedPhrases: Int,
        numberTotalPhrases: Int,
        voiceAmplitude: Float,
        recordingProgress: Int,
        onClose: () -> Unit,
    )
}

```

```kotlin

interface IVoiceEnrollSuccessView {
    @Composable
    fun Content(
        phrase: String,
        numberRecordedPhrases: Int,
        numberTotalPhrases: Int,
        onClose: () -> Unit,
    )
}

```

```kotlin

interface IVoiceEnrollErrorView {
    @Composable
    fun Content(
        phrase: String,
        numberRecordedPhrases: Int,
        numberTotalPhrases: Int,
        onClose: () -> Unit,
    )
}

```

Una vez creadas las clases que implementan los interfaces, en el lanzamiento del componente se podrá añadir el parámetro "customViews" para que se utilicen en el SDK.

<br>


# Captura de NFC

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***NFC Component***.

Este componente se encarga de realizar la lectura del NFC de los documentos de identidad y pasaportes. Sus principales procesos son:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kts
implementation "com.facephi.androidsdk:nfc_component:$sdk_nfc_component_version"{
      exclude group : "org.bouncycastle", module : "bcprov-jdk15on"
      exclude group : "org.bouncycastle", module : "jetified-bcprov-jdk15on-1.68"
  }
```

Además habrá que añadir en gradle:

```kts
android {
  ...
 packaging {
      resources {
          pickFirsts.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
      }
  }
}
```

## Controladores disponibles

| **Controlador** | **Descripción**                      |
| --------------- | ------------------------------------ |
| NFCController   | Controlador principal de lectura NFC |

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura:

<pre class="language-kotlin"><code class="lang-kotlin"><strong>val response = SDKController.launch(
</strong><strong>    NfcController(
</strong>        componentData = NfcConfigurationData(...),
        state = { state ->
            Napier.d("NFC: State: ${state.name}")
        },
        debugLogs = {
            Napier.d("NFC Logs: $it")
        }
    )
)
when (response) {
    is SdkResult.Error -> Napier.d("NFC: ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
</code></pre>

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *NFCConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```kotlin
NfcConfigurationData(
    documentNumber = NFC_SUPPORT_NUMBER, // Num soport.
    birthDate = NFC_BIRTH_DATE, // "dd/MM/yyyy"
    expirationDate = NFC_EXPIRATION_DATE, // "dd/MM/yyyy",
)
```

Los datos necesarios son los del documento que se va a capturar.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'NfcError'.

Listado de errores:

* NFC\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* NFC\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* NFC\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK.
* NFC\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* NFC\_EMPTY\_LICENSE: El String de licencia está vacío.
* NFC\_EXTRACT\_DATA\_ERROR: Error en los datos extraídos.
* NFC\_FETCH\_DATA\_ERROR: Error en la recogida del resultado.
* NFC\_FLOW\_ERROR: Error en el proceso de flow.
* NFC\_INITIALIZATION\_ERROR: Error de inicialización.
* NFC\_LAST\_COMMAND\_EXPECTED: Error en el comando de finalización
* NFC\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos.
* NFC\_NO\_DATA\_ERROR: Los datos de entrada son nulos o no se ha recibido resultado de la lectura.
* NFC\_ERROR: Error general
* NFC\_ERROR\_DATA: Error en los datos de entrada
* NFC\_ERROR\_DISABLED: NFC deshabilitado
* NFC\_ERROR\_ILLEGAL\_ARGUMENT: NFC con un tag incorrecto
* NFC\_ERROR\_IO: Error de entrada/salida
* NFC\_ERROR\_NOT\_SUPPORTED: NFC no soportado
* NFC\_ERROR\_TAG\_LOST: Conexión perdida
* NFC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* NFC\_TIMEOUT: Timeout en el proceso.

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

En la parte de SdkResult.Success - *data*, dispondremos de la clase *NfcResult*.

El resultado devuelve las imágenes en formato **SdkImage**, es posible extraer el bitmap accediendo a *image.bitmap*. Si se quisiera convertir a base64 se puede utilizar la función:

`Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)`

{% hint style="info" %}
Los campos cifrados en el resultado se incorporan a partir de la versión 2.6.0
{% endhint %}

Los campos devueltos en el resultado son los siguientes:

**nfcRawData**

Información obtenida por cada tipo de dato en formato crudo.

**nfcDocumentInformation**

Información obtenida del documento ordenada por:

* documentNumber
* expirationDate
* issuer
* mrzString
* type

**nfcPersonalInformation**

Información obtenida del documento ordenada por:

* address
* birthdate
* city
* gender
* name
* nationality
* personalNumber
* placeOfBirth
* surname

**nfcImages**

Información de imágenes obtenida del documento ordenada por:

* facialImage
* fingerprintImage
* signatureImage
* tokenFacialImage
* tokenSignatureImage

**nfcSecurityData**

Información de datos de seguridad del documento ordenada por:

* dataGroupsHashes
* dataGroupsRead
* documentSigningCertificateData
* issuerSigningCertificateData
* ldsVersion

**nfcValidations**

Información de las validaciones del documento ordenada por:

* accessType
* activeAuthenticationSupported
* activeAuthenticationValidation
* chipAuthenticationSupported
* chipAuthenticationValidation
* dataGroupsHashesValidation
* documentSigningValidation
* issuerSigningValidation

**tokenOcr**

Datos del OCR cifrados

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *NFCConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

**documentNumber**

Indica el número de documento o número de soporte dependiendo del documento a realizar la lectura.

Éste campo es obligatorio.

**birthDate**

Indica la fecha de nacimiento que aparece en el documento ("dd/MM/yyyy").

Éste campo es obligatorio.

**expirationDate**

Indica la fecha de expiración que aparece en el documento ("dd/MM/yyyy").

Éste campo es obligatorio.

**extractionTimeout**

Establece el tiempo máximo que se puede realizar la lectura.

**showReadingScreen**

Establece si se desea mostrar la pantalla modal inferior con la lectura que se está realizando. Si se desactiva, no se muestra ninguna vista y se deberán escuchar los estados que devuelve el controlador.

**showTutorial**

Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**vibrationEnabled**

Indica si se desea un feedback de vibración al acabar el proceso.

**skipPace**

Indica que solo se desea realizar la lectura BAC de NFC. Es una lectura con información más simple y rápida que permite la lectura de más variedad de documentos.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso

**extractFacialImage**

Indica si quiere extraer la imagen de la cara.

**extractSignatureImage**

Indica si quiere extraer la imagen de la firma.

**documentType**

Campo utilizado para cambiar la vista de tutorial y que muestre los diferentes documentos.

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

**readingProgressStyle**

Cambio de estilo en la pantalla de lectura de documento:

* ReadingProgressStyle.DOTS: El progreso viene marcado visualmente con puntos
* ReadingProgressStyle.PERCENTAGE: El progreso se muestra con un porcentaje

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse añadiendo un fichero XML de recursos en la aplicación cliente y sobrescribiendo los valores por defecto.

```kotlin
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="nfc_widget_previous_tip_title_passport">NFC Reader</string>
    <string name="nfc_widget_previous_tip_title_id">NFC Reader</string>
    <string name="nfc_widget_previous_tip_description">&lt;b&gt;Attach&lt;/b&gt; the document to the back of your device.</string>
    <string name="nfc_widget_start_button">Start</string>
    <string name="nfc_widget_tutorial_button">Check out these tips</string>
    <string name="nfc_widget_close_button">Close</string>
    <string name="nfc_widget_info_button">More information</string>
    <string name="nfc_widget_previous_tip_animation_desc">NFC previous tips</string>
    <string name="nfc_widget_mandatory_tutorial_title">NFC Reader</string>
    <string name="nfc_widget_tutorial_tip_1">When we pass a card through a sensor, there is an exchange of information called NFC.</string>
    <string name="nfc_widget_tutorial_tip_2">On your mobile, the sensor is in the marked area. Here you must gather your document.</string>
    <string name="nfc_widget_tutorial_tip_3_passport">Keep &lt;b&gt; closed &lt;/b&gt; the passport to do the reading.</string>
    <string name="nfc_widget_tutorial_tip_3_id">For a better reading, remove the cover of your mobile.</string>
    <string name="nfc_widget_ready_to_scan">Ready to scan</string>
    <string name="nfc_widget_reading_device">Reading device</string>
    <string name="nfc_widget_start_message">Attach the chip to your mobile.\nWhen it detects it, hold it still.</string>
    <string name="nfc_widget_reading_message">Hold the position.</string>
    <string name="nfc_widget_reading_document_message">Extracting document data.</string>
    <string name="nfc_widget_reading_images_message">Extracting images.</string>
    <string name="nfc_widget_close_alt">Close process</string>
    <string name="nfc_widget_reading_title">Reading NFC chip</string>
    <string name="nfc_widget_reading_animation_desc">NFC reading animation</string>
    <string name="nfc_widget_cancel_button">Cancel</string>
    <string name="nfc_widget_success_title">Reading finished</string>
    <string name="nfc_widget_success_document_prefix">Document:</string>
    <string name="nfc_widget_success_animation_desc">Reading completed</string>
    <string name="nfc_widget_error_title">Reading incomplete</string>
    <string name="nfc_widget_error_animation_desc">Reading cancelled</string>
    <string name="nfc_widget_retry_button">Retry</string>
    <string name="nfc_widget_close_action">Close</string>
    <string name="nfc_widget_cancelled_title">NFC flow cancelled</string>
    <string name="nfc_widget_cancelled_desc">Close the view to continue.</string>
    <string name="nfc_widget_cancelled_animation_desc">NFC flow cancelled</string>
    <string name="nfc_widget_timeout_title">Follow the instructions</string>
    <string name="nfc_widget_timeout_desc">Join the document &lt;b&gt;after&lt;/b&gt; clicking on the &lt;b&gt;Start button.&lt;/b&gt;</string>
    <string name="nfc_widget_tag_lost_title">Reading not finished</string>
    <string name="nfc_widget_tag_lost_desc">Hold the position until the end of the reading</string>
    <string name="nfc_widget_data_error_title">Document could not be read</string>
    <string name="nfc_widget_data_error_desc">Review the data entered</string>
    <string name="nfc_widget_internal_error_title">There was a technical problem</string>
    <string name="nfc_widget_internal_error_desc">We apologize. The capture could not be made</string>
    <string name="nfc_widget_state_waiting_for_tag">Slide the document until the sensor detects it.</string>
    <string name="nfc_widget_state_preparing">Preparing chip reading...</string>
    <string name="nfc_widget_state_secure_access">Validating secure document access...</string>
    <string name="nfc_widget_state_reading_data">Reading document data...</string>
    <string name="nfc_widget_state_reading_images">Reading document images...</string>
    <string name="nfc_widget_state_io_error">A communication issue with NFC was detected.</string>
    <string name="nfc_widget_state_finished">Reading completed.</string>
</resources>

```

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
nfc_anim_reader.json
nfc_anim_tuto_1.json
nfc_anim_tuto_2.json
nfc_anim_tuto_3.json
nfc_anim_tuto_3_pass.json
nfc_anim_tuto_id.json
nfc_anim_tuto_passport.json
```

### Vistas externas <a href="#id-83-vistas-externas" id="id-83-vistas-externas"></a>

Es posible modificar las pantallas inferiores de lectura del componente manteniendo su funcionalidad y navegación. A partir de la versión 2.8.0 la personalización externa queda limitada a las bottom sheets de lectura; las vistas legacy de tip previo y diagnóstico ya no forman parte del contrato público. Para ello deben implementarse los interfaces siguientes:

Pantallas del diálogo de lectura:

```kotlin

interface INfcWaitingBottomView {
    @Composable
    fun Content(
        onClose: () -> Unit,
    )
}

```

```kotlin

interface INfcReadingBottomView {
    @Composable
    fun Content(
        state: NfcReadState,
        onClose: () -> Unit
    )
}

```

```kotlin

interface INfcSuccessBottomView {
    @Composable
    fun Content(
        onContinue: () -> Unit,
    )
}

```

```kotlin

interface INfcErrorBottomView {
    @Composable
    fun Content(
        error: NfcError,
        onContinue: () -> Unit,
    )
}

```

Una vez creadas las clases que implementan los interfaces, en el lanzamiento del componente se podrá añadir el parámetro "customViews" para que se utilicen en el SDK.


# Subida de ficheros y gestión de QR - Capture

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura de documentos y la lectura y generación de QRs se realizan con el ***CaptureComponent***.

Este componente permitirá la subida de documentos realizando una foto con la cámara del dispositivo o desde galeria.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```
implementation "com.facephi.androidsdk:capture_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**        | **Descripción**                           |
| ---------------------- | ----------------------------------------- |
| FileUploaderController | Controlador para la captura de documentos |
| QrReaderController     | Controlador para la captura de QRs        |
| QrGeneratorController  | Controlador para la generación de QRs     |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura de documentos:

```kotlin
val response = SDKController.launch(
    FileUploaderController(FileUploaderConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

Lanzamiento de la captura de QR:

```kotlin
val response = SDKController.launch(
    QrReaderController(QrCaptureConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

Lanzamiento de la generación de QR:

```kotlin
val response = SDKController.launch(
    QrGeneratorController(QrGeneratorConfiguration(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para los controladores de captura de componentes y captura de QR se puede generar la configuración con los parámetros por defecto. Para el caso de la geneación del QR se necesitará el texto que se va a utilizar:

```
QrGeneratorConfiguration(source = "QR text")
```

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'CaptureError'.

Listado de errores:

* CAP\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado devuelto por la actividad es incorrecto o no contiene la información necesaria para continuar.
* CAP\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación requerido es nulo o no válido, impidiendo inicializar correctamente el módulo de captura.
* CAP\_CAMERA\_ERROR: Ha ocurrido un error interno relacionado con la cámara del dispositivo (fallo de apertura, inicialización o captura).
* CAP\_CAMERA\_PERMISSION\_DENIED: El usuario ha denegado los permisos necesarios para acceder a la cámara.
* CAP\_CANCEL\_BY\_USER: El usuario ha cancelado manualmente el proceso de captura.
* CAP\_CANCEL\_LAUNCH: El proceso ha sido cancelado de forma general por el SDK o por una acción externa.
* CAP\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es válida, ha expirado o no coincide con la configuración requerida.
* CAP\_EMPTY\_LICENSE: La cadena de licencia está vacía o no se ha proporcionado.
* CAP\_FETCH\_DATA\_ERROR: Se ha producido un error al obtener o procesar los datos necesarios para ejecutar el flujo. *(Incluye información adicional en el campo `error`.)*
* CAP\_FLOW\_ERROR: Se ha producido un error interno durante la ejecución del flujo de captura. *(Incluye información adicional en el campo `error`.)*
* CAP\_INITIALIZATION\_ERROR: Error al inicializar los componentes necesarios del SDK. *(Incluye información detallada en el campo `error`.)*
* CAP\_FILE\_UPLOADER\_CAPTURE\_ERROR: Error durante el proceso de subida de los archivos generados en la captura.
* CAP\_IMAGE\_TOO\_LARGE: La imagen seleccionada desde galería supera el tamaño máximo configurado en `maxGalleryImageSizeKb`.
* CAP\_MANAGER\_NOT\_INITIALIZED: Los managers necesarios para ejecutar el proceso no han sido inicializados correctamente.
* CAP\_NO\_DATA\_ERROR: Los datos de entrada requeridos son nulos, inexistentes o insuficientes para continuar el proceso.
* CAP\_OPERATION\_NOT\_CREATED: No se ha podido crear o recuperar una operación activa necesaria para continuar. *(Incluye información detallada en el campo `error`.)*
* CAP\_QR\_CAPTURE\_ERROR: Error durante la captura o lectura del código QR.
* CAP\_QR\_GENERATION\_ERROR: Error al generar el código QR solicitado.
* CAP\_TIMEOUT: Se ha alcanzado el tiempo máximo permitido en alguna de las fases del proceso.
* CAP\_FLOW\_VIDEO\_RECORDING\_ERROR: Error durante la grabación de vídeo dentro del flujo establecido.
* CAP\_FLOW\_TRACKING\_ERROR: Error al realizar el tracking necesario para completar el flujo de captura.

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

#### **Recepción del resultado de la captura de documentos**

En la parte de SdkResult.Success - *data*, dispondremos de la clase *FileUploaderResult*.

Los campos devueltos en el resultado son los siguientes:

***capturedDocumentList***

Listado de ficheros capturados. Pueden ser imágenes o PDFs. Los campos devueltos de cada uno son:

* mimeType
* timestampMillis
* content: Contenido del documento. Será diferente si es una imagen o un documento PDF. Para diferenciarlo:

```kotlin
capturedDocumentList.forEach { documentData ->
                            when (val content = documentData.content) {
                                is FileContent.UploaderImage -> {
                                    // Uploader: New image found
                                    // content.image
                                }

                                is FileContent.UploaderDocument -> {
                                    // Uploader: New document found
                                    // content.bytes
                                }
                            }
                        }
```

#### **Recepción del resultado de la captura de QR**

En la parte de SdkResult.Success - *data*, dispondremos de la clase *QrResult*.

Los campos devueltos en el resultado son los siguientes:

***qrText***

Texto obtenido del QR

#### **Recepción del resultado de la generación de QR**

En la parte de SdkResult.Success - *data*, dispondremos de una SdkImage con el QR creado.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

#### **Configuración de la captura de documentos**

Para lanzar el componente actual, se deberá crear un objeto *FileUploaderConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `vibrationEnabled`: Indica la activación de la vibración cuando el widget termine satisfactoriamente.
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.
* `showDiagnostic`: Mostrar pantallas de diagnóstico al final del proceso.
* `showPreviousTip`: Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.
* `maxScannedDocs`: Número máximo de documentos que se podrán capturar
* `allowGallery`: Se habilita el acceso a la galería para la obtención de imágenes o PDFs
* `onlyGalleryMode`: Si está activo, el flujo se abre directamente en modo galería y no muestra la captura con cámara. Por defecto `true`.
* `maxGalleryImageSizeKb`: Tamaño máximo permitido para imágenes seleccionadas desde galería, en KB. Por defecto `2048`; si se supera se devuelve `CAP_IMAGE_TOO_LARGE`.

#### **Configuración de la captura de QR**

Para lanzar el componente actual, se deberá crear un objeto *QrCaptureConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `vibrationEnabled`: Indica la activación de la vibración cuando el widget termine satisfactoriamente.
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.
* `showDiagnostic`: Mostrar pantallas de diagnóstico al final del proceso.
* `showPreviousTip`: Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.
* `showTutorial`: Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.
* `cameraShape`: Permite elegir entre una máscara cuadrada y una redonda.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de ([Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Si se desea modificar los textos de la SDK habría que incluir el siguiente fichero XML en la aplicación del cliente, y modificar el valor de cada *String* por el deseado.

```
<resources>
    <!-- Previous Tip -->
    <string name="capture_component_qr_tip_title">Escanea el código QR</string>
    <string name="capture_component_qr_tip_message">&lt;b&gt; Enfoca &lt;/b&gt; el código QR &lt;b&gt; dentro del recuadro &lt;/b&gt;</string>
    <string name="capture_component_qr_tip_button">Comenzar</string>
    <string name="capture_component_qr_tip_anim_desc">Animación de un teléfono móvil haciendo una foto a un código QR. En la pantalla del móvil aparece un recuadro. Cuando el código QR encaja dentro del recuadro, la aplicación hace una foto.</string>
    <string name="capture_component_qr_tutorial_1_anim_desc">Se muestra un código QR sobre un fondo blanco. Los bordes del código QR no se distinguen con claridad. Mediante una animación, el fondo cambia de color.</string>
    <string name="capture_component_qr_tutorial_2_anim_desc">Un teléfono móvil hace una foto a un código QR. El código QR aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el código QR encaja dentro del recuadro, la aplicación hace una foto.</string>
    <!-- Tutorial -->
    <string name="capture_component_qr_tutorial_1">Asegúrate de que el código QR tiene &lt;b&gt; luz suficiente &lt;/b&gt; y &lt;b&gt; no hay reflejos &lt;/b&gt; o destellos sobre el código.</string>
    <string name="capture_component_qr_tutorial_2">Encaja los bordes del código QR dentro del recuadro.</string>
    <!-- Process -->
    <string name="capture_component_qr_camera_message">Mantén el QR en el centro</string>
    <string name="capture_component_button_message">Capturar</string>
    <!-- Diagnostic -->
    <string name="capture_component_timeout_title">Tiempo superado</string>
    <string name="capture_component_timeout_desc">Pedimos disculpas. No se ha podido hacer la captura</string>
    <string name="capture_component_internal_error_title">Hubo un problema técnico</string>
    <string name="capture_component_internal_error_desc">Pedimos disculpas. No se ha podido hacer la captura</string>

    <!-- WIDGET -->
    <!-- Previous Tip -->
    <string name="capture_widget_tip_title">Escanear documentos</string>
    <string name="capture_widget_tip_message">Haz una foto al documento, o sube una imagen.&lt;br&gt;&lt;br&gt; Puedes escanear varios documentos antes de finalizar.</string>
    <string name="capture_widget_tip_message_alt">Haz una foto al documento, o sube una imagen. Puedes escanear varios documentos antes de finalizar.</string>
    <string name="capture_widget_tip_button">Comenzar</string>
    <string name="capture_widget_tip_button_alt">Comenzar captura de documentos</string>
    <string name="capture_widget_tip_close_button_alt">Volver</string>
    <string name="capture_widget_tip_info_button_alt">Ver consejos</string>
    <string name="capture_widget_tip_anim_desc">Animación de un teléfono móvil haciendo una foto a un documento. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.</string>
    <!-- Camera -->
    <string name="capture_widget_document_camera_button_gallery">Galería</string>
    <string name="capture_widget_document_camera_button_capture">Capturar</string>
    <string name="capture_widget_document_camera_button_cancel">Cancelar captura</string>
    <string name="capture_widget_document_camera_button_finish">Finalizar</string>
    <!-- Gallery -->
    <string name="capture_widget_gallery_images">Imágenes</string>
    <string name="capture_widget_gallery_pdf">Seleccionar PDF</string>
    <string name="capture_widget_gallery_cancel">Cancelar</string>
    <!-- Confirmation -->
    <string name="capture_widget_image_captured">Imagen capturada</string>
    <string name="capture_widget_confirmation_message">¿Todos los datos se leen de forma clara y nítida?</string>
    <string name="capture_widget_confirmation_retry">NO, QUIERO REPETIR LAS FOTOGRAFÍAS</string>
    <string name="capture_widget_confirmation_continue">Sí, finalizar</string>
    <string name="capture_widget_confirmation_delete">Borrar foto</string>
    <string name="capture_widget_confirmation_image_unavailable">Vista previa no disponible</string>
    <string name="capture_widget_confirmation_no_images">No hay capturas disponibles</string>
    <string name="capture_widget_confirmation_delete_dialog_title">¿Quieres eliminar este documento?</string>
    <string name="capture_widget_confirmation_delete_dialog_message">Al eliminar este documento no vas a poder recuperarlo. Deberás realizar una nueva fotografía.</string>
    <string name="capture_widget_confirmation_delete_dialog_cancel">CANCELAR</string>
    <string name="capture_widget_confirmation_delete_dialog_confirm">ELIMINAR DOCUMENTO</string>
    <!-- Diagnostic -->
    <string name="capture_widget_timeout_title">Tiempo superado</string>
    <string name="capture_widget_timeout_desc">Pedimos disculpas. No se ha podido hacer la captura</string>
    <string name="capture_widget_internal_error_title">Hubo un problema técnico</string>
    <string name="capture_widget_internal_error_desc">Pedimos disculpas. No se ha podido hacer la captura</string>

</resources>

```

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
qr_anim_tip_1.json
qr_anim_tip_2.json
capture_anim_tip.json
```


# Videollamada - Videocall

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***VideoCall Component***.

Este componente se encarga de gestionar la comunicación entre un usuario y un agente (videoasistencia). Sus principales procesos son:

* Gestión interna de cámaras, micro y permisos.
* Conexión con los servicios.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencia

La dependencia específica del componente es:

```
implementation "com.facephi.androidsdk:videocall_component:$version"
```

***

## Controladores disponibles

| **Controlador**         | **Descripción**                                           |
| ----------------------- | --------------------------------------------------------- |
| VideoCallController     | Controlador principal de videollamada                     |
| StopVideoCallController | Detener la compartición de pantalla y la llamada en curso |

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento:

```kotlin
val response = SDKController.launch(
    VideoCallController(VideoCallConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoCallConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria no necesitará ningún parámetro:

```kotlin
VideoCallConfigurationData()
```

## Recepción del resultado

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'VideoCallError'.

Lista de errores:

* VCL\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad es incorrecto
* VCL\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo
* VCL\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VCL\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VCL\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VCL\_EMPTY\_LICENSE: El String de licencia está vacío
* VCL\_FACE\_DETECTION\_TIMEOUT: No se ha detectado cara
* VCL\_FETCH\_DATA\_ERROR: Error en la recogida del resultado
* VCL\_FLOW\_ERROR: Error en el proceso de flow
* VCL\_INITIALIZATION\_ERROR: Error de inicialización
* VCL\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* VCL\_NETWORK\_CONNECTION: Error en la conexión a internet
* VCL\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VCL\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VCL\_PERMISSION\_ERROR: El usuario ha rechazado los permisos
* VCL\_SCREEN\_SHARING\_PERMISSION\_ERROR: El usuario ha rechazado el permiso para compartir pantalla
* VCL\_SOCKET\_ERROR: Error en la conexión de los servicios
* VCL\_TIMEOUT: Timeout en el proceso
* VCL\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VCL\_UNKNOWN\_ERROR: Error desconocido
* VCL\_VIDEO\_CALL\_ACTIVE: No se puede iniciar porque ya hay una videollamada activa
* VCL\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de vídeo grabación está activo

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

En la parte de SdkResult.Success - *data*, dispondremos de la clase *VideoCallResult* que tendrá una única propiedad.

* `sharingScreen`: Indica si la llamada sigue activa con compartición de pantalla iniciada.

Cuando el resultado sea Success y esté activo el flag *sharingScreen* se podrá activar compartir pantalla.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoCallConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

Los campos incluidos en la configuración, normalmente **no es necesario que sean informados** ya que se completan internamente a través de la licencia usada.

Estos campos suelen informarse **solo** cuando el **servidor** es **OnPremise**.

* `url`: Ruta al socket de video.
* `apiKey`: ApiKey necesaria para la conexión con el socket de video.
* `tenantId`: Identificador del tenant que hace referencia al cliente actual, necesario para la conexión con el servicio de video.
* `activateScreenSharing`: Activar la opción de compartir pantalla en la llamada.
* `timeout`: Tiempo de espera para que un agente coja la llamada (ms).

### Compartir pantalla <a href="#id-72-compartir-pantalla" id="id-72-compartir-pantalla"></a>

Cuando el usuario active la funcionalidad de compartir pantalla se recibirá en el controlador el resultado con "sharingScreen = true". Esto indica que la llamada sigue en curso.

```kotlin
val result = SDKController.launch(
    VideoCallController(VideoCallConfigurationData(activateScreenSharing = true)))

when (result) {
    is SdkResult.Error -> {
        Napier.d("VideoCall: ERROR - ${result.error.name}")
    }

    is SdkResult.Success -> {
            Napier.d("VideoCall: OK - ScreenSharing: ${result.data.sharingScreen}")
        }
    }

```

Para detener la llamada se hará uso del controlador StopVideoCallController.

```kotlin
val controller = StopVideoCallController()

controller.setOutput { state ->
    Napier.d { "VIDEOCALL: SCREEN SHARING STATE: ${state.name}" }
}
viewModelScope.launch {
    SDKController.launch(controller)
}
```

Los posibles estados son:

```kotlin
AGENT_HANGUP,
PERMISSION_ERROR,
NETWORK_CONNECTION_ERROR,
UNKNOWN_ERROR,
SHARING,
CANCEL_BY_USER,
FINISH
```

El estado que indica la finalización completa de la llamada es FINISH.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse añadiendo un fichero XML de recursos en la aplicación cliente y sobrescribiendo los valores por defecto.

```kotlin

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Video call -->
    <string name="video_widget_call_component_text_waiting_agent_title">Connecting with an assistant...</string>
    <string name="video_widget_call_component_local">You</string>
    <string name="video_widget_call_component_agent">Assistant</string>
    <string name="video_widget_call_component_exit">Exit</string>
    <string name="video_widget_call_component_text_finish">Video assistance is complete</string>
    <string name="video_widget_call_component_phone_button_alt">Phone</string>
    <string name="video_widget_call_component_switch_button_alt">Switch camera</string>
    <string name="video_widget_call_component_restart">RETRY</string>
    <string name="video_widget_call_component_timeout_title">Time exceeded</string>
    <string name="video_widget_call_component_timeout_desc">Unable to connect with an agent.</string>
    <string name="video_widget_call_component_internal_error_title">There was a technical problem</string>
    <string name="video_widget_call_component_internal_error_desc">An assistant could not be reached.</string>
    <string name="video_widget_call_component_close_button_alt">Close</string>
    <string name="video_widget_call_component_back_button_alt">Back</string>
    <string name="video_widget_call_component_exit_alert_question">Do you want to end the call?</string>
    <string name="video_widget_call_component_exit_alert_finish">End</string>
    <string name="video_widget_call_component_exit_alert_accept">Accept</string>
    <string name="video_widget_call_component_exit_alert_cancel">Cancel</string>
    <string name="video_widget_call_component_skip">SKIP</string>
    <string name="video_widget_call_component_share_button_alt">Share screen</string>
</resources>

```

### Colores <a href="#id-82-colores" id="id-82-colores"></a>

```xml
<color name="colorVideoCallActionsBackground">#30333d</color>
<color name="colorVideoCallButtonBackground">#FF526080</color>
```

### Animaciones <a href="#id-83-animaciones" id="id-83-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
video_call_anim_waiting.json
```

### Vistas externas <a href="#id-84-vistas-externas" id="id-84-vistas-externas"></a>

Es posible modificar completamente las pantallas del componente manteniendo su funcionalidad y navegación. Para ello deben implementarse los interfaces siguientes:

Pantalla de diagnóstico de error:

```kts

interface IVideoCallErrorDiagnosticView {
    @Composable
    fun Content(
        error: VideoCallError,
        onRetry: () -> Unit,
        onClose: () -> Unit,
    )
}

```

Una vez creadas las clases que implementan los interfaces, en el lanzamiento del componente se podrá añadir el parámetro "customViews" para que se utilicen en el SDK.

\ <br>


# Videoidentificación - VideoID

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

ELa captura facial se realiza con el ***VideoID Component***.

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

* Gestión interna de cámaras, micro y permisos.
* Conexión con los servicios.
* Lectura del OCR y captura del documento.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```kotlin
implementation "com.facephi.androidsdk:video_id_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**            | **Descripción**                                    |
| -------------------------- | -------------------------------------------------- |
| VideoIdController          | Controlador principal de video identificación      |
| SignatureVideoIdController | Controlador para firmar un proceso con una Captura |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento:

```kotlin
val response = SDKController.launch(
    VideoIdController(VideoIdConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoIdConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```kotlin
VideoIdConfigurationData(
    mode = VideoIdMode.DOCUMENT_FRONT_BACK,
)
```

Los diferentes modos son:

* VideoIdMode.ONLY\_FACE
* VideoIdMode.FACE\_DOCUMENT\_FRONT
* VideoIdMode.FACE\_DOCUMENT\_FRONT\_BACK
* VideoIdMode.DOCUMENT\_FRONT
* VideoIdMode.DOCUMENT\_FRONT\_BACK

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'VideoIdError'.

Lista de errores:

* VID\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad es incorrecto
* VID\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo
* VID\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VID\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VID\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VID\_EMPTY\_LICENSE: El String de licencia está vacío
* VID\_FACE\_DETECTION\_TIMEOUT: No se ha detectado cara
* VID\_FETCH\_DATA\_ERROR: Error en la recogida del resultado
* VID\_FLOW\_ERROR: Error en el proceso de flow
* VID\_INITIALIZATION\_ERROR: Error de inicialización
* VID\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* VID\_NETWORK\_CONNECTION: Error en la conexión a internet
* VID\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VID\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VID\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* VID\_SOCKET\_ERROR: Error en la conexión de los servicios
* VID\_TIMEOUT: Timeout en el proceso
* VID\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VID\_VIDEO\_CALL\_ACTIVE: No se puede iniciar porque ya hay una videollamada activa
* VID\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de vídeo grabación está activo

### Recepción de ejecución correcta - *data* <a href="#id-62-recepcion-de-ejecucion-correcta-data" id="id-62-recepcion-de-ejecucion-correcta-data"></a>

En la parte de SdkResult.Success - *data*, dispondremos de la clase VideoIdResult.

El resultado devuelve las imágenes en formato **SdkImage**, es posible extraer el bitmap accediendo a *image.bitmap*. Si se quisiera convertir a base64 se puede utilizar la función:

`Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)`

Los campos devueltos en el resultado son los siguientes:

**frontDocumentData**

Datos del frente del documento. Incluye:

* documentImage: Imagen del documento
* documentFullImage: Imagen completa capturada
* documentFaceImage: Si se ha encontrado una cara en el documento se devuelve la imagen de la misma.
* iqaOverExposure: Valor numérico entre 0 y 1 que indica el nivel de sobreexposición de la imagen; un valor alto sugiere que la imagen está demasiado iluminada, lo que puede dificultar la lectura del documento.
* iqaReadable: Valor numérico entre 0 y 1 que indica la legibilidad del texto del documento; valores más altos implican que el texto es más claro y fácil de reconocer.
* iqaSharpness: Valor numérico entre 0 y 1 que indica la nitidez de la imagen del documento; valores altos reflejan una imagen más enfocada, lo que mejora la capacidad de extracción de datos.
* documentFaceImageTokenized: Si se ha encontrado una cara en el documento se devuelve la imagen cifrada de la misma.

**backDocumentData**

Datos del reverso del documento. Incluye:

* documentImage: Imagen del documento
* documentFullImage: Imagen completa capturada
* documentFaceImage: Si se ha encontrado una cara en el documento se devuelve la imagen de la misma.
* iqaOverExposure: Valor numérico entre 0 y 1 que indica el nivel de sobreexposición de la imagen; un valor alto sugiere que la imagen está demasiado iluminada, lo que puede dificultar la lectura del documento.
* iqaReadable: Valor numérico entre 0 y 1 que indica la legibilidad del texto del documento; valores más altos implican que el texto es más claro y fácil de reconocer.
* iqaSharpness: Valor numérico entre 0 y 1 que indica la nitidez de la imagen del documento; valores altos reflejan una imagen más enfocada, lo que mejora la capacidad de extracción de datos.
* documentFaceImageTokenized: Si se ha encontrado una cara en el documento se devuelve la imagen cifrada de la misma.

**faceImage**

Imagen del usuario capturada en la primera sección del proceso.

**ocrMap**

Mapa del OCR extraído del documento.

**ocrDiagnostic**

Diccionario con el diagnóstico OCR del documento. Las claves son los campos a validar y los valores son instancias de OcrDiagnostic.

Diagnóstico OCR extraído del documento.

* OK: El OCR es correcto.
* NOT\_FOUND: No se encuentra la clave OCR.
* TOLERANCE\_ERROR: El OCR no es correcto.
* WARNING: El OCR no es correcto, pero es solo una advertencia porque es un campo opcional.

**matchingSidesScore**

Valor numérico entre 0 y 1 que estima el nivel de coincidencia entre las caras del documento (frontal y trasera).

**documentType**

Tipo de documento obtenido.

**personalData**

Conjunto reducido de datos obtenidos del usuario:

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

**speechText**

Texto que el usuario deberá pronunciar durante la grabación del video.

**faceImageTokenized**

Imagen cifrada del usuario capturada en la primera sección del proceso.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto \_VideoIdConfigurationData \_ que será la configuración del controlador del componente.

Los campos incluidos en la configuración (**url, apiKey, tenantId**), normalmente **no es necesario que sean informados** ya que se completan internamente a través de la licencia usada.

Estos campos suelen informarse **solo** cuando el **servidor** es **OnPremise**.

**url**

Ruta al socket de video

**apiKey**

ApiKey necesaria para la conexión con el socket de video

**tenantId**

Identificador del tenant que hace referencia al cliente actual, necesario para la conexión con el servicio de video.

**sectionTime**

Indica la duración de las secciones con tiempo asociado (captura facial y cambio de cámara).

**mode**

* ONLY\_FACE: El proceso se realiza capturando la cara del usuario.
* FACE\_DOCUMENT\_FRONT: El proceso se realiza capturando la cara del usuario y la parte delantera del documento de identidad.
* FACE\_DOCUMENT\_FRONT\_BACK: El proceso se realiza capturando la cara del usuario y el documento de identidad completo.
* DOCUMENT\_FRONT: El proceso extrae la información sólo de la cara delantera del documento.
* DOCUMENT\_FRONT\_BACK: El proceso extrae la información sólo del documento completo.

**timeoutServerConnection**

Tiempo máximo de espera en ms para la respuesta del servidor.

**sectionTimeout**

Tiempo máximo permitido para completar una sección (en ms).

**autoFaceDetection**

Activa/Desactiva la detección automática de cara.

**debug**

Habilita la visualización de información adicional útil para el diagnóstico y seguimiento del comportamiento interno.

**countryFilter**

Permite restringir el procesamiento a un conjunto específico de países, aceptando un array de strings que representan los alias en formato ISO3 (código de 3 letras según el estándar ISO 3166-1).

**documentFilter**

Permite restringir los tipos de documentos aceptados durante la captura. Los valores posibles son:

* "IDC": Documento de Identidad (ID Card)
* "PSP": Pasaporte (Passport)
* "DLI": Licencia de Conducir (Driver License)
* "VIS": Visado (Visa)
* "FOC": Tarjeta de Extranjero (Foreign Card)
* "INV": Factura (Invoice)
* "CUS": Documento Personalizado (Custom Document)

**speechText**

Texto que el usuario deberá pronunciar durante la grabación del video.

**ocrValidations**

Diccionario con las validaciones OCR a realizar. Las claves son los campos a validar y los valores son instancias de OcrValidationValue.

OcrValidationValue tiene los siguientes campos:

* value: El valor a validar.
* tolerance: El nivel de tolerancia para la validación.
  * STRICT: Validación estricta.
  * LOW\_TOLERANCE: Validación con baja tolerancia.
  * MEDIUM\_TOLERANCE: Validación con tolerancia media.
  * HIGH\_TOLERANCE: Validación con alta tolerancia.
* validationType: El tipo de validación a realizar.
  * OPTIONAL: Validación opcional.
  * REQUIRED: Validación obligatoria.

**ocrMaxWarnings**

Número máximo de advertencias permitidas en la validación OCR.

**maxRetries**

Número máximo de reintentos permitidos para la validación OCR. El valor por defecto es 3.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse añadiendo un fichero XML de recursos en la aplicación cliente y sobrescribiendo los valores por defecto.

```kotlin

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Waiting -->
    <string name="video_widget_id_text_waiting_agent_title">Video ID</string>

    <!-- Process -->
    <string name="video_widget_id_document_front_message">Place the front of your document on the markers</string>
    <string name="video_widget_id_document_front_message_readable">Keep the front of your document on the markers</string>
    <string name="video_widget_id_document_front_message_not_readable">Bring the front of your document closer to the markers</string>
    <string name="video_widget_id_document_back_message">Now place the back of your document</string>
    <string name="video_widget_id_document_back_message_readable">Keep the back of your document on the markers</string>
    <string name="video_widget_id_document_back_message_not_readable">Bring the back of your document closer to the markers</string>
    <string name="video_widget_id_switch_camera_message">Get the document ready while we switch the camera</string>
    <string name="video_widget_id_finish_button">FINISH</string>
    <string name="video_widget_id_ready_button">CONTINUE</string>
    <string name="video_widget_id_exit_alert_cancel">Cancel</string>
    <string name="video_widget_id_exit_alert_question">Are you sure you want to finish the process?</string>
    <string name="video_widget_id_exit_alert_finish">Finish</string>
    <string name="video_widget_id_exit_alert_accept">Accept</string>
    <string name="video_widget_id_close_button_alt">Close</string>
    <string name="video_widget_id_back_button_alt">Back</string>
    <string name="video_widget_id_logo_alt">Logo</string>
    <string name="video_widget_id_face_message">Place your face inside the frame.</string>
    <string name="video_widget_id_multiple_face_message">Multiple faces detected. Place only your face inside the frame</string>
    <string name="video_widget_id_speech_message">Say out loud: "I (name and surname) accept the terms and conditions".</string>
    <string name="video_widget_id_front_document_captured_message">Front of the document captured successfully</string>
    <string name="video_widget_id_document_back_finish_message">Back of the document captured successfully</string>

    <!-- Diagnostic -->
    <string name="video_widget_id_restart_button">RECORD AGAIN</string>
    <string name="video_widget_id_timeout_title">Time exceeded</string>
    <string name="video_widget_id_timeout_desc">We couldn't complete the recording in time. Let's try again.</string>
    <string name="video_widget_id_face_timeout_title">We couldn't detect your face</string>
    <string name="video_widget_id_face_timeout_desc">Place your face on the marker to start the process</string>
    <string name="video_widget_id_internal_error_title">There was a technical problem</string>
    <string name="video_widget_id_internal_error_desc">We apologize. An unexpected error occurred. Try again.</string>
    <string name="video_widget_id_ocr_error_desc">The document could not be read. Please check the lighting and the distance to the camera</string>
    <string name="video_widget_id_finish_message">Video recording completed!</string>
</resources>

```

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
video_id_anim_doc_and_face.json
video_id_anim_face.json
video_id_anim_loading.json
```

### Vistas externas <a href="#id-83-vistas-externas" id="id-83-vistas-externas"></a>

Es posible modificar completamente las pantallas del componente manteniendo su funcionalidad y navegación. Para ello deben implementarse los interfaces siguientes:

Pantalla de diagnóstico de error:

```kts

interface IVideoIdErrorDiagnosticView {
    @Composable
    fun Content(
        error: VideoIdError,
        onRetry: () -> Unit,
        onClose: () -> Unit,
    )
}

```

Una vez creadas las clases que implementan los interfaces, en el lanzamiento del componente se podrá añadir el parámetro "customViews" para que se utilicen en el SDK.


# Videograbación - Videorecording

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La videograbación de pantalla se realiza con el ***VideoRecording Component***.

Este componente se encarga de capturar la pantalla del dispositivo en segundo plano. Está orientado principalmente para la grabación del proceso de onboarding.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```
implementation "com.facephi.androidsdk:video_recording_component:$version"
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**              | **Descripción**                                            |
| ---------------------------- | ---------------------------------------------------------- |
| VideoRecordingController     | Controlador principal de video grabación.                  |
| StopVideoRecordingController | Controlador para realizar la parada de la video grabación. |

***

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

### Lanzamiento de la captura <a href="#id-41-lanzamiento-de-la-captura" id="id-41-lanzamiento-de-la-captura"></a>

Para iniciar la grabación de pantalla:

```kotlin
val response = SDKController.launch(
    VideoRecordingController(
        VideoRecordingConfigurationData(...)
    )
)

when (response) {
    is SdkResult.Error   -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}

```

### Detener la captura <a href="#id-42-detener-la-captura" id="id-42-detener-la-captura"></a>

Para detener la grabación de pantalla:

```kotlin
val controller = StopVideoRecordingController()

controller.setOutput {
    Napier.d("APP: VIDEO RECORDING STATE (stop): ${it.name}")
}

SDKController.launch(controller)

```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'VideoRecordingError'.

Lista de errores:

* VRC\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VRC\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VRC\_EMPTY\_LICENSE: El String de licencia está vacío
* VRC\_INITIALIZATION\_ERROR: Error de inicialización
* VRC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VRC\_NETWORK\_CONNECTION: Error en la conexión a internet
* VRC\_PERMISSION\_ERROR: El usuario ha rechazado los permisos necesarios. Con `enableAudio=true` también cubre la denegación o cierre del permiso de micrófono y el rechazo del permiso de `MediaProjection`.
* VRC\_SOCKET\_ERROR: Error en la conexión de los servicios
* VRC\_UNKNOWN\_ERROR: Error desconocido
* VRC\_VIDEO\_CALL\_ACTIVE: No se puede iniciar porque hay una videollamada activa
* VRC\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VRC\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de grabación de vídeo está activo
* VRC\_FETCH\_DATA\_ERROR: Error en la recogida del resultado

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

En caso de éxito, el campo `data` contiene un objeto `VideoRecordingResult`.

* `state`: Estado de la grabación. `SHARING` indica que la grabación queda iniciada y `FINISH` indica que se ha detenido correctamente.

## Información avanzada

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-51-configuracion-avanzada-del-componente" id="id-51-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoRecordingConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

Los campos `url`, `apiKey` y `tenantId` normalmente **no es necesario que sean informados** ya que se completan internamente a través de la licencia usada.

Estos campos suelen informarse **solo** cuando el **servidor** es **OnPremise**.

#### **url**

Ruta al socket de video

#### **apiKey**

ApiKey necesaria para la conexión con el socket de video

#### **tenantId**

Identificador del tenant que hace referencia al cliente actual, necesario para la conexión con el servicio de video.

#### **enableAudio**

Activa la captura de audio durante la grabación de pantalla. Por defecto `false`. Cuando se informa como `true`, Android solicita `RECORD_AUDIO` antes del permiso de `MediaProjection`; si el usuario deniega o cierra la pantalla de permisos se devuelve `VRC_PERMISSION_ERROR` y la grabación no se inicia.

\ <br>


# Términos y condiciones

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La aceptación de términos y condiciones de uso se hace con el ***Terms Conditions Component***.

Este componente se encarga de realizar la captura de la respuesta del usuario ante unos términos y condiciones de uso. Sus principales procesos son:

* Lanzamiento de un visor de texto HTML.
* Captura de la respuesta del usuario.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

La dependencia específica del componente es:

```
implementation "com.facephi.androidsdk:terms_conditions_component:$version"
```

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

<table data-header-hidden><thead><tr><th width="193.87109375"></th><th></th></tr></thead><tbody><tr><td><strong>Controlador</strong></td><td><strong>Descripción</strong></td></tr><tr><td>TermsConditionsController</td><td>Controlador principal de captura de aceptación de términos</td></tr></tbody></table>

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura:

```kotlin
val response = SDKController.launch(
    TermsConditionsController(TermsConditionsConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *TermsConditionsConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```kotlin
TermsConditionsConfigurationData(
  termsConditions = "...html..."
)
```

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> Napier.d("Accepted")
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'DisclaimerError'.

Listado de errores:

* TER\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado de la actividad es incorrecto
* TER\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo
* TER\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* TER\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* TER\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* TER\_EMPTY\_LICENSE: El String de licencia está vacío
* TER\_FETCH\_DATA\_ERROR: Error en la recogida del resultado
* TER\_FLOW\_ERROR: Error en el proceso de flow
* TER\_INITIALIZATION\_ERROR: Error de inicialización
* TER\_INTERNAL\_LICENSE\_ERROR: Error interno relacionado con la licencia
* TER\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* TER\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* TER\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* TER\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* TER\_TIMEOUT: Timeout en el proceso

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

El usuario habrá aceptado las condiciones si se recibe SdkResult.Success.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *TermsConditionsConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `termsConditions`: Texto de condiciones y términos de uso que se mostrará al usuario
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Personalización del SDK](/sdks/sdk-mobile/android-sdk/personalizacion)), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Si se desea modificar los textos de la SDK habría que incluir el siguiente fichero XML en la aplicación del cliente, y modificar el valor de cada *String* por el deseado.

| **Name**                                    | **Value**                                                                           |
| ------------------------------------------- | ----------------------------------------------------------------------------------- |
| disclaimer\_widget\_agree\_button           | Aceptar                                                                             |
| disclaimer\_widget\_decline\_button         | Declinar                                                                            |
| disclaimer\_widget\_cancel\_alert\_title    | Declinar RGPD                                                                       |
| disclaimer\_widget\_cancel\_alert\_desc     | Declinando el RGPD provocará el cierre de la sesión actual. ¿Desea cerrar la sesión |
| disclaimer\_widget\_cancel\_alert\_accept   | Cerrar sesión                                                                       |
| disclaimer\_widget\_cancel\_alert \_dismiss | Cancelar                                                                            |


# Manejo de Errores

El lanzamiento del SDK siempre devuelve un resultado. El resultado puede ser negativo y contener un error. Cada Componente especifica en su propia página el listado de errores y su significado.


# Personalización

Esta guía explica cómo personalizar la apariencia del SDK en tus aplicaciones Android. Se recomienda agregar las modificaciones tanto en el tema claro como oscuro (night).

## Colores y logo

Para cambiar los colores principales y el logo del SDK:

1. Crea un archivo `sdk_styles.xml` en la aplicación del cliente.
2. Añade o modifica el valor *hex* (RGB) color y logo:

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- SdkTheme -->
    <color name="sdkPrimaryColor">#7636FC</color>
    <color name="sdkSecondaryColor">#03DAC5</color>
    <color name="sdkBackgroundColor">#FFFFFF</color>
    <color name="sdkErrorColor">#DD3631</color>
    <!-- SdkColorsPalette -->
    <color name="sdkAnimationColor">#3167FC</color>
    <color name="sdkButtonBackgroundColor">#3167FC</color>
    <color name="sdkTitleTextColor">#1D2C4D</color>
    <color name="sdkBodyTextColor">#526080</color>
    <color name="sdkSuccessColor">#07A13A</color>
    <color name="sdkNeutralColor">#202C4B</color>
    <color name="sdkAccentColor">#EA7547</color>
    <color name="sdkTopIconsColor">#243760</color>
    <color name="sdkButtonTextColor">#FFFFFF</color>
    <!-- SDK BUTTONS -->
    <dimen name="sdk_buttons_corner_dimen">32dp</dimen>
    <!-- SDK LOGO -->
    <drawable name="sdk_logo">@drawable/ic_demo_logo</drawable>

  <!-- ..Add particulars of each component... -->

</resources>
```

* Los **colores principales** que afectan también a animaciones son:\
  `sdkPrimaryColor`, `sdkErrorColor`, `sdkSuccessColor`, `sdkNeutralColor`, `sdkAccentColor`.
* Para incluir el **logo** hay que añadir en el fichero la siguiente línea, con el nombre configurado.

```xml
<!-- SDK LOGO -->
<drawable name="sdk_logo">@drawable/logo_name</drawable>
```

Se recomienda formato **vectorial (.xml).**

{% hint style="info" %}
Los componentes de Selphi y SelphID lleva su zip de recursos asociados que se mantiene ajeno a esta característica del SDK.
{% endhint %}

## Animaciones <a href="#id-2-animaciones" id="id-2-animaciones"></a>

Los archivos Lottie se pueden sobrescribir colocando los nuevos archivos en `res/raw/` con los mismos nombres:

```
anim_cancelled.json
anim_success.json
```

## Textos <a href="#id-3-textos" id="id-3-textos"></a>

Crea un fichero XML con las strings a sobrescribir:

```xml
    <!-- Exit Alert -->
    <string name="fphi_exit_alert_title">Finish the process</string>
    <string name="fphi_exit_alert_question">Do you want to finish the process?</string>
    <string name="fphi_exit_alert_finish">Finish</string>
    <string name="fphi_exit_alert_cancel">Cancel</string>
    <!-- Permissions -->
    <string name="fphi_permissions_camera">In order to continue, &lt;b&gt;you need to allow access to the camera&lt;/b&gt;.</string>
    <string name="fphi_permissions_camera_alt">In order to continue, you need to allow access to the camera.</string>
    <string name="fphi_permissions_title">Permission denied</string>
    <string name="fphi_permissions_general">In order to continue, &lt;b&gt;you need to allow access to the permission needed.&lt;/b&gt;</string>
    <string name="fphi_permissions_general_alt">In order to continue, you need to allow access to the permission needed.</string>
    <string name="fphi_permissions_microphone">In order to continue, &lt;b&gt;allow access to the microphone.&lt;/b&gt;</string>
    <string name="fphi_permissions_microphone_alt">In order to continue, allow access to the microphone.</string>
    <string name="fphi_permissions_confirm">Retry</string>
    <string name="fphi_permissions_confirm_settings">Go to settings</string>
    <!-- Messages -->
    <string name="fphi_close">Close process</string>
    <string name="fphi_info">Show tutorial</string>
    <string name="fphi_finish">Finish</string>
    <string name="fphi_retry">Retry</string>
    <!-- Tutorial -->
    <string name="fphi_tutorial_skip">SKIP</string>
    <string name="fphi_tutorial_skip_alt">Skip advices</string>
    <string name="fphi_tutorial_next">NEXT</string>
    <string name="fphi_tutorial_next_alt">Next advice</string>
    <string name="fphi_tutorial_previous">PREVIOUS</string>
    <string name="fphi_tutorial_previous_alt">Previous advice</string>
    <string name="fphi_tutorial_finish">FINISH</string>
    <string name="fphi_tutorial_finish_alt">Finish advices</string>
    <!-- Check Network -->
    <string name="fphi_network_connection_error_title">Check your internet connection</string>
    <string name="fphi_network_connection_error_desc">Check that your connection is stable and try again.</string>
    <!-- Diagnostic -->
    <string name="fphi_timeout_error_title">Time exceeded</string>
    <string name="fphi_timeout_error_desc">We apologize. The capture could not be made</string>
    <string name="fphi_internal_error_title">There was a technical problem</string>
    <string name="fphi_internal_error_desc">We apologize. The capture could not be made</string>

```

## Fuentes <a href="#id-4-fuentes" id="id-4-fuentes"></a>

* Añade los archivos `.ttf` en la carpeta `res/font/`.
* Asigna el **nombre exacto** esperado por el SDK. Si el nombre no coincide, la fuente no se aplicará.

<div align="left"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-3451c0ac6611ee68cc68ed39d8aa32b95dbe4dec%2Ffonts.png?alt=media" alt=""><figcaption></figcaption></figure></div>

## Iconos de la barra superior <a href="#id-6-iconos-de-la-barra-superior" id="id-6-iconos-de-la-barra-superior"></a>

Para personalizar los iconos de la barra superior, crea los recursos en `res/drawable/` con los siguientes nombres:

```
ic_fphi_close_arrow
ic_fphi_close
ic_fphi_info
```

## Imágenes de las pantallas de solicitud de permisos y diagnósticos <a href="#id-6-iconos-de-la-barra-superior" id="id-6-iconos-de-la-barra-superior"></a>

Para personalizar las imágenes que aparecen en las pantallas de solicitud de permiso y de diagnóstico, crea los recursos en `res/drawable/` con los siguientes nombres:

```
ic_fphi_camera_permission
ic_fphi_connection_error
ic_fphi_mic_permission
ic_fphi_timeout_error
ic_fphi_error
ic_fphi_support
```

<br>


# Aplicaciones de ejemplo

Una vez integrado el SDK de Facephi en tu proyecto Android, es necesario realizar la configuración inicial para que las soluciones biométricas funcionen correctamente.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

[![Android Repository v.2.3.X](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAE10lEQVR4nO1ZW6xcYxTeblHEParu4k5EH4aTufzrW7PWnnMcVHg5BIkXIigqgteKB0GlNJVIPIoHb4qUUh6J4KFH1Kn2EHFPVFP3Uxxk7dnTMzN7Zs+/Z2bPETkr+ZPJzOz1/99a379uOwiW5H8qzrlj1blrFVinRJsV2KHAHgH22bLPSjQT/7auSnQNMx8T/BdkcnLy0JDoJgVeF6K/FPgny7JnhOg1AW40XcGopVgsHhYC9wnwddbDp4D6SonuZeZlIwGhwBVKNDssAIlFtKtKdHluAMz1SrQhNwBJQM+Z54cKQlVPVOCDkYHAfrq9N14qLR8KCGY+09w9ahC6AGannWEgEM65E+IwuiggdIFms8y8ol9PLFsMOmkKzfoK0QI8s9iH13YwwMbsITZd6YNGO2a+VIG1SvT5ALSZEaIHpFJZGVUHwPoenpnwAmEhr1eeYOZTO9DQAP2uwJsKrKkxuxpw7vj4+BG2QufOs++qwJ1K9JIS/SzO3T01NXVQCxMqlZU9gOz0ophl7F5W7JZ9C4XCIV7WSvkvEZ3k4ck1qcoNqU/ZMfRE1STMvMKDjl+meiUuAHvympkvyAtI1bmK18VnvqGrEqtiPaPHdXkBUaLVXmcgerWjAosYGUrxh3ME8qxntPtzcmzsqKSCelPk440f7ULmBaQGXKjAH54GvTqhQIie8Hx4fV4gGiLAC55neTxol7gF9XHpWJCzKPOU5z15OfGwJRofXjLzwXkDkXL5fE+P7OgEZLeHBXYHI5AJotM82fF9Ekh90tHrou8LguCAvIEw88XNLIgmMPX1d5th5xIPNyJFyFy1eid07qyJYvG4Wrl8sn1urFEAaRajsqUGW7Z3VAuqntJk2FYRor0x0ncV2CbApxHdiL6NPscrJLo+yFkE2JjCil+brsGeTg9/Ev/4loXYKnCPxWmrWNW5S6zdbFglbyBrg+BA26tWqZyuzl1kkbJKdJVVzkL0qM3CYtrNJB5WYEsM5BGrLgV4UoAXFXhbgOnYIz/Ek8Ob8/SGEM3FU8rPBNiuRO8L8IoAT1sv1Mh5HcsUKzs8Q54p+MU8lQOI29ovdI9zPJRQUnUu9FUQr9+U6JZhUC1qH4geywIiXpJQtqpQONwnBHewyjt2l9o7PR+xztGMYbTtY9+5rn1R0z1pWVGfQnSrJaAUxd8J8Lww32GWEpGza7Xa0Q3dYRgeb32MjUOF6H4rL6zdzQpAF/LL5q4WMst2C3nW8FgPbgf2oZ0d1iaU+61fKi2PvjNK9nt4tJzpytSwZ5Giy4PT9nsIXKbAT2kgDHSPDnAwMES77CypvLXQ202BxfKmEmJLNAmJX+II8IUQbQ2dW5W6Qb3Svn1AIKu9phtC9GFmXmaQyPPd9kDPtc27AheisgDzHeg1P6z8EQeFrPdinpmL2TaqZ9FO0WmvDdZsSNeTpynCzOf0QakNmTcyisV1l/dGWXJJrN/fG0RvZBkAtohNKbJwOav+DJTaPvAbYBE5Q4g+XkQgH1nHGAxDyuXykVZpjhqIEG0d+rv4KCxbid0hmg0biADzQvRUroMOca5g/UFeQASYDoFSMAoxS1kIbn6PYi/8s+pR4Jum0DqrRHeNYtyUEMsjVrYosKlRvmSRuEjdZAXgIDlpSZYkyE/+BcW+JVjSStXbAAAAAElFTkSuQmCC)](https://github.com/facephi/sdk-mobile-android-samples/tree/2.3.X) [Android Repository Samples](https://github.com/facephi/sdk-mobile-android-samples)

## Configurar y ejecutar aplicaciones <a href="#pasos-para-configurar-y-ejecutar-las-aplicaciones" id="pasos-para-configurar-y-ejecutar-las-aplicaciones"></a>

1. Incluir el usuario y token facilitado por Facephi en el fichero `local.properties` (como se indica en Instalación).
2. Incluir el `applicationId` de la licencia en el Gradle de la aplicación.
3. Rellenar los datos en la clase `SdkData`.

## SdkData - Datos necesarios para el uso del SDK <a href="#sdkdata---datos-necesarios-para-el-uso-del-sdk" id="sdkdata---datos-necesarios-para-el-uso-del-sdk"></a>

Para que la aplicación funcione correctamente se deberán rellenar los siguientes datos:

```kotlin
// Datos para licencia online
val environmentLicensingData: EnvironmentLicensingData = EnvironmentLicensingData(
apiKey = "....."
)

// Datos para licencia offline
const val LICENSE = "...."
const val LICENSE_ONLINE = false

// Identificador del cliente y tipo de operación
const val CUSTOMER_ID = "...."
val OPERATION_TYPE = OperationType.ONBOARDING

// Selphi, con nombre del zip de recursos y datos de configuración
const val SELPHI_RESOURCES = ".....zip"
val selphiConfiguration = SelphiConfigurationData(
...,
resourcesPath = SELPHI_RESOURCES
)

// SelphID, con nombre del zip de recursos y datos de configuración
const val SELPHID_RESOURCES = "...zip"
val selphIDConfiguration = SelphIDConfigurationData(
...,
resourcesPath = SELPHID_RESOURCES
)

// URL de servicios de verificación
const val BASE_URL = "..."
```

**IMPORTANTE:** El `applicationId` de la aplicación debe coincidir con el solicitado en la licencia.

***


# Ajustes avanzados

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

En este apartado se amplía la información general del lanzamiento del SDK.

***

## Información avanzada del lanzamiento del SDK <a href="#id-2-informacion-avanzada-del-lanzamiento-del-sdk" id="id-2-informacion-avanzada-del-lanzamiento-del-sdk"></a>

En esta sección se va a ampliar la información del apartado de "Lanzamiento Simplificado del SDK".

### Añadir repositorio privado <a href="#id-21-anadir-repositorio-privado" id="id-21-anadir-repositorio-privado"></a>

Por cuestiones de seguridad y mantenimiento, los nuevos componentes de la ***SDKMobile*** se almacenan en unos repositorios privados que requieren de unas credenciales específicas para poder acceder a ellos. Esas credenciales deberá obtenerlas a través del *equipo de soporte* de **Facephi**.

Una vez obtenidas las credenciales, se deberá incluir el siguiente fragmento de código para configurar el repositorio maven en el **Gradle** de tu proyecto, o en el fichero **settings.gradle** del mismo. Se recomienda incluirlo tras *mavenCentral()*

```kotlin
maven {
    Properties props = new Properties()
    def propsFile = new File('local.properties')
    if(propsFile.exists()){
        props.load(new FileInputStream(propsFile))
    }
    name="external"
    url = uri("https://facephicorp.jfrog.io/artifactory/maven-pro-fphi")
    credentials {
        username = props["artifactory.user"] ?: System.getenv("USERNAME_ARTIFACTORY")
        password = props["artifactory.token"] ?: System.getenv("TOKEN_ARTIFACTORY")
    }
}
```

Para que el proyecto recupere correctamente las dependencias, se deberá tener las credenciales (Usuario y Token) configuradas correctamente

Hay varias formas de configurar las credenciales de acceso al repositorio:

* Como variables de entorno con el siguiente nombre. Por ejemplo:

  ```
  export USERNAME_ARTIFACTORY=YOUR_CREDENTIALS_USERNAME
  export TOKEN_ARTIFACTORY=YOUR_CREDENTIALS_TOKEN
  ```

  **Si las dependencia no las reconoce al sincronizar**, se deben incluir a través de variables de entorno en el archivo:

`~/.zshrc`

* Incluidos en el fichero *local.properties* con la siguiente estructura:

  ```
  artifactory.user=YOUR_CREDENTIALS_USERNAME
  artifactory.token=YOUR_CREDENTIALS_TOKEN
  ```

### Inicialización del SDK <a href="#id-22-inicializacion-del-sdk" id="id-22-inicializacion-del-sdk"></a>

**Debe evitarse inicializar un controlador que no vaya a usarse**.

El SDK funciona a través de un controlador principal (SDKController) que debe inicializarse correctamente para poder hacer uso del resto de funcionalidad. Los pasos a seguir en la inicialización son:

1. Incluir el objeto Application a través de la clase SdkApplication.
2. Decidir si la licencia se incluirá a través de un *String* o con un *servicio de licenciamiento remoto* (consultar **apartado 3.1**).
3. El controlador *TrackingController* en caso de querer conectar con la plataforma.

El **punto 3** es opcional, y requeriría usar el componente de Tracking (más información acerca de este módulo en su propia documentación).

Un ejemplo de inicialización sin *TrackingController* sería el siguiente:

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOffline("LICENSE")
)

val result = SDKController.initSdk(sdkConfig)

when (result) {
  is SdkResult.Success -> Napier.d("APP: INIT SDK: OK")
  is SdkResult.Error -> Napier.d(
          "APP: INIT SDK: KO - ${result.error.name}"
        )
}
```

Un ejemplo de inicialización con *TrackingController* sería el siguiente:

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOffline("LICENSE"),
    trackingController = TrackingController(),
)

val result = SDKController.initSdk(sdkConfig)

when (result) {
  is SdkResult.Success -> Napier.d("APP: INIT SDK: OK")
  is SdkResult.Error -> Napier.d(
          "APP: INIT SDK: KO - ${result.error.name}"
        )
}
```

#### **Inyección de licencias**

Como se ha comentado previamente, actualmente existen dos formas de inyectar la licencia:

**a. Obteniendo la licencia a través de un servicio**

A través de un servicio que simplemente requerirá una URL y un API-KEY como identificador. Esto evitaría problemas a la hora de manipular la licencia, así como la constante sustitución de dichas licencias a la hora de surgir algún problema con ella (malformación o modificación indebida, expiración de la licencia...)

Ejemplo de implementación en Kotlin:

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOnline(EnvironmentLicensingData(
            apiKey = "...")
      )),
)

val result = SDKController.initSdk(sdkConfig)

when (result) {
  is SdkResult.Success -> Napier.d("APP: INIT SDK: OK")
  is SdkResult.Error -> Napier.d(
          "APP: INIT SDK: KO - ${result.error.name}"
        )
}
```

Ejemplo de implementación en Java:

```kotlin
SDKController.INSTANCE.initSdk(
    new SdkApplication(activity.getApplication()),
    new LicensingOnline(new EnvironmentLicensingData(
      apiKey = "...")),
    sdkResult ->
    {
      if (sdkResult instanceof SdkResult.Success) {
        Napier.d("APP: INIT SDK: OK")
      } else if (sdkResult instanceof SdkResult.Error) {
        Napier.d("APP: INIT SDK: KO - ${it.error}")
      }
    }
  );
```

**b. Inyectando la licencia como String**

Se puede asignar la licencia directamente como un String, de la siguiente manera:

Ejemplo de implementación en Kotlin:

```kotlin
val sdkConfig = SdkConfigurationData(
    sdkApplication = SdkApplication(application),
    licensing = LicensingOffline("LICENSE"),
)

val result = SDKController.initSdk(sdkConfig)

when (result) {
  is SdkResult.Success -> Napier.d("APP: INIT SDK: OK")
  is SdkResult.Error -> Napier.d(
          "APP: INIT SDK: KO - ${result.error.name}"
        )
}
```

Ejemplo de implementación en Java:

```kotlin
SDKController.INSTANCE.initSdk(
  new SdkApplication(activity.getApplication()),
  new LicensingOffline("LICENSE"),
  sdkResult ->
  {
    if (sdkResult instanceof SdkResult.Success) {
      Timber.d("APP: INIT SDK: OK")
    } else if (sdkResult instanceof SdkResult.Error) {
      Timber.d("APP: INIT SDK: KO - ${it.error}")
    }
  }
);
```

#### **Recepción de errores**

En la parte del error, dispondremos de la clase SdkError.

Listado de errores:

* EMPTY\_LICENSE: Licencia vacía
* INIT\_AI\_MODELS(error: String): Error obtenido en el servicio de descarga de modelos
* INIT\_FLOW (error: String): Error obtenido en el servicio de descarga de flow
* LICENSE\_CHECKER\_ERROR (error: String): Error obtenido al verificar si la licencia es correcta
* LICENSING\_ERROR (error: String): Error obtenido en el servicio de descarga de licencias
* NETWORK\_CONNECTION\_ERROR: Error de conexión a internet
* TRACKING\_ERROR (error: String): Error obtenido al iniciar el controlador de tracking

***

## Iniciar nueva operación <a href="#id-3-iniciar-nueva-operacion" id="id-3-iniciar-nueva-operacion"></a>

Cada vez que se desee iniciar el flujo de alguna operación nueva (ejemplos de operaciones serían: *onboarding, authentication, videoCall*,...) es esencial indicarle al **SDKController** que ésta va a comenzar, y así la SDK sabrá que las próximas llamadas de **Componentes** (también llamados **Steps**) formarán parte de dicha operación.

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método **newOperation**

Este método tiene los siguientes parámetros de entrada:

1. **operationType**: Indica si se va a hacer un proceso de ONBOARDING o de AUTHENTICATION.
2. **customerId**: Id único del usuario si se tiene (controlado a nivel de aplicación)
   1. Este parámetro aparecerá reflejado para cada operación en la plataforma.
3. **steps**: Lista de pasos de la operación si se han definido previamente
4. **enableTracking**: Permite activar o desactivar el envío de eventos de tracking para esta operación. Si no se informa, se considera `true`.

Hay 2 maneras de realizar este inicio de operación, dependiendo de si **se conocen los pasos** que formarán el flujo del proceso de registro o autenticación (en caso de que los componentes se ejecuten de forma secuencial y siempre de la misma forma) o, en caso contrario, de que el flujo **no esté definido** y sea desconocido (por ejemplo, el cliente final es el que decide el orden de ejecución de los componentes).

* Flujo **conocido** (aparecerá la operación *trackeada* en la plataforma con todos los pasos de la lista).

  Ejemplo de implementación Kotlin:

```kotlin
val result = SDKController.newOperation(
        operationType = OperationType.ONBOARDING,
        customerId = "customer_id",
        steps = listOf(Step.SELPHI_COMPONENT, Step.SELPHID_COMPONENT),
        enableTracking = true)
when (result) {
    is SdkResult.Success -> {
        Timber.d("APP: NEW OPERATION OK")
        Timber.d("Session ID: ${result.data.sessionId}")
        Timber.d("Operation ID: ${result.data.operationId}")
    }
    is SdkResult.Error -> {
        Timber.d("APP: NEW OPERATION ERROR: ${result.error.name}")
    }
}
```

Ejemplo de implementación Java:

```kotlin
 SDKController.INSTANCE.newOperation(
        OperationType.ONBOARDING,
        "customer_id",
        [Step.SELPHI_COMPONENT, Step.SELPHID_COMPONENT]
        ){
          if (sdkResult instanceof SdkResult.Success) {
            Napier.d("APP: NEW OPERATION: OK")
          } else if (sdkResult instanceof SdkResult.Error) {
            Napier.d("APP: NEW OPERATION: KO - ${it.error}")
          }
        }
  );
```

* Flujo **desconocido** (aparecerá la operación *trackeada* en la plataforma con puntos suspensivos). Ejemplo de implementación Kotlin:

```kotlin
val result = SDKController.newOperation(
        operationType = OperationType.ONBOARDING,
        customerId = "customer_id",
        enableTracking = true)
when (result) {
    is SdkResult.Success -> {
        Timber.d("APP: NEW OPERATION OK")
    }
    is SdkResult.Error -> {
        Timber.d("APP: NEW OPERATION ERROR: ${result.error.name}")
    }
}
```

Ejemplo de implementación Java:

```kotlin
 SDKController.INSTANCE.newOperation(
        OperationType.ONBOARDING,
        "customer_id"
        ){
          if (sdkResult instanceof SdkResult.Success) {
            Napier.d("APP: NEW OPERATION: OK")
          } else if (sdkResult instanceof SdkResult.Error) {
            Napier.d("APP: NEW OPERATION: KO - ${it.error}")
          }
        }
  );
```

`sdkResult` → Contiene en `data` la información de la operación creada.

Cuando el resultado es correcto, `data` es un `OperationResult` con:

| Campo         | Descripción                                                   |
| ------------- | ------------------------------------------------------------- |
| `sessionId`   | Identificador de la sesión creada o recuperada por el SDK.    |
| `operationId` | Identificador de la operación activa.                         |
| `type`        | Tipo de operación iniciado (`ONBOARDING` o `AUTHENTICATION`). |
| `customerId`  | Identificador de usuario asociado a la operación.             |

**Una vez creada la operación** se podrán ejecutar los componentes de la SDK asociados a esta operación. Consultar la documentación específica de cada componente para saber cómo hacerlo.

### **Tipos de operación existentes** <a href="#id-31-tipos-de-operacion-existentes" id="id-31-tipos-de-operacion-existentes"></a>

En la actualidad, existen las siguientes operaciones, durante las cuales se hacen uso de unos determinados **Componentes (STEPS).**

A continuación se muestra una tabla con la relación entre *operaciones* y *steps*:

| **Operación (OperationType)** | **Componente (Step)**                          | Descripción                                                                                                                              |
| ----------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| ONBOARDING                    | <p>SELPHI\_COMPONENT<br>SELPHID\_COMPONENT</p> | <p>- Validación facial de un selfie contra la cara de un documento<br>- Extracción del OCR del documento<br>- Detección de vivacidad</p> |
| AUTHENTICATION                | SELPHI\_COMPONENT                              | <p>- Validación facial mediante plantillas<br>- Detección de vivacidad</p>                                                               |

Esta lista se irá ampliando en próximas actualizaciones de la SDK, según vayan apareciendo nuevos componentes y casos de uso.

{% hint style="info" %}
Si la creación de una nueva operación devuelve un error del tipo **INTERNAL\_ERROR** se debe principalmente a un problema de **seguridad**. Para poder investigar la causa, es posible recuperar el token asociado al error, el cual proporciona información adicional para su análisis.

```
if (result.error is SdkError.INTERNAL_ERROR){
    val token = (result.error as SdkError.INTERNAL_ERROR).error
}
```

{% endhint %}

***

## Seguridad <a href="#id-24-lanzamiento-de-los-componentes" id="id-24-lanzamiento-de-los-componentes"></a>

El SDK de Android incorpora un sistema de seguridad destinado a detectar y bloquear entornos potencialmente poco fiables o que puedan indicar intentos de ataque.<br>

Este mecanismo está habilitado por defecto, permite identificar situaciones que podrían comprometer la seguridad y previene la ejecución del SDK en contextos que no se consideran seguros:

```
SDKController.securityMode(enable: Boolean) 
```

***

## Lanzamiento de componentes <a href="#id-4-lanzamiento-de-componentes" id="id-4-lanzamiento-de-componentes"></a>

La funcionalidad del SDK se divide en diferentes componentes con controladores particulares. Estos controladores se “lanzarán” desde el controlador general.

Una vez creada la **nueva operación** (**apartado 3**), se podrán lanzar los diferentes controladores de la SDK. Para consultar esta información se deberá acceder a la **documentación de cada uno de los componentes específicos**.

Ejemplo de lanzamiento Kotlin:

```kotlin
val result = SDKController.launch(ExampleController(ConfigurationData()))
when (result) {
    is SdkResult.Success -> {
        //Result OK
        result.data
    }
    is SdkResult.Error -> {
        //Result KO
        result.error.name
    }
}
```

Ejemplo de lanzamiento Java:

```kotlin
SDKController.INSTANCE.launch(
    new ExampleController(new ConfigurationData()) {
        if (sdkResult instanceof SdkResult.Success) {
            //Result OK
            it.data
          } else if (sdkResult instanceof SdkResult.Error) {
            //Result KO
            it.error.name
          }
    }
)
```

### Opciones para el lanzamiento del componente <a href="#id-41-opciones-para-el-lanzamiento-del-componente" id="id-41-opciones-para-el-lanzamiento-del-componente"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Hay dos formas de lanzar el componente:

* **\[CON TRACKING]** Esta llamada permite lanzar la funcionalidad del componente con normalidad, pero sí se trackearán los eventos internos al servidor de *tracking*:

```
val response = SDKController.launch(
    ExampleController(SConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

* **\[SIN TRACKING]** Esta llamada permite lanzar la funcionalidad del componente con normalidad, pero **no se trackeará** ningún evento al servidor de *tracking*:

```
val response = SDKController.launchMethod(
    ExampleController(ConfigurationData(...))
)
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

El método **launch** debe usarse **por defecto**. Este método permite utilizar ***tracking*** en caso de estar su componente activado, y no lo usará cuando esté desactivado (o no se encuentre el componente instalado).

Por el contrario, el método **launchMethod** cubre un caso especial, en el cual el integrador tiene instalado y activado el tracking, pero en un flujo determinado dentro de la aplicación no desea trackear información. En ese caso se usa este método para evitar que se envíe esa información a la plataforma.

***

## Retorno de resultado <a href="#id-5-retorno-de-resultado" id="id-5-retorno-de-resultado"></a>

El resultado de cada componente será devuelto a través de la SDK manteniendo siempre la misma estructura a través de la clase ***SdkResult*** cuya clase es una Sealed Class que puede tener 2 posibles estados:

* SdkResult.Success: Indica que la operación ha finalizado correctamete y en su interior tiene:
  * ***data:*** Contiene el tipo de dato que sea necesario según el proceso/componente lanzado.
* SdkResult.Error
  * ***error:*** Contiene el tipo de error que sea necesario según el proceso/componente lanzado.

En la documentación de cada componente específico se desglosarán los diferentes campos que puede devolver este objeto

Ejemplo de uso:

```kotlin
when (result) {
    is SdkResult.Success -> {
        Napier.d("Selphi: OK")
        // SelphiResult:
        // result.data.bestImage
    }

    is SdkResult.Error -> Napier.d("Selphi: KO - ${result.error.name}")
}
```

***

## Controladores auxiliares <a href="#id-6-controladores-auxiliares" id="id-6-controladores-auxiliares"></a>

En este apartado se incluyen otros controladores y operaciones auxiliares, algunos de ellos opcionales, y que pueden ser necesarios para la correcta finalización del flujo.

Estos campos son necesarios para la comunicación con el servicio de **Facephi**, en caso de querer realizar cualquier **verificación** y de desear realizar el *tracking* de una operación determinada.

### Obtención del OperationId <a href="#id-61-obtencion-del-operationid" id="id-61-obtencion-del-operationid"></a>

```
val result = SDKController.launch(GetOperationIdController())
Napier.d("Operation ID ${result}")
```

### Obtención del OperationType <a href="#id-62-obtencion-del-operationtype" id="id-62-obtencion-del-operationtype"></a>

```
val result = SDKController.launch(GetOperationTypeController())
Napier.d("Operation type ${result}")
```

### Obtención del SessionId <a href="#id-63-obtencion-del-sessionid" id="id-63-obtencion-del-sessionid"></a>

```
val result = SDKController.launch(GetSessionIdController())
Napier.d("Session ID ${result}")
```

### Obtención del CustomerID <a href="#id-64-obtencion-del-customerid" id="id-64-obtencion-del-customerid"></a>

```
val result = SDKController.launch(GetCustomerIdController())
Napier.d("Customer ID ${result}")
```

### Asignación del CustomerID <a href="#id-65-asignacion-del-customerid" id="id-65-asignacion-del-customerid"></a>

```
SDKController.launch(CustomerIdController("CustomerId"))
```

***

## Opciones de depuración y control de errores <a href="#id-7-opciones-de-depuracion-y-control-de-errores" id="id-7-opciones-de-depuracion-y-control-de-errores"></a>

Existen ciertas opciones en el SDK que permiten un aumento en los logs de depuración para poder comprobar que todo funciona de manera correcta.

### Control de errores en las conexiones de Tracking con la plataforma <a href="#id-71-control-de-errores-en-las-conexiones-de-tracking-con-la-plataforma" id="id-71-control-de-errores-en-las-conexiones-de-tracking-con-la-plataforma"></a>

Una vez el SDK se haya iniciado correctamente, se pueden aplicar ciertos ajustes para tener una mayor información acerca de los posibles errores en tracking, se puede realizar un seguimiento a través de este lanzamiento de controlador:

```kotlin
SDKController.launch(TrackingErrorController {
    Napier.d("Tracking Error: ${it.name}")
})
```

### Activación de Logs de depuración general <a href="#id-72-activacion-de-logs-de-depuracion-general" id="id-72-activacion-de-logs-de-depuracion-general"></a>

```kotlin
 if (BuildConfig.DEBUG) {
  SDKController.enableDebugMode()
 }
```

***

## Seguimiento y Análisis de Eventos en la Aplicación <a href="#id-8-seguimiento-y-analisis-de-eventos-en-la-aplicacion" id="id-8-seguimiento-y-analisis-de-eventos-en-la-aplicacion"></a>

La funcionalidad de eventos permite registrar e interpretar interacciones clave dentro de la aplicación, como cambios de pantalla y acciones del usuario, facilitando el análisis del comportamiento en tiempo real.

Cada evento se envía con un sello de tiempo, tipo y detalle específico, proporcionando un seguimiento estructurado y optimizando la experiencia del usuario con datos precisos y accionables.

```kotlin
 SDKController.getAnalyticsEvents { time, componentName, eventType, info ->
            Log.i { "EVENTS", "*** $time - ${componentName.name} -" +
                " ${eventType.name} -  ${info ?: ""} " }
        }
```


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del SDK de Facephi para Android. Recomendamos mantener siempre tu integración actualizada a la última versión estable.

## Última versión

### **Versión: 2.12.2**

*Octubre 2026*

* SelphID
  * Se ha resuelto un fallo intermitente (crash) que provocaba el cierre inesperado del sistema en determinados modelos de chipsets MediaTek bajo condiciones específicas de carga.
  * Se ha actualizado el bundle de recursos con mejoras en los siguientes documentos
    * Cédula de Honduras
    * Cédula de El Salvador
    * Cédula de Costa Rica
    * Cédula de Nicaragua
    * Nuevo modelado del Permiso Laboral de Costa Rica
    * Nuevo modelado del Documento de Extranjería de Costa Rica (DIMEX)

### **Versión: 2.12.0**

*Septiembre 2026*

* Tracking
  * Nueva versión del widget: 1.4.11
  * Servicio de obtención de tiempo remoto
* Selphi
  * Nueva versión del widget: 6.4.1
  * Mejoras en IAD
* SelphID
  * Nueva versión del widget: 1.41.5
  * Mejoras en la repetición de la captura de la parte trasera del componente
  * Mejoras en el sistema de trazas/logs (versión MBSDR)
* Video ID
  * Nueva versión del widget: 0.3.1
  * Actualización del Reader

### **Versión: 2.11.0**

*Septiembre 2026*

* Selphi
  * Nueva versión del widget: 6.4.0
* SelphID
  * Nueva versión del widget: 1.41.4

    * Nuevo parámetro de entrada que activa el modo de lectura de códigos de barras cuando hay dificultad de lectura

    (solo activo en versión MBSDR y con zip de recursos de una versión > 1.41.4)

    ```
    encodedDataFocusEnabled
    ```

    * Nuevo parametro de salida

    (solo activo en versión MBSDR y con zip de recursos de una versión > 1.41.4)

    ```
    encodedDataImages: List<SelphIDEncodedDataImage>
    tokenEncodedDataImages: List<SelphIDEncodedDataToken>
    ```

### **Versión:** 2.10.0

*Agosto 2026*

* General
  * Nueva versión de la librería de diseño: 2.7.7
  * Nuevo scroll completo de pantalla en:
    * Pantalla de tip previo
    * Pantalla de tutorial
    * Pantalla de diagnóstico
  * Nueva cancelación del proceso del SDK
* Selphi
  * Nueva versión del widget: 6.3.0
* SelphID
  * Nueva versión del widget: 1.40.0
* NFC
  * Nueva versión del widget: 0.3.10
  * Mejoras en el lanzamiento del controlador
* Capture
  * Nueva versión del widget: 1.3.6
  * Mejoras en el lanzamiento del controlador FileUploader

### **Versión:** 2.9.0

*Julio 2026*

* General
  * Nuevos colores para la personalización
* Términos y condiciones de uso
  * Creación del nuevo componente
* Tracking
  * Nueva versión del widget: 1.4.5
  * Eventos para los términos y condiciones de uso
* Selphi
  * Nueva versión del widget: 6.2.3
* SelphID
  * Nueva versión del widget: 1.39.3
* Phingers
  * Nueva versión del widget: 1.4.9
  * Actualización de dependencias internas
* Voice
  * Inclusión del widget KMP: 0.1.7
* NFC
  * Nueva versión del widget: 0.3.8
  * Mejoras en la navegación
  * Mejoras en las pantallas

### **Versión:** 2.8.1

*Junio 2026*

* General
  * API Version: 35
  * Actualización de componentes del SDK Android a la línea 2.8.1
  * Se fuerza el uso de OkHttp como motor HTTP en Android para el SDK y Licensing, mejorando la compatibilidad con aplicaciones que usan dependencias antiguas de Ktor
  * Mejora del manejo de errores de Licensing cuando el cliente HTTP no puede inicializarse: el flujo devuelve un error controlado en lugar de propagar un fallo interno
  * Reglas de consumo actualizadas para reducir avisos de R8/ProGuard en dependencias opcionales de Ktor, ubicación y Error Prone
  * Mejora interna de los checks de release para validar los tests Android en Debug y evitar reglas ProGuard solo para pruebas
  * Dependencias base actualizadas:
    * Facephi Security: 1.2.10
    * Facephi Logger: 1.2.3
    * Facephi Tokenizer: 1.1.5
    * Facephi Licensing: 2.6.1
* Tracking
  * Nueva versión del widget: 1.4.4
* Selphi
  * Nueva versión del widget: 6.2.1
* SelphID
  * Nueva versión del widget: 1.39.2
* Phingers
  * Nueva versión del widget: 1.3.5

***

## Versiones anteriores

### **Versión:** 2.8.0

*Mayo 2026*

* General
  * API Version: 35
  * Actualización de componentes del SDK Android a la línea 2.8.0
  * Mejora de la limpieza de sesión al cerrar el SDK, incluyendo caches internos y callbacks registrados
  * Mejora de la resolución de colores por atributos de tema en Android
  * Dependencias base actualizadas:
    * Facephi Security: 1.2.9
    * Facephi Logger: 1.2.3
    * Facephi Tokenizer: 1.1.5
* Tracking
  * Nueva versión del widget: 1.4.3
  * Actualización de dependencias internas del widget y alineación del bridge de integración<br>
* Capture
  * Nueva versión del widget: 1.2.0
  * Soporte de modo solo galería en File Uploader mediante `onlyGalleryMode`
  * Nuevo límite `maxGalleryImageSizeKb` para rechazar imágenes de galería demasiado grandes antes de procesarlas
  * Se propaga `maxScannedDocs` al widget como máximo de documentos o capturas permitidas
  * Nuevo error `IMAGE_TOO_LARGE` (`CAP_862`) cuando una imagen supera el tamaño configurado
  * Nueva pantalla de galería con textos, iconografía y estados de error específicos<br>
* NFC
  * Nueva versión del widget: 0.2.2
  * El componente delega la lectura NFC y la tokenización en el widget principal, manteniendo la fachada pública del SDK
  * Se eliminan vistas legacy de consejo previo y diagnóstico de error; la personalización pública queda limitada a bottom sheets
  * Se mantienen `showDiagnostic`, `showTutorial` y `showPreviousTip` para controlar la experiencia visual del flujo
  * Corrección del progreso por puntos durante la lectura NFC
  * Saneado de logs de depuración para evitar trazas sensibles o excesivas
  * Mejora de compatibilidad con el contrato de resultados y validaciones criptográficas expuestas por el widget<br>
* Phingers
  * Nueva versión del widget: 1.3.1
  * Soporte de nuevo servicio de licencia en el widget
  * Corrección de trazas de licencia del widget para mantener logs más consistentes
  * Phingers TF permite informar `licenseKey`, `product` y `operationId` al widget
  * Mejora de propagación de configuración de diagnóstico en flujos remotos<br>
* Video Widget
  * Nueva versión del widget compartido: 0.0.9
  * Centraliza el runtime de Video ID, VideoCall y Video Recording en `com.facephi.video:fphivideo`
  * En Android el widget contiene Activities, permisos, servicios foreground, sockets, streaming de video, MediaProjection y recursos nativos de vídeo
  * Los componentes del SDK quedan como fachadas públicas y adaptadores de configuración, resultados, errores, analytics y vistas personalizadas<br>
* Video ID
  * Migración del runtime de video a un widget compartido de video
  * Mejora de cancelación y limpieza cuando se interrumpe el flujo
  * El identificador de firma se propaga al runtime para distinguir flujos de Video ID y firma
  * Se evita iniciar Video ID si hay una videollamada o una grabación activa<br>
* VideoCall
  * Migración del runtime de videollamada a un widget compartido de video
  * Mejora de la gestión de notificaciones internas de cancelación e interrupción
  * Se evita iniciar una videollamada si ya hay otra videollamada o una grabación activa<br>
* Video Recording
  * Migración del runtime de grabación a un widget compartido de video
  * Nuevo parámetro `enableAudio`, desactivado por defecto, para permitir grabación de audio durante la grabación de pantalla
  * Cuando `enableAudio=true`, Android solicita `RECORD_AUDIO` antes del permiso de `MediaProjection`
  * Si se deniega el micrófono, se muestra la pantalla de permisos del design system para reintentar o abrir ajustes
  * Si se cierra la pantalla de permisos o se rechaza `MediaProjection`, el flujo finaliza con `PERMISSION_ERROR` sin iniciar la grabación
  * La pista de micrófono se publica junto a las credenciales de pantalla cuando el audio está activado
  * Ajuste de la posición del sello temporal sobre el frame de grabación
  * Mejora de la gestión de notificaciones internas para detener o cancelar la grabación

### **Versión:** 2.7.0

*Marzo 2026*

* General
  * API Version: 35
  * Refuerzo del control de entorno seguro en la inicialización del SDK, el inicio de flujos, la restauración de sesión y la ejecución de componentes
  * El método SDKController.securityMode(...) deja de estar disponible; el control del chequeo de seguridad pasa a la configuración inicial del SDK y queda reservado para entornos de desarrollo o demo
  * La propiedad orientation del SDK utiliza ahora SdkViewOrientation, desacoplada del módulo visual
  * La restauración de sesión devuelve ahora un resultado explícito para facilitar el manejo de errores
  * Nuevo error de flujo FLOW\_INTERNAL\_ERROR con token para bloqueos internos o de seguridad
  * Normalización del uso de errores internos en distintos componentes del SDK
  * Mejoras visuales y de comportamiento en landscape, rotación y ajuste de vistas
  * Facephi Security: 1.2.7
  * Facephi Logger: 1.2.2
  * Facephi Tokenizer: 1.1.2
* Tracking
  * Nueva versión del widget: 1.4.0
  * Se añade el campo includeIAD al tracking de selfie<br>
* Capture
  * Nueva versión del widget: 1.1.8
* Selphi
  * Nueva versión del widget: 6.1.0
  * Corrección en la identificación del flavor IAD
  * Envío correcto del asset IAD al tracking
  * Se informa explícitamente cuando la captura incluye IAD<br>
* SelphID
  * Nueva versión del widget: 1.38.0
  * Nuevo selector de país y tipo de documento
  * Nuevos parámetros para limitar países y tipos documentales permitidos
  * Mejoras visuales y de experiencia en la pantalla de selección
  * Si la aplicación pasa a segundo plano durante el flujo, la salida se resuelve correctamente como cancelación de usuario<br>
* Phingers
  * Nueva versión del widget: 1.1.7
  * Mejoras en la clasificación de errores internos
  * Nuevos ajustes de configuración para template y timeout en flujos remotos<br>
* Video ID
  * Mejoras en la cancelación del flujo para finalizar correctamente y evitar errores tardíos
  * Ajustes en landscape y en la previsualización de rotación
  * Corrección del tamaño de la máscara documental en vertical
  * Nuevos campos de configuración para validaciones OCR, calidad documental y reintentos<br>
* NFC
  * Actualización de dependencias internas
    * jmrtd 0.8.5
  * Mejoras en la resolución del nombre y número personal del titular
  * Refuerzo del chequeo de seguridad antes de iniciar el componente
  * Corrección SOP-3866: se priorizan los datos DG11 para obtener la información del titular cuando están disponibles

### **Versión:** 2.6.0

*Febrero 2026*

* General
  * API Version: **35**
  * Mejoras en diseño y accesibilidad
  * Facephi Security: 1.2.3
  * Facephi Logger: 1.2.2
  * Facephi Tokenizer: 1.1.2
* Tracking
  * Nueva versión del widget: 1.2.8
* Capture
  * Nueva versión del widget: 1.1.7
* Selphi
  * Nueva versión del widget: 6.0.3
* SelphID
  * Nueva versión del widget: 1.37.1
* Phingers <mark style="color:orange;">**\***</mark>
  * Mejoras en diseño
  * Nueva versión del widget: 1.1.6
  * Mejoras en el proceso de captura
* Voice
  * Correcciones de flujo
  * Mejoras en accesibilidad
* NFC
  * Nuevos datos cifrados a la salida

<mark style="color:$danger;">**\*IMPORTANTE:**</mark> <mark style="color:$danger;">Se necesita una nueva licencia para utilizar esta version</mark>

### **Versión:** 2.5.0

*Diciembre 2025*

* General
  * Soporte de rotación/landscape en SDK y widgets
  * Actualización de dependencias:
    * API Version: **36**
    * Gradle 8.13
    * Android Gradle Plugin 8.9.3 -> 8.13.1
    * Kotlin 2.1.21 -> 2.2.21
    * Compose 1.9.5/1.9.3
    * Lifecycle 2.10.0
    * Ktor 3.3.2
    * Serialization 1.9.0
    * ZXing 3.5.4
    * Datastore 1.2.0
    * Kover 0.9.3
    * Facephi Security 1.2.0
    * Facephi Logger 1.2.0
    * Facephi Tokenizer 1.1.0
* Tracking
  * Nueva versión del widget: 1.2.2
* Capture
  * Nueva versión del widget: 1.1.0
* Selphi
  * Nueva versión del widget: 5.20.0
* SelphID
  * Nueva versión del widget: 1.36.1
* NFC
  * Nueva vista de progreso de lectura en porcentaje y estilo configurable
  * Correcciones de flujo y manejo de errores en lectura

### **Versión:** 2.4.3

* Selphi
  * Nueva versión del widget: 5.20.0

### **Versión:** 2.4.2

* SelphID
  * Nueva versión del widget: 1.36.0
* Tracking
  * Nueva versión del widget: 1.1.26
* Capture - File Uploader
  * Nueva versión del widget: 1.0.2

### **Versión:** 2.4.1

* General
  * Mejoras en diseño
  * Nueva versión de Security: 1.1.3
* SelphID
  * Nueva versión del widget: 1.35.2
* Selphi
  * Nueva versión del widget: 5.19.5
* Tracking
  * Nueva versión del widget: 1.1.25
* Video ID
  * Nueva versión del Reader: 1.9.6
* NFC
  * Actualización de dependencias
  * Mejora de datos
* Capture - File Uploader
  * Nueva versión del widget: 1.0.1

### **Versión:** 2.4.0

* General
  * Mejoras en diseño
  * Nueva función para desactivar la seguridad
  * Nueva versión de Tokenizer: 1.0.8
  * Nueva versión de Security: 1.1.1
  * Nueva versión de Logger: 1.1.1
* SelphID
  * Nueva versión del widget: 1.35.0
  * Nueva personalización
* Selphi
  * Nueva versión del widget: 5.19.1
  * Nueva personalización
* Tracking
  * Nueva versión del widget: 1.1.22
* Video ID
  * Nueva versión del Reader: 1.9.5

### **Versión:** 2.3.6

* General
  * Mejoras en diseño
  * Ampliación de información en los errores
  * Nueva versión de Logger: 1.0.2
  * Nueva versión de Security: 1.0.6
* SelphID
  * Nueva versión del widget: 1.34.5
* Tracking
  * Nueva versión del widget: 1.1.16
* Selphi
  * Nueva versión del widget: 5.18.2
* Video recording
  * Borrado de output
  * Respuesta directa en las funciones start
  * Actualización de dependencias
* Video ID
  * Actualización de dependencias
* VideoCall
  * Actualización de dependencias
* NFC
  * Actualización de dependencias
* Phingers
  * Mejoras en el proceso
  * Actualización de dependencias

### **Versión:** 2.3.5 <a href="#id-235" id="id-235"></a>

* General
  * Nuevos códigos de error
* SelphID
  * Nueva versión del widget: 1.34.1
* Tracking
  * Nueva versión del widget: 1.1.12
* Video ID
  * Nueva versión del Reader: 1.8.0
  * Nueva versión del Helper: 3.27.0

### **Versión:** 2.3.4 <a href="#id-234" id="id-234"></a>

* General
  * Mejoras en Accesibilidad
  * Mejoras en pantallas horizontales
  * Refactorización de errores
* Video ID
  * Nueva versión del Reader: 1.7.1
* SelphID
  * Nueva versión del widget: 1.33.6
* Design KMP
  * Mejoras en los recursos de IOS
* NFC
  * Mejoras en la lectura

### **Versión:** 2.3.3 <a href="#id-233" id="id-233"></a>

* General
  * Mejoras en Accesibilidad
  * Mejoras en pantallas horizontales
  * Nueva versión del widget de seguridad: 1.0.1
* Video ID
  * Nuevos modos de lanzamiento
  * Nueva versión del reader: 1.7.0
  * Nueva versión del helper: 3.26.13
* SelphID
  * Nueva versión del widget: 1.33.4
* Selphi
  * Nueva versión del widget: 5.17.5
* Tracking
  * Nueva versión del widget: 1.1.10

### **Versión:** 2.3.2 <a href="#id-232" id="id-232"></a>

* General
  * Mejoras en Accesibilidad
  * Compatible con 16Kb
* Video ID
  * Validaciones de OCR de entrada y salida
* Selphi
  * Nueva versión del widget: 5.17.3
* SelphID
  * Nueva versión del widget: 1.33.1
* VideoCall
  * Nuevo desarrollo para compartir pantalla
* VideoRecording
  * Nuevo desarrollo para compartir pantalla

### **Versión:** 2.3.1 <a href="#id-231" id="id-231"></a>

* General
  * Mejoras en Accesibilidad
* Selphi
  * Nueva versión del widget: 5.17.2
  * Incluye Tokenizer
* Tracking
  * Nueva versión del widget: 1.1.9

### **Versión:** 2.3.0 <a href="#id-230" id="id-230"></a>

* General
  * Common Design librería interna
  * Proguard ajustes
  * Actualizado el target Api a 35
  * Android Gradle Plugin 8.9.1
  * Kotlin 2.1.10
  * Mejoras en Accesibilidad
* Tracking
  * Nueva versión del widget: 1.1.8
  * Compatible con IDV Platform (Necesaria una nueva licencia)
* Flow
  * Ajustes y mejoras
* VideoCall
  * Mejoras de UI
* Video ID
  * Verificación de cara presente
  * Lectura del OCR del documento presentado
  * Nuevos datos de salida

### **Versión:** 2.2.3 <a href="#id-223" id="id-223"></a>

* General
  * Separación completa entre la activación de pantalla de tip previo y la pantalla de tutorial.
  * Añadido sistema de seguimiento y análisis de eventos para interacción y navegación.
  * Nuevo lector de licencias.
* Voice
  * Actualización de dependencias internas
* Phingers
  * Actualización de dependencias internas
  * Nuevo filtro
* Video ID
  * Nuevo parámetro de entrada para la selección de cámara
  * Nuevo parámetro de entrada para activar/desactivar la captura automática de cara
  * Detección del proceso de video grabación activo antes de iniciar
* Video Call
  * Detección del proceso de video grabación activo antes de iniciar
  * VideoCallScreenSharingManager no necesita la aplicación.
  * Detección de fallos en la conexión a internet
* Video Recording
  * Detección de fallos en la conexión a internet
* SelphID
  * Nuevo parámetro de entrada para activar la vibración
  * Nueva versión del widget: 1.32.2
* Selphi
  * Nuevo parámetro de entrada para activar la vibración
  * Nuevos parámetros de entrada para los intentos de Liveness Move
  * Nueva versión del widget: 5.17.1
* License Checker
  * Nueva versión del widget: 0.4.0

### **Versión:** 2.2.2 <a href="#id-222" id="id-222"></a>

* SelphID
  * Nueva versión del widget: 1.31.2

### **Versión:** 2.2.1 <a href="#id-221" id="id-221"></a>

* General
  * Actualización de dependencias internas
* Selphi
  * Nuevo parámetro de entrada para la selección de cámara
  * Nueva versión del widget: 5.16.2
* Tracking
  * Nueva versión 1.1.7
* SelphID
  * Nueva versión del widget: 1.31.0

### **Versión:** 2.2.0 <a href="#id-220" id="id-220"></a>

* General
  * Mejoras en la gestión de excepciones
  * Actualización de dependencias internas
* Selphi
  * Nueva versión del widget: 5.16.1
  * Se añade parámetro para la duración de la extracción
  * Se añade la gestión de la orientación
* SelphID
  * Nueva versión del widget: 1.30.1

### **Versión:** 2.1.2 <a href="#id-212" id="id-212"></a>

* General
  * Mejoras UX
  * Mejoras en la accesibilidad
* SelphID
  * Nueva versión del widget: 1.29.0
* Selphi
  * Nueva versión del widget: 5.15.5
* Video Call
  * Mejoras en la connectividad
* Video Id
  * Mejoras en la connectividad
* Video Recording
  * Mejoras en la connectividad

### **Versión:** 2.1.1 <a href="#id-211" id="id-211"></a>

* General
  * Mejoras UX
* SelphID
  * Nueva versión del widget: 1.28.1
* Selphi
  * Nueva versión del widget: 5.14.2
* Tracking
  * Nueva versión del widget: 1.1.5
* Capture
  * Mejoras en la captura de documentos

### **Versión:** 2.1.0 <a href="#id-210" id="id-210"></a>

* General
  * Mejoras y correcciones internas
  * Mejoras de seguridad
  * Mejoras en la gestión de dependencias internas
* Flow
  * Mejoras y correcciones internas
* Tracking
  * Advanced Tracking
  * Mejoras y correcciones internas
* SelphID
  * Nueva versión 1.27.0
* Selphi
  * Nueva versión 5.14.1

### **Versión:** 2.0.3 <a href="#id-203" id="id-203"></a>

* General
  * Mejoras de accesibilidad
  * Mejoras en las corutinas de los controladores
  * UI para tablets
  * Creación de pantallas personalizables
* NFC
  * Correción del Security provider
  * Correción de fechas
  * Captura de excepciones
* Video Call
  * Añadir timeout
* Video ID
  * Control de error de red
  * Añadir timeouts
  * Detección de cara al iniciar
* SelphID
  * Nueva versión 1.26.0.
  * Añadir tutorial
* Selphi
  * Nueva versión 5.13.4
  * Nuevo campo cropImageDebug
* Tracking
  * Añadir tracking widget
* Capture
  * Nueva captura de documentos

### **Versión:** 2.0.2 <a href="#id-202" id="id-202"></a>

* General
  * Mejoras en los tutoriales
  * Mejoras en UX/UI
  * Kotlin Actualizado de 1.9.24 a 2.0.0 con K2 compiler
  * Android Gradle Plugin Actualizado de 8.3.2 a 8.5.0
  * Actualización de dependencias menores
  * Vistas horizontales para tablets
* SelphID
  * Nueva versión 1.25.1
* Tracking
  * Añadida conexión por APIKEY
  * Version 2 en los eventos
  * Ajustes de stepSucceed previo a los assets
  * Mejoras en la lógica de perdidas de conexión
* NFC
  * Mejoras y correcciones
  * Corregido "Tag lost error"
  * Mejoras en la reconexión
  * Ahora se puede escoger si se quiere extraer la imagen de la cara y la firma
  * Se añade un parámetro para cambiar la vista de tutorial y que muestre los diferentes documentos
* VideoRecording
  * Ajustes y mejoras en la parada del Servicio
* VideoCall
  * Ajustes y mejoras en la parada del Servicio
* Selphi
  * Nueva versión 5.13.1
  * Se añade a la salida el parámetro livenessDiagnostic

### **Versión:** 2.0.1 <a href="#id-201" id="id-201"></a>

* General
  * SdkConfigurationData corrección de texto "iaModels" a "aiModels"
  * Mejoras internas de PreviousTips
  * Dependencias importantes actualizadas:
    * composeCompilerVersion = 1.5.12
    * androidGradlePlugin = 8.3.2
    * kotlinAndroidGradlePlugin = 1.9.23
* Selphi
  * Nueva versión 5.12.3
  * Se añade a la respuesta bestImageTokenized
* SelphID
  * Nueva versión 1.24.2
* VideoCall
  * Imagen de Timeout actualizada
* Phingers
  * Simplificado ConfigurationData
* Tokenizer
  * Nueva versión de core 2.0.7

### **Versión:** 2.0.0 <a href="#id-200" id="id-200"></a>

* General
  * Todas las funciones de SDKController, pasan de tener output con lambda, a ser suspend functions y devolver el resultado de manera sincrona. Para consumirlo ahora será necesario usar una Coroutine. Si se llama desde un ViewModel, se puede usar viewModelScore.launch, si no CoroutineScope(Dispatchers.IO).launch
  * La inicialización del SDK ahora tiene un SDKConfigurationData con los datos que se han de rellenar
  * En el SDKConfigurationData podrás elegir entre LicensingOnline o LicensingOffline
  * Todos los ConfigurationData con imágenes en su interior han sido modificados para cambiar el nombre de los parámetros (Image)
* Tracking
  * Ajustes y mejoras
* Voice
  * Librería del widget actualizada a la versión 3.13.0
  * Mejorado el UX/UI
  * Mejorados los resultados de las verificaciones

### **Versión:** 1.5.6 <a href="#id-156" id="id-156"></a>

* Selphi
  * Nueva versión 5.12.3

### **Versión:** 1.5.5 <a href="#id-155" id="id-155"></a>

* General
  * Ajustes y mejoras de seguridad
  * Selphi and Selphid mejora de la gestión interna de imágenes
* NFC
  * Corrección del campo Personal Number

### **Versión:** 1.5.4 <a href="#id-154" id="id-154"></a>

* General
  * Ajustes y mejoras de seguridad
  * Ajustes de diseño en las vistas de tutorial con fullscreen
* Selphi
  * Nueva versión 5.12.1
* SelphID
  * Nueva versión 1.23.1

### **Versión:** 1.5.3 <a href="#id-153" id="id-153"></a>

* General
  * Pantallas de diagnóstico con reintentar
  * Flow
    * Nuevas funcionalidades
    * Tema dinámico
    * Preview controller
    * Servicios de cliente y preview
    * Mejoras
* Selphi
  * Nueva versión 5.12.0
  * Tutoriales
  * Envío de bestImage completa a tracking
* SelphID
  * Nueva versión 1.22.3
* Phingers
  * Se ha añadido retroalimentación háptica con vibración
  * Mejoras en tutorial
* NFC
  * Mejoras
* VideoId
  * Mejoras en la conexión
  * Ajustes UX
* VideoCall
  * ScreenSharing
  * Nuevos estados
  * Mejoras en la conexión
* VideoRecording
  * Nuevos estados
  * Mejoras en la conexión
  * Incidencia conocida: API 34 Android
* Capture QR
  * QR formatos

### **Versión:** 1.5.2 <a href="#id-152" id="id-152"></a>

* General
  * Mejoras en pantallas pequeñas
  * Nuevo SelphiSignController
  * Nuevo VideoIdSignController
  * Nuevas clases SDKImage y SDKApplication
* NFC
  * Mejoras
* SelphID
  * 1.21.1
* Selphi
  * 5.11.2
* Voz
  * Mejora del tamaño de la librería

### **Versión:** 1.5.1 <a href="#id-151" id="id-151"></a>

* General
  * Mejoras y corrección de errores
* Voz
  * Actualización de la librería interna
  * Ajustes de calibración
  * Devolución de audios tokenizados
* Phingers
  * Seguimiento WSQ
* Comportamiento
  * Actualización de la librería interna
  * Mejoras y correcciones

### **Versión:** 1.5.0 <a href="#id-150" id="id-150"></a>

* Compatible con API 34 (Android 14)
* Actualizados los plugins Gradle de Android (8.1.1)
* Versión actualizada de Kotlin utilizada (1.9.10)
* Ajustes de datos de entrada del componente de vídeo
* Mejorado SdkResult como clase sellada
* Nomenclatura de los pasos de entrada NewOperation

#### Versión


# iOS SDK

Esta sección reúne todo lo necesario para implementar los flujos biométricos en aplicaciones iOS de forma consistente y segura.

### Qué puedes hacer con este SDK

* Instalar e inicializar el SDK en tu proyecto iOS.
* Ejecutar flujos biométricos como **IDV Mobile** y **lanzamiento simplificado**.
* Configurar componentes y módulos del SDK.
* Personalizar la experiencia (UI, textos y comportamientos).
* Consultar ejemplos prácticos en **Swift**.
* Revisar el historial de versiones y mejoras.

***

### Índice de contenidos

* [**Requisitos mínimos**](/sdks/sdk-mobile/ios-sdk/requisitos-minimos)\
  Requisitos mínimos necesarios para integrar el SDK.
* [**Instalación**](/sdks/sdk-mobile/ios-sdk/instalacion)\
  Integra el SDK mediante CocoaPods o Swift Package Manager
* [**Inicialización**](/sdks/sdk-mobile/ios-sdk/inicializacion)\
  Inicialización y uso del SDK
  * [**Integración IDV Mobile**](/sdks/sdk-mobile/ios-sdk/inicializacion/integracion-idv-mobile)\
    Implementa flujos de verificación de identidad.
  * [**Lanzamiento simplificado**](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado)\
    Ejecuta procesos biométricos con configuración mínima.
* [**Componentes y Módulos**](/sdks/sdk-mobile/ios-sdk/modulos)\
  Configura y combina los módulos disponibles del SDK.
* [**Manejo de errores genéricos**<br>](/sdks/sdk-mobile/ios-sdk/manejo-de-errores-genericos)Detalle de los distintos errores que puede retornar el SDK.
* [**Personalización del SDK**](/sdks/sdk-mobile/ios-sdk/personalizacion)\
  Ajusta la interfaz, los textos y el comportamiento.
* [**Aplicaciones de Ejemplo**](/sdks/sdk-mobile/ios-sdk/aplicaciones-de-ejemplo)\
  Ejemplos funcionales listos para ejecutar.
* [**Ajustes avanzados**](/sdks/sdk-mobile/ios-sdk/ajustes-avanzados)\
  Configuraciones adicionales y casos especiales.
* [**Changelog**](/sdks/sdk-mobile/ios-sdk/changelog)\
  Cambios, mejoras y correcciones por versión.


# Requisitos mínimos

Antes de integrar el SDK Mobile de Facephi, asegúrate de cumplir los siguientes requisitos:

* Dispositivo con iOS 9 o superior. **Es importante tener en cuenta que algunos módulos/componentes tienen versiones mínimas superiores.**
* Permisos requeridos. Algunos de los componentes necesitan permisos de acceso a:
  * Cámara
  * Micrófono
  * Compartir Pantalla
  * Lector NFC
* Xcode actualizado.
* MacOS
  * Incluye soporte para chips *Intel* y *Apple M*.

## Incidencias conocidas (Mac con chip M1)

Si usas un Mac con chip M1 y quieres la distribución por Cocoapods en lugar de SPM:

* Evita instalar CocoaPods mediante **Homebrew**.
* Instala **cocoapods** y **cocoapods-art** usando `gem`.

A continuación se incluye un script que prepara el entorno automáticamente:

```sh
#! /bin/zsh

install_cocoapods () {
    echo "Installing cocoapods with gem"
    # Creating new gems home if it doesnt't exist
    if [ ! -d "$HOME/.gem" ]; then
        mkdir "$HOME/.gem"
    fi
    # Adding to current session
    export GEM_HOME="$HOME/.gem"
    export PATH="$GEM_HOME/bin:$PATH"

    # Adding for future sessions
    if test -f "$HOME/.zshrc"; then
        echo 'Adding $GEM_HOME env var and then adding it to your $PATH'
        echo '' >> "$HOME/.zshrc"
        echo 'export GEM_HOME="$HOME/.gem"' >> "$HOME/.zshrc"
        echo 'export PATH="$GEM_HOME/bin:$PATH"' >> "$HOME/.zshrc"
        echo 'alias pod='arch -x86_64 pod'' >> "$HOME/.zshrc"
    fi

    # Installing cocoapods
    gem install cocoapods
    sudo arch -x86_64 gem install ffi
    which pod
    pod --version
    gem install cocoapods-art
}

uninstall_cocoapods_homebrew () {
    which -s brew
    if [[ $? != 0 ]] ; then
        echo "Homebrew not installed, skipping uninstalling cocoapods from homebrew"
    else
        brew uninstall cocoapods
    fi
}

if ! type "pod" > /dev/null; then
    echo "You don't have cocoapods installed..."
else
    echo "Trying to uninstall it from homebrew first"
    uninstall_cocoapods_homebrew
fi

install_cocoapods
```

***


# Instalación

Integra el SDK Mobile de Facephi en tus aplicaciones iOS para ejecutar procesos de verificación biométrica de forma rápida y segura.

## Qué incluye el SDK

El SDK Mobile está formado por un conjunto de **librerías modulares (componentes)** que permiten construir una solución biométrica adaptada a cada cliente.

***

## Distribución de las dependencias

#### Configurar credenciales (`netrc`)

Los binarios del SDK (tanto en **CocoaPods** como en **SPM**) se distribuyen desde **Artifactory**. Aunque los paquetes SPM se resuelven desde repositorios en GitHub, Xcode descarga el binario empaquetado como **ZIP** desde Artifactory; por ello, es **obligatorio** disponer de credenciales válidas en el archivo `netrc` de tu máquina, **también si integras solo por SPM**.

Solicita usuario y token al **equipo de soporte de Facephi**. El usuario debe tener permisos sobre los repositorios **`cocoa-pro-fphi`** y **`spm-pro-fphi`**.

Añade las credenciales a tu archivo `netrc` ejecutando desde Terminal:

```sh
$ nano ~/.netrc
```

Incluye al final del archivo el siguiente bloque (respeta el indentado con **dos espacios**):

```sh
machine facephicorp.jfrog.io
  login <USERNAME>
  password <TOKEN>
```

### Cocoapods

Las librerías (componentes) del SDK iOS se distribuyen por cocoapods mediante el uso de un repositorio privado de Artifactory.

#### 1. Preparar el entorno

Para acceder al repositorio privado de Facephi es necesario tener **CocoaPods** instalado en la máquina.

Los componentes del SDK Mobile se distribuyen desde un repositorio privado que requiere credenciales, las cuales debes solicitar al **equipo de soporte de Facephi**.

#### 2. Configurar acceso al repositorio privado

**Instala el plugin de Artifactory**

```sh
sudo gem install cocoapods-art
```

> ⚠️ En equipos con **chip M1**, pueden producirse errores durante la instalación. Si ocurre, utiliza el siguiente comando. Si no, revisa la sección de incidencias al final de esta página.
>
> `sudo arch -arm64 gem install ffi; sudo arch -arm64 gem install cocoapods-art`

Finalmente añade el repositorio que contiene dependencias privadas:

```sh
pod repo-art add cocoa-pro-fphi 
"https://facephicorp.jfrog.io/artifactory/api/pods/cocoa-pro-fphi"
```

> En caso de tener problemas con la instalación, desinstala completamente cocoapods y todas sus dependencias para hacer una instalación limpia.

#### 4. Añadir repositorio y dependencias

En tu `Podfile`, añade las siguientes configuraciones:

```sh
plugin 'cocoapods-art', :sources => [
  'cocoa-pro-fphi’
]

source 'https://cdn.cocoapods.org/'

target 'Example' do
  pod 'FPHISDKMainComponent', '~> $VERSION'

   post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
      config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
      config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
    end
  end
end
...
end

```

#### 5. Actualizar dependencias

Antes de ejecutar `pod install`, actualiza el repositorio local:

```sh
pod repo-art update cocoa-pro-fphi
```

También se puede hacer una *actualización limpia* borrando previamente el repositorio para asegurarnos de que no hay problemas de caché. Para ello, ejecutamos:

```
pod repo-art remove cocoa-pro-fphi;
rm -rf $HOME/.cocoapods/repos/cocoa-pro-fphi; // $HOME usually refers to /Users/{username}
rm -rf $HOME/.cocoapods/repos-art/cocoa-pro-fphi;
```

Y finalmente añadimos de nuevo el repositorio privado:

```sh
pod repo-art add cocoa-pro-fphi 
"https://facephicorp.jfrog.io/artifactory/api/pods/cocoa-pro-fphi"
```

### SPM

Las librerías (componentes) del SDK iOS se distribuyen por **Swift Package Manager (SPM)** mediante repositorios en GitHub. Cada paquete referencia un **binario precompilado** empaquetado en **ZIP** y hosteado en **Artifactory**; Xcode lo descarga durante la resolución de dependencias.

Por eso, **independientemente de si uses HTTPS o SSH** para resolver los paquetes en GitHub, **debes tener configurado el archivo `.netrc`** con credenciales de Artifactory (véase [Configurar credenciales (`netrc`)](#configurar-credenciales-netrc)) antes de resolver dependencias en Xcode.

{% hint style="info" %}
Sin credenciales válidas en `.netrc`, la resolución de paquetes SPM puede fallar aunque el acceso a GitHub esté correctamente configurado.
{% endhint %}

#### 1. Preparar el entorno

Los repositorios de paquetes SPM deben importarse al proyecto en el apartado *Package Dependencies* de Xcode.

Los repositorios del SDK son **públicos en GitHub** y pueden añadirse con **HTTPS** o **SSH**. **Por defecto, usa HTTPS**: no requiere configuración adicional de claves SSH ni vincular una cuenta de GitHub en Xcode.

**Protocolo de acceso: HTTPS (recomendado por defecto) vs SSH (opcional)**

* **HTTPS** — Método por defecto. No requiere configuración extra. Válido para los repositorios públicos del SDK.

```
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
```

* **SSH** — **Opcional.** Puede ser preferible en entornos corporativos que ya usen claves SSH con GitHub. Requiere tener SSH configurado en tu cuenta (véase el apartado 2).

```
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

{% hint style="info" %}
El repositorio *público* indica su visibilidad en GitHub, no el protocolo de descarga. Puedes integrar el SDK por SPM usando **solo HTTPS** sin completar el apartado de SSH.
{% endhint %}

#### 2. (Opcional) Configurar conexión de GitHub a Xcode con SSH <a href="#spm-ssh-opcional" id="spm-ssh-opcional"></a>

**Solo necesario si vas a añadir los paquetes SPM con URLs SSH** en lugar de HTTPS. Si usas HTTPS (recomendado por defecto), puedes omitir este apartado.

Si optas por SSH, conecta Xcode con GitHub mediante una clave de cifrado SSH de tipo Ed25519.

**Generar clave SSH**

Este paso es opcional y solo hay que hacerlo si NO tienes ya una clave creada.

Seguimos los pasos 1 a 3 de [Generating a new SSH key and adding it to the ssh-agent - GitHub Docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key).

**Añadir clave SSH al directorio de claves del equipo**

Seguimos los pasos 1 a 4 de [Generating a new SSH key and adding it to the ssh-agent - GitHub Docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent).

**Añadir clave SSH a la cuenta de GitHub**

Seguimos los pasos 1 a 9 de [Adding a new SSH key to your GitHub account - GitHub Docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account#adding-a-new-ssh-key-to-your-account).

**Crear Token Personal**

1. Accedemos a [Configuración de GitHub → Developer Settings → Personal Access Tokens](https://github.com/settings/tokens/new).
2. Determinamos el tiempo de expiración y los permisos que queremos dar al nuevo token. Este apartado es muy importante ya que dependiendo del uso que le vayamos a dar a nuestros repositorios con XCode necesitaremos más o menos permisos. **Es importante dar permisos estrictamente para lo que necesitamos**.
3. Copiamos el token generado y lo guardamos de forma segura en una herramienta de tipo *vault* como Keeper.

**Conectar XCode**

1. Abrimos XCode → Settings → Source Control
2. Añadimos una cuenta de GitHub
3. En las credenciales introducimos el nombre de nuestra cuenta y el token que acabamos de generar.
4. Aceptamos y al volver a la vista de la configuración de XCode pulsamos en la ![Info](https://facephicorporative.atlassian.net/gateway/api/emoji/327ed40d-1088-4122-8df3-ab0b3c942ddb/atlassian-info/path?scale=MDPI) sobre nuestra nueva cuenta vinculada.
5. Si vas a usar URLs **SSH**, asegúrate de que aparezca seleccionado SSH y la referencia a la clave configurada en los pasos anteriores. Si usas **HTTPS**, este paso no aplica.

#### 3. Cómo añadir un SPM <a href="#como-anadir-un-spm-a-tu-proyecto" id="como-anadir-un-spm-a-tu-proyecto"></a>

Los SPMs se añaden a nivel de proyecto, no a nivel de target como sí ocurre en Cocoapods.

Para hacerlo vamos a la raíz de nuestra aplicación → Project → Package Dependencies → +

<figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-0e6704d0f5d09ec245e5bcedcfb84fc51229dafb%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

Luego copia la **URL HTTPS** del repositorio remoto (método por defecto):

```
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
```

Si prefieres SSH y completaste el apartado 2, usa la URL SSH equivalente (`git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git`).

<figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-b69bfe862f6aab5f750c63030ebeff6639d29188%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="https://media-cdn.atlassian.com/file/86700223-4823-4698-8e83-ef48334812d1/image/cdn?allowAnimated=true&#x26;client=2496a37b-bf8c-4ee3-a347-9deae0e25c51&#x26;collection=contentId-3812360243&#x26;height=125&#x26;max-age=2592000&#x26;mode=full-fit&#x26;source=mediaCard&#x26;token=eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIyNDk2YTM3Yi1iZjhjLTRlZTMtYTM0Ny05ZGVhZTBlMjVjNTEiLCJhY2Nlc3MiOnsidXJuOmZpbGVzdG9yZTpjb2xsZWN0aW9uOmNvbnRlbnRJZC0zODEyMzYwMjQzIjpbInJlYWQiXX0sImV4cCI6MTc3MjcxMTA4NywibmJmIjoxNzcyNzA4MjA3LCJhYUlkIjoiNjA0N2E4N2Y1MTQ3MWMwMDZhYjJhZjI2IiwiaHR0cHM6Ly9pZC5hdGxhc3NpYW4uY29tL2FwcEFjY3JlZGl0ZWQiOmZhbHNlfQ.YsCtEHq02P38kdq_2HpB2BQ-9d9-GXXiE2TSoNYk9hk&#x26;width=760" alt=""><figcaption></figcaption></figure>

***

El SPM contiene y expone *targets.* Estos targets son librerías que debemos importar en un target de nuestro proyecto para poder usarlos. Para hacerlo, vamos al target que queramos que tenga esta dependencia y añadimos el módulo SPM deseado:

<figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-1fdcfaeff69f35e5ff77018a9171116312f668f6%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-1d3cc4450701b444dbadb4dd1548b81d1578c5f6%2Fimage.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

#### 4. Troubleshooting SPM <a href="#troubleshooting" id="troubleshooting"></a>

**Puntos clave al configurar en Xcode**

* **Dependency Rule:** al agregar cada paquete, configura la regla como **Up to Next Minor Version** (no *Up to Next Major Version*). Usar *Major* puede traer versiones con cambios incompatibles.
* **Frameworks, Libraries, and Embedded Content:** verifica que el target de tu app tenga todos los módulos SPM añadidos. Si alguno falta, los `import` fallarán aunque SPM haya descargado los paquetes correctamente.

**Error 403 al descargar binarios desde Artifactory (credenciales o permisos)**

Si las credenciales de `.netrc` no están configuradas, son incorrectas o el usuario no tiene permisos sobre el repositorio **`spm-pro-fphi`**, la resolución de paquetes SPM falla con un error similar a:

```
failed downloading 'https://facephicorp.jfrog.io/artifactory/spm-pro-fphi/SDK/FPHISDKCoreComponent/2.8.1/core.zip' which is required by binary target 'core': badResponseStatusCode(403)
```

Comprueba lo siguiente:

* El bloque `machine facephicorp.jfrog.io` en `~/.netrc` está bien formado (indentado con **dos espacios**) y el **usuario** y **token** son válidos.
* Tu usuario de Artifactory tiene permisos de lectura sobre **`spm-pro-fphi`** (y **`cocoa-pro-fphi`** si también usas CocoaPods). Si no los tienes, solicítalos al **equipo de soporte de Facephi**.
* Tras corregir las credenciales, limpia la caché de SPM y vuelve a resolver dependencias (véase *Problemas de caché* más abajo).

**Problemas de caché (SPM no resuelve dependencias o el proyecto no compila)**

Durante la integración, lo más frecuente son problemas de caché. Sigue estos pasos **en orden**:

1. Cierra el proyecto en Xcode.
2. Limpia la caché desde Terminal. Ejecuta el siguiente comando **en una sola línea**:

```sh
rm -rf ~/Library/Developer/Xcode/DerivedData && rm -rf ~/Library/org.swift.swiftpm && rm -rf ~/Library/Caches/org.swift.swiftpm
```

{% hint style="warning" %}
Los tres comandos deben ejecutarse en la misma línea, unidos por `&&`. Si los separas en varias líneas, la terminal puede no aplicar la limpieza completa.
{% endhint %}

3. Elimina el archivo **`Package.resolved`**. Este archivo guarda los SHA de commit que SPM usa para descargar cada paquete; si está desactualizado, SPM puede no resolver las dependencias. Puedes encontrarlo en:

   * Clic derecho sobre el `.xcworkspace` (o `.xcodeproj`) → *Mostrar contenido del paquete* → `xcshareddata` → `swiftpm` → `Package.resolved`.
   * Clic derecho sobre el `.xcworkspace` (o `.xcodeproj`) → clic derecho sobre el `.xcworkspace` interno → *Mostrar contenido del paquete* → `xcshareddata` → `swiftpm` → `Package.resolved`.

   Elimínalo y deja que Xcode lo regenere al volver a abrir el proyecto.
4. Abre el proyecto y, en Xcode, ejecuta *File → Packages → Reset Package Caches*.

**Los imports no resuelven aunque SPM descargó los paquetes**

Revisa que el **target** de tu app tenga todas las librerías añadidas en *Frameworks, Libraries, and Embedded Content*. Es un paso que suele pasarse por alto al migrar desde CocoaPods o al trabajar con workspaces.

**Los SPMs no se descargan y no puedo ver el error**

Cuando esto ocurre, XCode a veces no nos dice el error. Para verlo, vamos a la terminal y ejecutamos:

`$ xcodebuild -resolvePackageDependencies`

Con ese comando sí que podremos ver el error concreto para darle solución.

**Error por clave RSA (solo si usas SSH)**

Si añades paquetes con URLs **SSH**, puede aparecer un error similar a:

```
git@github.com:facephi/whatever_library.git: An unknown error occurred. ERROR: You're using an RSA key with SHA-1, which is no longer allowed.
```

Ocurre por el uso de una clave SSH con cifrado RSA, que GitHub ya no admite. La solución pasa por configurar SSH con una clave más segura (se recomienda Ed25519), siguiendo el [apartado 2 opcional de SSH](#spm-ssh-opcional). Consulta también [Improving Git protocol security on GitHub](https://github.blog/2021-09-01-improving-git-protocol-security-github/).

***

## Soporte

Si tienes dudas o problemas durante la instalación, contacta con el **Soporte Técnico de Facephi**.


# Inicialización

El SDK puede ser utilizado para capturas biométricas:

* [Orquestadas](/sdks/sdk-mobile/ios-sdk/inicializacion/integracion-idv-mobile): Mediante el uso de IDV Suite y la configuración de flujos y comportamientos en un backoffice.
* [Invididuales](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado): Mediante el uso y gestión de los componentes desde una aplicación móvil.


# Integración IDV Mobile

## Qué es IDV Mobile

**IDV (Identity Verification)** es el flujo que permite verificar y autenticar la identidad de una persona mediante la captura y validación de **rasgos biométricos**.

El flujo se configura previamente en la **plataforma de Facephi** y se ejecuta en la aplicación mediante su identificador (`flowId`).

## Dependencias necesarias

A continuación se detalla el listado de dependencias de los componentes disponibles para integrar un flujo de IDV en iOS. Instala únicamente los componentes de captura que se hayan licenciado.

### Cocoapods

```sh
// CORE
pod 'FPHISDKMainComponent', '~> $VERSION'
pod 'FPHISDKTrackingComponent', '~> $VERSION'
// COMPONENTES DE CAPTURA
pod 'FPHISDKSelphIDComponent', '~> $VERSION'
pod 'FPHISDKSelphiComponent', '~> $VERSION'
pod 'FPHISDKNFCComponent', '~> $VERSION'
pod 'FPHISDKCaptureComponent', '~> $VERSION'
pod 'FPHISDKVideoRecordingComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

```sh
// CORE
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
git@github.com:facephi-clienters/SDK-TrackingPackage-SPM.git
// COMPONENTES DE CAPTURA
git@github.com:facephi-clienters/SDK-SelphidMBSDRComponent-SPM.git
git@github.com:facephi-clienters/SDK-Selphi_component-SPM.git
git@github.com:facephi-clienters/SDK-NFC_component-SPM.git
git@github.com:facephi-clienters/SDK-VideoRecording-SPM.git
git@github.com:facephi-clienters/SDK-CapturePackage-SPM.git
```

## Dependencias opcionales

El SDK cuenta con varias librerías que agregan funcionalidad.

* Status -> Permite que el SDK muestre pantallas de tutorial y diagnóstico para cada componente, mejorando la experiencia de usuario.
* Tokenize -> Algunos servicios requieren el envío de los assets tokenizados. Esta librería añade los valores tokenizados a la respuesta del componente.

### Cocoapods

```sh
pod 'FPHISDKStatusComponent', '~> $VERSION'
pod 'FPHISDKTokenizeComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

```sh
git@github.com:facephi-clienters/SDK-StatusPackage-SPM.git
git@github.com:facephi-clienters/SDK-TokenizePackage-SPM.git
```

## Inicializar el SDK

El SDK funciona a través de un **controlador principal (`SDKController`)**, que debe inicializarse correctamente antes de poder lanzar cualquier flujo.

Facephi proporcionará el `apiKey` de la licencia necesario para la inicialización.

Tras una inicialización correcta, la aplicación tendrá acceso a **todos los flujos configurados para ese proyecto**.

```swift
SDKController.shared.initSdk(
        licensingUrl: SdkConfigurationManager.LICENSING_URL,
        apiKey: SdkConfigurationManager.APIKEY_LICENSING_IDV,
        output: { sdkResult in
            if sdkResult.finishStatus == .STATUS_OK {
                self.log("Licencia automática seteada correctamente")
            } else {
                self.log("Ha ocurrido un error al intentar obtener la licencia: \(sdkResult.errorType)")
            }
        },
        trackingController: trackingController,
        tokenizeController: tokenizeController,
        statusController: statusController,
        analyticsOutput: { time, component, type, info  in
            self.log("Analytics: \(Date()) \(component) - \(type) - \(info)")
        })
```

## Lanzar un flujo de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El flujo de IDV se lanza mediante un `FlowController`, indicando:

* El **ID del flujo** configurado en plataforma (`flowId`).
* El **ID del cliente** (`customerId`).
* El **ID de autenticación** (`authenticationId`). Solo necesario si estamos ante un flujo de autenticación.
* La lista de **controladores** que pueden participar en el proceso.

Ejemplos de controladores habituales:

* `SelphiController` → Captura facial.
* `SelphIDController` → Captura de documentos.
* `StartVideoRecordingController` / `StopVideoRecordingController` → Grabación del proceso.

```swift
public func launchFlow(viewController: UIViewController, output: @escaping (SdkFlowResult) -> Void) {
        let selphidController = SelphIDController(data: nil, output: {
            print("SelphidController output: \($0.errorType)")
        }, viewController: viewController)
        
        let selphiController = SelphiController(data: nil, output: {
            print("SelphiController output: \($0.errorType)")
        }, viewController: viewController)
        
        let startVideoRecordingController = VideoRecordingController(viewController: viewController, output: {
            print("videoRecordingController output: \($0.errorType)")
        })
        
        let stopVideoRecordingController = StopVideoRecordingController(videoRecordingController: startVideoRecordingController, output: {
            print("stopVideoRecordingController output: \($0.errorType)")
        })
        
        let controllers: [IFlowableController] =
        [selphidController, selphiController, startVideoRecordingController, stopVideoRecordingController]
        
        let flowConfigurationData = FlowConfigurationData(
            id: 340260c3-0428-41d7-91c7-13c2a122cfc3,
            controllers: controllers,
            customerId: SdkConfigurationManager.customerId,
            authenticationId: authenticationId) // Parámetro opcional
        
        let flowController = SdkConfigurationManager.offlineFlow ? FlowOfflineController(flowConfigurationData: flowConfigurationData, output: output): FlowController(flowConfigurationData: flowConfigurationData, output: output)
        self.flowController = flowController
        SDKController.shared.launch(controller: flowController)
}
```

## Consultar flujos disponibles

Si necesitas obtener los flujos disponibles antes de lanzar uno de ellos, utiliza:

```kotlin
SDKController.shared.getFlowIds()
```

La función devuelve un listado con el **identificador del flujo** y su **tipo de operación**.


# Lanzamiento simplificado

Esta sección muestra ejemplos (en Swift) prácticos para integrar y utilizar el SDK de Facephi en aplicaciones móviles iOS, adaptados a los flujos de verificación más comunes.

## Inicializar el SDK

El SDK funciona a través de un **controlador principal (`SDKController`)**. Facephi proporcionará el `apiKey` de la licencia necesario para la inicialización.

```swift
 import core
 import sdk
 import trackingComponent
 
 ...
 
 let trackingController = TrackingController(
     trackingError: { trackingError in
         self.log("TRACKING ERROR: \(trackingError)")
     },
     enableLocation: false)

SDKController.shared.initSdk(licensingUrl: SdkConfigurationManager.LICENSING_URL, apiKey: SdkConfigurationManager.APIKEY_LICENSING, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licencia automática seteada correctamente")
    } else {
        self.log("Ha ocurrido un error al intentar obtener la licencia: \(sdkResult.errorType)")
    }
}, trackingController: trackingController)

```

## Iniciar operación

Antes de lanzar cualquier componente, es obligatorio **iniciar una operación**.

Este método tiene 3 parámetros de entrada:

* **operationType**: Indica si se va a hacer un proceso de ONBOARDING o de AUTHENTICATION.
* **customerId**: Identificador del usuario (controlado a nivel de aplicación).
* **steps**: Lista de pasos de la operación si se han definido previamente:

**- Pasos definidos**:

{% code overflow="wrap" %}

```swift
SDKController.shared.newOperation(operationType: OperationType.X, customerId: "customerId", steps: [.SELPHI, .SELPHID, .OTHER("CUSTOM_STEP")], output: { _ in })
```

{% endcode %}

**- Pasos no definidos:**

{% code overflow="wrap" %}

```swift
SDKController.shared.newOperation(operationType: OperationType.X, customerId: "customerId", output: { _ in})
```

{% endcode %}

## Lanzamiento de componentes

Cada componente tiene su propio controlador y se lanza desde `SDKController`.

{% code overflow="wrap" %}

```swift
public func launchExample(setTracking: Bool = true,viewController: UIViewController,componentConfigurationData: ComponentConfigurationData)
{
    let output: (SdkResult<ExampleResult>) -> Void = { exampleResult in
        print("exampleResult: \(exampleResult.finishStatus)")
    }
        
    let controller = ExampleController(data: exampleConfigurationData, output: output, viewController: viewController)
        
    if setTracking {
        SDKController.shared.launch(controller: controller)
    } else {
        SDKController.shared.launchMethod(controller: controller)
    }
}
```

{% endcode %}


# Componentes


# Conexión con plataforma

Este componente necesita una versión mínima de iOS13

El envío de eventos a la plataforma se realiza con el ***Tracking Component*****.**

Éste se encarga de realizar el trackeo y la monitorización de la información obtenida durante la ejecución de las operaciones. Se podrá realizar el seguimiento en tiempo real de estos datos en la **Plataforma**, mientras se está ejecutando el proceso en el dispositivo del cliente.

Al contrario que ocurre con el resto, este componente no funciona individualmente, trabaja de forma transversal al resto de componentes instalados en la *SDKMobile*.

## Dependencias

### Cocoapods

Las librerías de Facephi se distribuyen de forma remota mediante gestores de dependencias. En iOS, se utiliza **CocoaPods**. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
  pod 'FPHISDKMainComponent', '~> $VERSION'
```

Para instalar el componente **Tracking**, añade la dependencia correspondiente en el `Podfile` del proyecto, junto con las dependencias obligatorias del SDK.

```swift
  pod 'FPHISDKTrackingComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

Si utilizas **SPM**, asegúrate de que las dependencias obligatorias del SDK estén previamente instaladas.

```sh
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

Para instalar el componente **Selphi**, inclúyelo en los módulos del proyecto.

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-TrackingPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-TrackingPackage-SPM.git
```

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist** cuando el tracking vaya a enviar localización:

```
Es necesario permitir el acceso a la localización (NSLocationUsageDescription - Privacy - Location Usage Description)
```

{% hint style="info" %}
El permiso de localización solo es necesario si **no** configuras **`enableLocation: false`** en el inicializador de **`TrackingController`**. Por defecto **`enableLocation`** es **`true`** y el componente puede solicitar y enviar localización en los eventos hacia la plataforma.
{% endhint %}

## Integración

Para referenciar la dependencia desde nuestro código Swift:

```swift
import trackingComponent
```

## Inyección en el SDK <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

```swift
SDKController.shared.initSdk(licensingUrl: SdkConfigurationManager.LICENSING_URL, apiKey: SdkConfigurationManager.APIKEY_LICENSING, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licencia automática seteada correctamente")
    } else {
        self.log("Ha ocurrido un error al intentar obtener la licencia: \(sdkResult.errorType)")
    }
}, trackingController: trackingController)
```

## Inicialización del TrackingController

Crea la instancia de **`TrackingController`** antes de llamar a **`SDKController.shared.initSdk`**, pasándola en el parámetro `trackingController`.

```swift
let trackingController = TrackingController(
    trackingError: { trackingError in
        print("TRACKING ERROR: \(trackingError)")
    },
    enableLocation: false,
    debug: debugFlag)
```

### **enableLocation**

Controla si el componente **Tracking** solicita y envía **localización** en los eventos hacia la plataforma. Por defecto a `true`.

## Recepción de errores

Los errores del controlador de tracking no son terminales. Al contrario que con el resto del SDK, se informan a través del callback inyectado en su inicialización (`trackingError` en el inicializador anterior).

El parámetro *trackingError* es un String que puede obtener los siguientes valores:

* **APPLICATION\_CONTEXT\_ERROR:** Error en la inicialización del contexto
* **ASSET\_LINK**: Error al enviar el enlace del recurso
* **ASSET\_UPLOAD**: Error durante la carga del recurso
* **COMPONENT\_LICENSE\_ERROR**: Licencia del componente ausente o no válida
* **CUSTOMER\_ID**: Error al obtener o validar el ID del cliente
* **DEVICE\_EVENT\_ERROR**: Fallo durante un evento relacionado con el dispositivo
* **EMPTY\_LICENSE**: Datos de licencia vacíos o inexistentes
* **FLOW**: Error durante el flujo de ejecución
* **INITIALIZATION\_ERROR**: Fallo general en la inicialización
* **INIT\_IDS\_ERROR**: Error al generar o asignar IDs durante la inicialización
* **INIT\_OPERATION**: Operación fallida en la fase de inicialización
* **LICENSE\_ERROR**: Licencia inválida o corrupta
* **MANAGER\_NOT\_INITIALIZED**: Se intentó usar el gestor sin inicializarlo
* **NETWORK\_CONNECTION**: Problema con la conexión de red
* **NETWORK\_ERROR**: Falla genérica de red
* **NO\_OPERATION\_CREATED\_ERROR**: No se creó ninguna operación cuando se esperaba
* **OCR\_DATA**: Error al procesar los datos de OCR
* **OPERATION\_NOT\_CREATED**: No se generó la operación esperada
* **OPERATION\_ID**: ID de operación inválido o ausente
* **SESSION\_ID**: Error con la identificación de sesión
* **SIGNATURE\_RESULT**: Fallo en el proceso o resultado de firma
* **STEP\_CHANGE**: Transición de paso inesperada o inválida
* **STEP\_RESULT\_CANCELLED**: El paso fue cancelado de forma inesperada
* **STEP\_RESULT\_ERROR**: El paso finalizó con un error
* **STEP\_RESULT\_EXPIRED**: El resultado del paso expiró antes de completarse
* **STEP\_RESULT\_SUCCEEDED**: El paso tuvo éxito pero generó un problema inesperado
* **TOKEN\_ERROR**: Token ausente, expirado o inválido
* **ADVANCED\_TRACKING\_UPLOAD**: Fallo al subir los datos de seguimiento avanzado
* **TENANT\_ID\_EMPTY\_ERROR**: El ID del tenant estaba vacío o ausente
* **ADVANCED\_TRACKING\_SERIALIZATION\_ERROR**: Error al serializar los datos de seguimiento avanzado
* **ADVANCED\_TRACKING\_VALIDATION\_ERROR**: Fallo en la validación de los datos de seguimiento
* **TOKENIZER\_ERROR**: Error durante el proceso de tokenización


# Captura facial - Selphi

Este componente necesita una versión mínima de iOS13

## Introducción

La captura facial se realiza mediante el **Selphi Component**.

Este componente se encarga de capturar un selfie del usuario y extraer sus principales características faciales. Incluye los siguientes procesos:

* Gestión interna de cámaras y permisos.
* Asistencia durante la captura del rostro.
* Generación de plantillas faciales y de la imagen del usuario.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se describen los pasos necesarios para la integración básica del SDK. En esta página se detalla la información específica para lanzar este componente.

***

## Dependencias

Para evitar conflictos y problemas de compatibilidad, si el proyecto contiene versiones antiguas de librerías Facephi (Widgets), deben eliminarse por completo antes de instalar los componentes de **SDKMobile**.

### Cocoapods

Las librerías de Facephi se distribuyen de forma remota mediante gestores de dependencias. En iOS, se utiliza **CocoaPods**. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
  pod 'FPHISDKMainComponent', '~> $VERSION'
```

Para instalar el componente **Selphi**, añade la dependencia correspondiente en el `Podfile` del proyecto, junto con las dependencias obligatorias del SDK.

```swift
  pod 'FPHISDKSelphiComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

Si utilizas **SPM**, asegúrate de que las dependencias obligatorias del SDK estén previamente instaladas.

```sh
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

Para instalar el componente **Selphi**, inclúyelo en los módulos del proyecto.

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-Selphi_component-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-Selphi_component-SPM.git
```

***

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist**:

```
Es necesario permitir el uso de la cámara (Privacy - Camera Usage Description)
```

## Controladores disponibles

| **Controlador**           | **Descripción**                                                |
| ------------------------- | -------------------------------------------------------------- |
| SelphiController          | Controlador principal de reconocimiento facial                 |
| RawTemplateController     | Controlador para generar un RawTemplate a partir de una imagen |
| SignatureSelphiController | Controlador para firmar un proceso con una Captura             |

***

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación, el componente puede lanzarse utilizando cualquiera de sus controladores disponibles, según la funcionalidad requerida.

```swift
let controller = SelphiController(data: selphiConfigurationData, output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

***

## Recepción del resultado

El lanzamiento del componente devuelve un resultado en formato `SdkResult`, que incluye:

* `selphiResult.finishStatus`
* `selphiResult.errorType`
* `selphiResult.data`

### Recepción de errores

*finishStatus*: Indica si la operación ha finalizado correctamente. Posibles valores:

<pre class="language-swift"><code class="lang-swift"><strong>FinishStatus.STATUS_OK
</strong>FinishStatus.STATUS_ERROR
</code></pre>

*errorType*: Errores propios del widget.

En iOS, `errorType` es un `ErrorType` del SDK. En un timeout, el enum Swift puede ser `.SDK_TIMEOUT`, `.SELPHI_TIMEOUT(LivenessDiagnostic?)` o, si se interpola directamente, mostrar nombres como `SDK_TIMEOUT` o `SELPHI_TIMEOUT`. En iOS no existe un caso `TIMEOUT` sin prefijo.

Para serializar el error debe utilizarse:

```swift
sdkResult.errorType.toString(addComponentPrefix: "SPI_")
```

Esto devuelve `SPI_TIMEOUT` tanto si el enum es `SDK_TIMEOUT` como `SELPHI_TIMEOUT`.

#### Comportamiento en timeout

En un timeout, el resultado tiene:

* `finishStatus`: `STATUS_ERROR`
* `data`: `nil` (no se devuelve un `SelphiResult`)
* `errorType`: `.SDK_TIMEOUT` o `.SELPHI_TIMEOUT(LivenessDiagnostic?)`

El caso `SELPHI_TIMEOUT` conserva, cuando está disponible, el diagnóstico de liveness del widget. Esa información **no** forma parte de `data`; solo puede leerse en iOS mediante pattern matching sobre `errorType`:

```swift
if case .SELPHI_TIMEOUT(let diagnostic) = sdkResult.errorType {
    // diagnostic: LivenessDiagnostic? (puede ser nil)
}
```

Si el timeout llega como `SDK_TIMEOUT`, no incluye diagnóstico de liveness. Si llega como `SELPHI_TIMEOUT`, el diagnóstico asociado puede ser `nil` cuando el timeout se produce por la vía de error del widget (`FWETimeout`) en lugar del delegate `extractionTimeout()`.

Para integraciones iOS nativas, el valor serializado debe tratarse como `SPI_TIMEOUT` (incluye tanto `SDK_TIMEOUT` como `SELPHI_TIMEOUT` del enum).

Si `showDiagnostic` está activo, el callback `output` no se invoca en el instante del timeout: se muestra primero la pantalla de diagnóstico y el resultado se entrega al pulsar cerrar. Con `showDiagnostic` desactivado, el callback se ejecuta de forma inmediata.

La lista siguiente incluye errores del contrato multiplataforma; algunos no se producen en iOS.

* SPI\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* SPI\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Configuración del extractor incorrecta.
* SPI\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* SPI\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* SPI\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* SPI\_EMPTY\_LICENSE: El String de licencia está vacío.
* SPI\_EXTRACTION\_LICENSE\_ERROR: Widget: Error de licencia.
* SPI\_ACTIVE\_LIVENESS\_ERROR: Widget: Error en el proceso de liveness activo.
* SPI\_HARDWARE\_ERROR: Widget: Error de hardware.
* SPI\_INITIALIZATION\_ERROR: Error de inicialización.
* SPI\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos.
* SPI\_NO\_DATA\_ERROR: Los datos de entrada son nulos.
* SPI\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* SPI\_RESOURCES\_FILE\_NOT\_FOUND: No se ha encontrado el zip de recursos.
* SPI\_SETTINGS\_PERMISSION\_ERROR: Widget: Error de permisos.
* SPI\_TEMPLATE\_ERROR:
* SPI\_TIMEOUT: Timeout en el proceso (`SDK_TIMEOUT` o `SELPHI_TIMEOUT` del enum).
* SPI\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Error en la captura.
* SPI\_UNKNOWN\_ERROR: Error desconocido.
* SPI\_WIDGET\_RESULT\_DATA\_ERROR: Error en los datos de salida del widget.

### Recepción de ejecución correcta - data

El contenido del campo `data` depende del componente lanzado. En **Selphi**, puede incluir:

* `template`\
  Plantilla facial generada tras la extracción. Válida para **authentication**.
* `templateRaw`\
  Plantilla facial en bruto generada después del proceso de extracción. Válida para **authentication**.
* `bestImageData`\
  Mejor imagen capturada, en formato array de bytes y tamaño original. Válida para **liveness**.
* `bestImageCroppedData`\
  Imagen recortada centrada en el rostro. Recomendado como avatar del usuario.
* `qrData`\
  Información obtenida de la lectura de QR en formato `String`.
* `bestImageTokenized`\
  Imagen cifrada resultante del proceso. Válida para **liveness**.

***

## Información avanzada

### Controladores adicionales

**SignatureSelphiController**\
Funciona igual que `SelphiController`, pero genera un fichero de firma del proceso.

**RawTemplateController**\
Permite generar un `RawTemplate` a partir de una imagen (`bitmap`).

Ejemplo de uso:

```swift
let controller = RawTemplateController(
	base64: bestImageData.base64EncodedString(),
	output: { sdkResult in
		guard let result = sdkResult.data else {return}
		print(result.base64EncodedString())
	})
SDKController.shared.launchMethod(controller: controller)
```

o

```swift
let controller = RawTemplateController(
	data: bestImageData,
	output: { sdkResult in
		guard let result = sdkResult.data else {return}
		print(result.base64EncodedString())
	})
SDKController.shared.launchMethod(controller: controller)
```

### Configuración avanzada

Para lanzar el componente, se debe crear un objeto `SelphiConfigurationData`.\
Este objeto define el comportamiento y la configuración del componente.

#### Parámetros disponibles

* `resourcesPath`\
  Ruta relativa a la carpeta `Resources` donde se encuentra el archivo de recursos.
* `showTutorial`\
  Muestra el tutorial previo a la captura.
* `showDiagnostic`\
  Muestra una pantalla de diagnóstico en caso de error o permisos insuficientes.
* `showResultAfterCapture`\
  Muestra la imagen capturada y permite repetir el proceso.
* `debug`\
  Activa el modo depuración.
* `fullscreen`\
  Prioriza la visualización en pantalla completa.
* `cropPercent`\
  Porcentaje de recorte del rostro.
* `livenessMode`\
  Modo de detección de vida:
  * `NONE`
  * `PASSIVE`
  * `MOVE`
* `stabilizationMode`\
  Obliga al usuario a mantener la cabeza estable antes de iniciar el proceso.
* `templateRawOptimized`\
  Indica si el `templateRaw` debe optimizarse.
* `qrMode`\
  Activa o desactiva la lectura de QR.
* `videoFilename`\
  Ruta absoluta para grabar el vídeo del proceso.
* `cameraFlashEnabled`\
  Activa el flash de la cámara.
* `translationsContent`\
  Configuración avanzada de textos mediante XML.
* `viewsContent`\
  Configuración avanzada de vistas mediante XML.
* `vibrationEnabled`\
  Activa la vibración en errores y en resultados correctos.
* `animateDismiss`\
  Indica si se anima el cierre del SDK al finalizar el proceso. Disponible desde **2.8.1**.

### Personalización del componente

Además de los cambios que se pueden realizar a nivel de SDK (explicados en *Personalización del SDK*), este componente permite su propia personalización.

#### Textos

Los textos se personalizan sobrescribiendo claves en `Localizable.strings`, dentro de la carpeta `Resources`.

Las claves con sufijo `_alt` se utilizan para accesibilidad (VoiceOver).

Ejemplo de modificación del texto **COMENZAR** para `es`:

Hay que ir al archivo **Localizable.strings** de la carpeta **es.lproj** (si no existe esta carpeta, habrá que crearla).

```
"selphi_component_tip_button_message" = "EMPEZAR";
```

Si una clave no está definida, se utilizará el valor por defecto.

| **Name**                                  | **Value**                                                                                                                                                                                                                               |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| selphi\_component\_tutorial\_message\_1   | Coloca tu cara en el centro y mira de frente a la cámara.                                                                                                                                                                               |
| selphi\_component\_tutorial\_message\_2   | Retira cualquier objeto que cubra tu cara.                                                                                                                                                                                              |
| selphi\_component\_tutorial\_message\_3   | Busca un entorno bien iluminado, sin sombras sobre tu rostro.                                                                                                                                                                           |
| selphi\_component\_tip\_message           | Coloca tu cara en el centro del círculo                                                                                                                                                                                                 |
| selphi\_component\_tip\_title             | Reconocimiento facial                                                                                                                                                                                                                   |
| selphi\_component\_tip\_button            | COMENZAR                                                                                                                                                                                                                                |
| selphi\_component\_tip\_button\_alt       | Comenzar captura de rostro                                                                                                                                                                                                              |
| selphi\_component\_tip\_anim\_alt         | Una persona muestra su cara dentro del círculo y la aplicación le hace una foto.                                                                                                                                                        |
| selphi\_component\_tip\_move\_anim\_alt   | Animación de una pantalla de móvil con la cámara frontal activada. En el centro de la pantalla aparece un círculo. Una persona muestra su cara dentro del círculo, la mueve ligeramente hacia un lado y la aplicación le hace una foto. |
| selphi\_component\_tutorial\_1\_anim\_alt | La foto se realiza cuando la persona está en el centro.                                                                                                                                                                                 |
| selphi\_component\_tutorial\_2\_anim\_alt | Una persona se quita las gafas de sol y se retira el pelo de los ojos.                                                                                                                                                                  |
| selphi\_component\_tutorial\_3\_anim\_alt | La imagen aparece oscura y una persona enciende la luz.                                                                                                                                                                                 |
| selphi\_component\_tip\_move\_message     | Coloca tu cara en el centro del círculo y sigue las indicaciones.                                                                                                                                                                       |
| selphi\_component\_timeout\_title         | Tiempo superado                                                                                                                                                                                                                         |
| selphi\_component\_timeout\_desc          | No hemos podido identificarte. Inténtalo de nuevo                                                                                                                                                                                       |

#### Animaciones

Las animaciones del tip previo y tutoriales son **Lottie (.json)**.

Para sustituirlas:

* Añade el archivo en la carpeta `Resources`.
* Mantén exactamente el mismo nombre del archivo.

Si no se sustituyen, se mostrarán las animaciones por defecto.

<table><thead><tr><th width="228.43359375">Nombre</th><th>Función</th></tr></thead><tbody><tr><td>selphi_anim_tip</td><td>Animación LivenessMode: None, Passive</td></tr><tr><td>selphi_anim_tip_move</td><td>Animación LivenessMode: Move</td></tr><tr><td>selphi_anim_tuto_1</td><td>Primera animación del tutorial</td></tr><tr><td>selphi_anim_tuto_2</td><td>Segunda animación del tutorial</td></tr><tr><td>selphi_anim_tuto_3</td><td>Tercera animación del tutorial</td></tr></tbody></table>


# Captura facial con IAD - Selphi

Este componente necesita una versión mínima de iOS13

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial con detección de ataques de inyección de vídeo se realiza mediante el **Selphi IAD Component**.

Este componente se encarga de capturar un selfie del usuario y extraer sus características faciales más relevantes incorporando un conjunto de controles de seguridad preventivos orientados a detectar entornos no confiables. Durante el proceso se realizan, entre otros, los siguientes pasos:

* Gestión interna de cámaras y permisos.
* Detección de intentos de suplantación mediante vídeos o fuentes de cámara manipuladas.
* Asistencia guiada durante la captura facial.
* Generación de plantillas biométricas e imágenes del usuario.

En la sección [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se describen los pasos básicos para la integración del SDK. En esta página se detalla la información específica necesaria para lanzar y configurar este componente.

***

## Dependencia <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cocoapods

Las librerías de Facephi se distribuyen de forma remota mediante gestores de dependencias. En iOS, se utiliza **CocoaPods**. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
  pod 'FPHISDKMainComponent', '~> $VERSION'
```

Para instalar el componente **SelphiIAD**, añade la dependencia correspondiente en el `Podfile` del proyecto, junto con las dependencias obligatorias del SDK.

```swift
  pod 'FPHISDKSelphiIADComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

Si utilizas **SPM**, asegúrate de que las dependencias obligatorias del SDK estén previamente instaladas.

```sh
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

Para instalar el componente **SelphiIAD**, inclúyelo en los módulos del proyecto.

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-Selphi_IAD_Component-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-Selphi_IAD_Component-SPM.git
```

***

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist**:

```
Es necesario permitir el uso de la cámara (Privacy - Camera Usage Description)
```

## Diferencias respecto a captura facial estándar

Las diferencias con el resto de la documentación de *Captura facial* se pueden resumir en dos apartados:

* El componente de SelphiIAD tiene una licencia distinta a la del componente estándar, por lo que, al comenzar a utilizar esta depedencia, **se deberá modificar la licencia del integrador.**
* En caso de una captura correcta, el modelo de datos `SelphiResult` contiene el parámetro:
  * `iad` -> Información obtenida en el análisis de ataques de inyección de vídeo preparada para su envío al servicio de verificación.

[<br>](https://open-2v.gitbook.com/url/preview/site_wUp9i/soluciones-y-sdks/sdk-mobile/android-sdk/componentes-modulos/captura-facial)


# Captura de documentos - SelphID

Este componente necesita una versión mínima de iOS9

## Introducción

Este componente se encarga de la **captura y análisis de documentos de identidad**, permitiendo extraer información estructurada y obtener imágenes procesadas del documento.

Sus principales funcionalidades son:

* Gestión interna de cámara y permisos.
* Asistencia guiada para la captura del **anverso y reverso** del documento.
* Extracción automática de datos mediante OCR.
* Obtención de imágenes procesadas del documento y de elementos asociados (rostro, firma, etc.).
* Alto nivel de configuración: países, idiomas, tipos y modelos de documentos.

Para una integración básica del SDK, consulta el apartado [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado). En esta página se detalla la información específica para el uso de este componente.

***

## Dependencias

Para evitar conflictos y problemas de compatibilidad, si el proyecto contiene versiones antiguas de librerías de Facephi (Widgets), estas deben eliminarse **por completo** antes de instalar los componentes de **SDK Mobile**.

### **Cocoapods**

* Las librerías de Facephi se distribuyen de forma remota mediante gestores de dependencias. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente **SelphID**, añade la dependencia correspondiente en el `Podfile` del proyecto.

```swift
pod 'FPHISDKSelphIDComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

Si utilizas **SPM**, asegúrate de que las dependencias obligatorias del SDK estén previamente instaladas.

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

Para instalar el componente **SelphID**, inclúyelo en los módulos del proyecto.

<pre class="language-swift"><code class="lang-swift"><strong>//HTTPS
</strong>https://github.com/facephi-clienters/SDK-SelphidComponentLight.git
//SSH
git@github.com:facephi-clienters/SDK-SelphidComponentLight.git
</code></pre>

***

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist**:

```
Es necesario permitir el uso de la cámara (Privacy - Camera Usage Description)
```

## Controladores disponibles

| **Controlador**   | **Descripción**                                       |
| ----------------- | ----------------------------------------------------- |
| SelphIDController | Controlador principal de reconocimiento de documentos |

***

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación, el componente puede lanzarse utilizando cualquiera de sus controladores disponibles, según la funcionalidad requerida.

```swift
let controller = SelphIDController(data: selphIDConfigurationData, output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

***

## Recepción del resultado <a href="#recepcion-del-resultado" id="recepcion-del-resultado"></a>

El resultado del lanzamiento se devuelve en un objeto `SdkResult`, que contiene:

* `selphIDResult.finishStatus`
* `selphIDResult.errorType`
* `selphIDResult.data`

***

### Recepción de errores <a href="#recepcion-de-errores" id="recepcion-de-errores"></a>

*finishStatus*: Que nos indicará si la operación ha finalizado correctamente. Posibles valores:

```swift
FinishStatus.STATUS_OK
FinishStatus.STATUS_ERROR
```

*errorType*: Errores propios del widget.

En iOS, `errorType` es un `ErrorType` del SDK. En un timeout, el enum Swift puede ser `.SDK_TIMEOUT`, `.SELPHID_TIMEOUT(UIImage?, UIImage?)` o, si se interpola directamente, mostrar nombres como `SDK_TIMEOUT` o `SELPHID_TIMEOUT`. En iOS no existe un caso `TIMEOUT` sin prefijo.

Para serializar el error debe utilizarse:

```swift
sdkResult.errorType.toString(addComponentPrefix: "SPD_")
```

Esto devuelve `SPD_TIMEOUT` tanto si el enum es `SDK_TIMEOUT` como `SELPHID_TIMEOUT`.

#### Comportamiento en timeout

En un timeout, el resultado tiene:

* `finishStatus`: `STATUS_ERROR`
* `data`: `nil` (no se devuelve un `SelphIDResult`)
* `errorType`: `.SDK_TIMEOUT` o `.SELPHID_TIMEOUT(UIImage?, UIImage?)`

El caso `SELPHID_TIMEOUT` conserva, cuando están disponibles, las imágenes crudas del documento capturadas antes del timeout (`rawFrontDocument` y `rawBackDocument` del widget). Esa información **no** forma parte de `data` ni se devuelve como `rawFrontDocument` / `rawBackDocument` del resultado de éxito; solo puede leerse en iOS mediante pattern matching sobre `errorType`:

```swift
if case .SELPHID_TIMEOUT(let frontRaw, let backRaw) = sdkResult.errorType {
    // frontRaw, backRaw: UIImage? (pueden ser nil)
}
```

Si el timeout llega como `SDK_TIMEOUT`, no incluye imágenes crudas. Si llega como `SELPHID_TIMEOUT`, las imágenes asociadas pueden ser `nil` cuando el timeout se produce por la vía de error del widget (`FWMETimeout`) en lugar del delegate `captureTimeout()`.

Para integraciones iOS nativas, el valor serializado debe tratarse como `SPD_TIMEOUT` (incluye tanto `SDK_TIMEOUT` como `SELPHID_TIMEOUT` del enum).

En iOS, propiedades como `timeoutDiagnostic` o `captureProgress` **no** se incluyen en el `SdkResult` de error. El componente usa `captureProgress` internamente para mostrar el mensaje de la pantalla de diagnóstico cuando `showDiagnostic` está activo.

Si `showDiagnostic` está activo, el callback `output` no se invoca en el instante del timeout: se muestra primero la pantalla de diagnóstico y el resultado se entrega al pulsar cerrar. Con `showDiagnostic` desactivado, el callback se ejecuta de forma inmediata.

La lista siguiente incluye errores del contrato multiplataforma; algunos no se producen en iOS (por ejemplo, `SPD_MOVE_FAIL`).

* SPD\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación necesario es nulo.
* SPD\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Configuración del extractor incorrecta
* SPD\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* SPD\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* SPD\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK.
* SPD\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* SPD\_CONTROL\_NOT\_INITIALIZATED\_ERROR: Widget: Error de inicialización
* SPD\_EMPTY\_LICENSE: El String de licencia está vacío.
* SPD\_EXTRACTION\_LICENSE\_ERROR: Widget: Error de licencia
* SPD\_HARDWARE\_ERROR: Widget: Error de hardware
* SPD\_INITIALIZATION\_ERROR: Error de inicialización.
* SPD\_MOVE\_FAIL: El usuario no se ha movido como se le ha especificado en el proceso.
* SPD\_NO\_DATA\_ERROR: Los datos de entrada son nulos.
* SPD\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* SPD\_RESOURCES\_NOT\_FOUND: No se ha encontrado el zip de recursos
* SPD\_SETTINGS\_PERMISSION\_ERROR: Widget: Error de permisos
* SPD\_TIMEOUT: Timeout en el proceso (`SDK_TIMEOUT` o `SELPHID_TIMEOUT` del enum).
* SPD\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Error en la captura
* SPD\_UNKNOWN\_ERROR: Error desconocido
* SPD\_WIDGET\_RESULT\_DATA\_ERROR: Error en los datos de salida del widget

### Recepción de ejecución correcta - data

El contenido del campo `data` depende del componente. En el caso de **SelphID**, se devuelven los siguientes campos:

**frontDocument / tokenFrontDocument**

La imagen frontal del documento procesada, limpiada y recortada por los bordes y su token correspondiente.

**backDocument / tokenBackDocument**

La imagen trasera del documento procesada, limpiada y recortada por los bordes y su token asociado.

**faceImage / tokenFaceImage**

La imagen del rostro que se ha encontrado en el documento, en caso de que exista y su token asociado.

**documentCaptured**

Esta propiedad indica el modelo de documento que se ha capturado cuando se realiza una busqueda en modo SMSearch. De esta forma la aplicación puede conocer qué modelo, de entre todos los permitidos, se ha detectado.

**matchingSidesScore**

Esta propiedad devuelve un cálculo de la similitud de los datos leídos entre el front y el back del documento. El cálculo se realiza comprobando la similitud entre los campos comunes leídos en ambas caras. El resultado del cálculo será un valor entre 0.0 y 1.0 para el caso de que existan campos comunes en el documento. Cuanto mayor es el valor, más similares son los datos comparados. Si el cálculo devuelve -1.0 es que el documento no contiene campos comunes o aún no se tiene información de las dos caras.

**Propiedad captureProgress**

Esta propiedad devuelve el estado en el que se encontraba el proceso de captura cuando el widget terminó con éxito (`STATUS_OK`). En un timeout, `data` es `nil` y este valor no se incluye en el `SdkResult` del callback de error. Estos son los posibles valores:

```
Front_Detection_None = 0
Front_Detection_Uncertain = 1
Front_Detection_Completed = 2
Front_Document_Analyzed = 3
Back_Detection_None = 4
Back_Detection_Uncertain = 5
Back_Detection_Completed = 6
Back_Document_Analyzed = 7
```

* **0**: En la lectura del Front, el widget termino sin poder haber detectado nada. Generalmente cuando no se pone ningún documento.
* **1**: En la lectura del Front, el widget termino habiendo detectado parcialmente un documento. En este caso algunos de los elementos esperados se han conseguido detectar, pero no todos los necesarios.
* **2**: En la lectura del Front, el widget termino habiendo completado la detección de todos los elementos del documento. Si el widget acaba en este estado es porque el análisis de OCR no se ha podido completar con éxito.
* **3**: En la lectura del Front, el widget termino habiendo analizado y extraído todo el OCR del documento. Este es el estado en el que acabaría una lectura correcta del Front de un documento.

Los estados **del 4 al 7** son exactamente iguales solo que se refieren al resultado del proceso cuando se analiza el back.

**ocrResults**

Este diccionario contiene todos los datos detectados en el documento. Las claves de cada campo están codificadas de tal forma que la propia clave contiene información de donde se ha obtenido el valor. Así, por ejemplo, la clave Front/MRZ/DocumentNumber indica el valor del DocumentNumber que se ha leído en el Front del documento y en la región del MRZ. Estas claves dependen del documento capturado y por tanto serán diferentes entre distintos países y modelos de documento. El diccionario también contiene claves con nombres más genéricos y que no llevan información relativa a la ubicación. Estas claves contienen el dato más completo de todos los leídos para dicho campo.

Estas claves son los siguientes:

* **FirstName**: El valor asociado a esta clave contiene el nombre del usuario.
* **LastName**: El valor asociado a esta clave contiene los apellidos del usuario.
* **DateOfBirth**: El valor asociado a esta clave contiene la fecha de nacimiento detectada en el documento.
* **Gender**: El valor asociado a esta clave contiene el sexo del usuario detectado en el documento.
* **Nationality**: El valor asociado a esta clave contiene la nacionalidad del usuario detectado en el documento.
* **DocumentNumber**: El valor asociado a esta clave contiene el número de documento.
* **DateOfExpiry**: El valor asociado a esta clave contiene la fecha de expiración del documento.
* **Issuer**: El valor asociado a esta clave contiene el editor del documento.
* **DateofIssue**: El valor asociado a esta clave contiene la fecha de expedición del documento.
* **PlaceOfBirth**: El valor asociado a esta clave contiene el lugar de nacimiento del usuario.
* **Address**: El valor asociado a esta clave contiene la dirección detectada en el documento.

Adicionalmente se añaden claves del propio objeto results para hacer más fácil su búsqueda:

* **DocumentCaptured**: Valor del modelo de documento que se ha capturado según el .xml de modelos. Corresponde a la propiedad documentCaptured.
* **MatchingSidesScore**: Valor que indica la correspondencia entre las caras leídas del documento. Corresponde a la propiedad matchingSidesScore.

**countryCaptured**

País del documento.

**documentTypeCaptured**

Tipo de documento. Se corresponde con los del apartado 5.1.10.

**encodedDataImages**

Disponible solo con flag *encodedDataFocusEnabled* activo, en flavor MBSDR y versión del zip de recursos > 1.41.4. Array de imágenes extraídas por el lector de código de barras.

**tokenEncodedDataImages**

Disponible solo con flag *encodedDataFocusEnabled* activo, en flavor MBSDR y versión del zip de recursos > 1.41.4. Array de imágenes tokenizadas extraídas por el lector de código de barras.

**personalData**

Conjunto reducido de datos obtenidos del usuario:

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

***

## Información avanzada

### Selector de documentos - OPCIONAL

**showDocumentSelector**

Activación de la vista de selector de documentos. Se presentará nada más lanzar el controlador.

**enabledCountries**

Listado de países en ISO2 que aparecerán en el selector. Si su valor es nulo o no contiene valores válidos, se mostrarán todos los disponibles por el SDK.

**enabledDocumentTypes**

Listado de tipos de documentos que aparecerán en el selector de tipos de documentos. Si su valor es nulo o no contiene valores, se mostrarán todos los disponibles por el SDK.

### Configuración avanzada

El componente se configura mediante un objeto `SelphIDConfigurationData`.

**debug**

Activación del modo depuración del componente.

**resourcesPath**

Establece la ruta donde se encuentra el archivo de recursos del widget. Este archivo contiene tanto los recursos gráficos como los recursos de localización. Esta ruta debe especificarse relativa a la carpeta ‘Resources’ de la aplicación principal.

**wizardMode**

Indica si el widget queda configurado para realizar la captura de ambas partes (frontal y trasera) del documento una a continuación de la otra. En este modo el widget solo se lanzaría una vez y al terminar de capturar el front, continuaría seguidamente con el back.

**showResultAfterCapture**

Indica si mostrar o no una pantalla con la imagen capturada del documento después del proceso de análisis. En esta pantalla se le da al usuario la posibilidad de repetir el proceso de captura si la imagen que se obtuvo del documento no fuera correcta.

**showTutorial**

Indica si el widget activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**tutorialOnly**

Indica si el widget se quiere lanzar solo para mostrar el tutorial.

**scanMode**

Indica el modo de escaneo OCR de los documentos. Dependiendo de la elección, se escanearán y buscarán varios tipos de documentos o uno en concreto. Este modo puede ser de tres tipos:

* **SelphIDScanMode.MODE\_GENERIC**: El modo genérico que permite escanear cualquier tipo de documento independiente del país o el tipo de documento. El resultado de este modo no es tan preciso como los siguientes pero permite escanear varios documentos estándar.
* **SelphIDScanMode.MODE\_SEARCH**: El modo de búsqueda permitirá utilizar una whitelist y blacklist, y buscará en los documentos que cumplan dichas condiciones. Estas condiciones se indican en la variable "specificData". De este modo se permite realizar la búsqueda acotando el número de plantillas, y haciendo que la búsqueda sea mucho más afinada que en el caso genérico.
* **SelphIDScanMode.MODE\_SPECIFIC**: Búsqueda de un documento específico. Estas condiciones se indican en la propiedad "specificData" que se muestra en lo sucesivo.

**SpecificData**

Esta propiedad permite definir qué documentos se escanearán durante el proceso, en caso de declarar el modo de escaneo (scanMode) a SMSearch o SMSpecific.

Un ejemplo de configuración que permita escanear todos los documentos de nacionalidad española sería el siguiente:

```swift
// Search mode definition
conf.scanMode = SelphIDScanMode.MODE_SEARCH
conf.specificData = “ES|<ALL>” // Código ISO de España (ES)
```

**tokenImageQuality**

Indica la cantidad de calidad que se quiere recibir en las imágenes tokenizadas. Valor entre 0 y 1.

**DocumentType**

Los valores permitidos son los siguientes:

* **SelphIDDocumentType.ID\_CARD:** El widget queda configurado para realizar la captura de documentos de identidad.
* **SelphIDDocumentType.PASSPORT:** El widget queda configurado para realizar la captura de pasaportes.
* **SelphIDDocumentType.DRIVERS\_LICENSE:** El widget queda configurado para realizar la captura de licencias de conducción.
* **SelphIDDocumentType.FOREIGN\_CARD:** El widget queda configurado para realizar la captura de documentos extranjeros.
* **SelphIDDocumentType.CUSTOM:** El widget queda configurado para realizar la captura de otro tipo de documentos que no corresponden a ninguna de las categorias anteriores.

**DocumentSide**

Los valores permitidos son los siguientes:

* **SelphIDDocumentSide.FRONT:** El widget queda configurado para realizar la captura de la parte frontal del documento.
* **SelphIDDocumentSide.BACK:** El widget queda configurado para realizar la captura de la parte trasera del documento.
* **SelphIDDocumentSide.ALL:** El widget queda configurado para realizar la captura de ambas partes del documento.

**Timeout**

Es un enumerado que define el timeout de la captura de un lado del documento. Tiene 3 posibles valores:

* **SelphIDTimeout.SHORT:** 15 segundos.
* **SelphIDTimeout.MEDIUM:** 20 segundos.
* **SelphIDTimeout.LONG:** 25 segundos.
* **SelphIDTimeout.VERY\_LONG**: 60 segundos.

**videoFilename**

Establece la ruta absoluta del nombre del archivo en el que se grabará un video del proceso de captura. La aplicación es la responsable de solicitar los permisos necesarios al teléfono en caso de que esa ruta requiera de permisos adicionales. El widget, por defecto, no realizará ningún proceso de grabación a menos que se especifique una ruta de archivo mediante este método.

**DocumentModels**

Esta propiedad permite, mediante una cadena en formato xml, configurar modelado de los documentos que el widget va a tratar de capturar. La definición de este modelado se encentra, por defecto, en un .xml de modelos que se encuentra en el .zip de recursos. Con esta propiedad se permite a una aplicación actualizar, en caliente, los modelados de los documentos.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**generateRawImages**

Esta propiedad configura el widget para devolver la imagen completa de la cámara que se utilizó para capturar el documento. Estas imágenes se devuelven en las propiedades `rawFrontDocument` y `rawBackDocument` del objeto `results` respectivamente.

**tokenPreviousCaptureData**

Cuando la captura del documento se realiza en 2 llamadas, esta propiedad permite pasar un diccionario con la información de la captura previa. De esta manera el widget puede combinar los resultados de ambas lecturas de una manera inteligente y así devolver la información combinada de ambas capturas. También permite al widget calcular un grado de similitud de los datos de ambas caras.

En el caso que la captura de ambas caras del documento se realice en una única llamada esto no es necesario ya que el widget internamente hace este proceso.

**translationsContent**

Esta propiedad avanzada permite, mediante una cadena en formato xml, configurar la traducción de los literales que se muestran durante el proceso.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**viewsContent**

Esta propiedad avanzada permite, mediante una cadena en formato xml, configurar las vistas del widget.

Nota: Esta propiedad no altera el contenido del archivo de recursos.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

**vibrationEnabled**

Indica si se desea un feedback de vibración al acabar el proceso.

**animateDismiss**

Indica si se anima el cierre del SDK al finalizar el proceso. Disponible desde **2.8.1**.

**encodedDataFocusEnabled**

Activa el modo de lectura de códigos de barras cuando hay dificultad de lectura. Solo disponible en el flavor MBSDR y con el zip de recursos en una versión superior a > 1.41.4

### Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de Personalización del SDK), este componente en concreto permite la modificación de su interfaz.

#### Colores

El componente, además de los colores estándar existentes en el [apartado general de personalización](/sdks/sdk-mobile/ios-sdk/personalizacion), dispone de dos colores específicos para la vista del selector:

* *sdkSelectorBackgroundColor*: Es el color usado para el fondo de la vista de selección. No confundir con *sdkBackgroundColor*.
* *sdkCardBackgroundColor*: Es el color usado para el fondo de las "cards" de selección.

#### Imágenes

El componente, además de las imágenes estándar existentes en el [apartado general de personalización](/sdks/sdk-mobile/ios-sdk/personalizacion), dispone de imágenes específicas para la vista del selector. El listado puede verse accediendo al enumerado `R.Image`.

#### Textos

Los textos pueden personalizarse sobrescribiendo las claves correspondientes en `Localizable.strings`.

Las claves con sufijo `_alt` se utilizan para accesibilidad (VoiceOver).

Ejemplo de modificación del texto **COMENZAR** para `es`:

Hay que ir al archivo **Localizable.strings** de la carpeta **es.lproj** (si no existe esta carpeta, habrá que crearla).

`"selphid_component_tip_button_message"="EMPEZAR";`

Si una clave no está definida, se utilizará el valor por defecto.

| Name                                            | Value                                                                                                                                                                                                                                                                                                                  |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `selphid_component_tutorial_message_1`          | Busca un fondo con buen contraste.                                                                                                                                                                                                                                                                                     |
| `selphid_component_tutorial_message_2`          | Coloca el documento dentro del recuadro.                                                                                                                                                                                                                                                                               |
| `selphid_component_tutorial_message_3`          | Evita brillos que dificulten la lectura del documento.                                                                                                                                                                                                                                                                 |
| `selphid_component_tip_message`                 | **Enfoca** tu documento **dentro del recuadro.** La foto se hará automáticamente.                                                                                                                                                                                                                                      |
| `selphid_component_tip_title`                   | Foto del documento                                                                                                                                                                                                                                                                                                     |
| `selphid_component_tip_button`                  | COMENZAR                                                                                                                                                                                                                                                                                                               |
| `selphid_component_tip_close_button_alt`        | VOLVER                                                                                                                                                                                                                                                                                                                 |
| `selphid_component_tip_button_alt`              | Comenzar captura de documento                                                                                                                                                                                                                                                                                          |
| `selphid_component_tip_anim_id_alt`             | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical.                                                                                                                                                                                                                         |
| `selphid_component_tip_anim_passport_alt`       | Animación de un teléfono móvil haciendo una foto a un pasaporte. El documento aparece en horizontal, abierto por la página donde aparece la foto. El móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando la página del pasaporte encaja dentro del recuadro, la aplicación hace una foto. |
| `selphid_component_tip_anim_driving_alt`        | Animación de un teléfono móvil haciendo una foto a un carné de conducir. El documento aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.                                               |
| `selphid_component_tutorial_1_anim_id_alt`      | Coloca tu documento de identidad en horizontal, y apunta con tu teléfono en posición vertical.                                                                                                                                                                                                                         |
| `selphid_component_tutorial_2_anim_id_alt`      | Coloca el documento en una superficie con un color distinto al documento.                                                                                                                                                                                                                                              |
| `selphid_component_tutorial_3_anim_id_alt`      | Hay reflejos en el documento.                                                                                                                                                                                                                                                                                          |
| `selphid_component_tutorial_1_anim_pass_alt`    | Se muestra un pasaporte de color blanco, sobre un fondo blanco. Los bordes del documento no se distinguen con claridad. Mediante una animación, el fondo cambia de color.                                                                                                                                              |
| `selphid_component_tutorial_2_anim_pass_alt`    | Un teléfono móvil hace una foto a un pasaporte. El documento aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.                                                                        |
| `selphid_component_tutorial_3_anim_pass_alt`    | Un pasaporte, visto de frente. Al inclinarlo, aparecen reflejos sobre el documento.                                                                                                                                                                                                                                    |
| `selphid_component_tutorial_1_anim_driving_alt` | Se muestra un carné de conducir de color blanco, sobre un fondo blanco. Los bordes del documento no se distinguen con claridad. Mediante una animación, el fondo cambia de color.                                                                                                                                      |
| `selphid_component_tutorial_2_anim_driving_alt` | Un teléfono móvil hace una foto a un carné de conducir. El documento aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.                                                                |
| `selphid_component_tutorial_3_anim_driving_alt` | Un carné de conducir, visto de frente. Al inclinarlo, aparecen reflejos sobre el documento.                                                                                                                                                                                                                            |
| `selphid_component_tip_health_alt`              | Animación de un teléfono móvil haciendo una foto a una tarjeta sanitaria. El documento aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.                                              |
| `selphid_component_tutorial_1_anim_health_alt`  | Se muestra una tarjeta sanitaria de color blanco, sobre un fondo blanco. Los bordes del documento no se distinguen con claridad. Mediante una animación, el fondo cambia de color.                                                                                                                                     |
| `selphid_component_tutorial_2_anim_health_alt`  | Un teléfono móvil hace una foto a una tarjeta sanitaria. El documento aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.                                                               |
| `selphid_component_tutorial_3_anim_health_alt`  | Una tarjeta sanitaria, visto de frente. Al inclinarlo, aparecen reflejos sobre el documento.                                                                                                                                                                                                                           |
| `selphid_component_tip_custom_alt`              |                                                                                                                                                                                                                                                                                                                        |
| `selphid_component_tutorial_1_anim_custom_alt`  |                                                                                                                                                                                                                                                                                                                        |
| `selphid_component_tutorial_2_anim_custom_alt`  |                                                                                                                                                                                                                                                                                                                        |
| `selphid_component_tutorial_3_anim_custom_alt`  |                                                                                                                                                                                                                                                                                                                        |
| `selphid_component_timeout_title`               | Tiempo superado                                                                                                                                                                                                                                                                                                        |
| `selphid_component_timeout_front_desc`          | Comprueba que el frente del documento está dentro del recuadro y los datos son visibles.                                                                                                                                                                                                                               |
| `selphid_component_timeout_back_desc`           | Comprueba que el dorso del documento está dentro del recuadro y los datos son visibles.                                                                                                                                                                                                                                |
| `selphid_component_timeout_desc`                | Comprueba que el documento está dentro del recuadro y los datos son visibles.                                                                                                                                                                                                                                          |
| `selphid_selector_title`                        | Realiza tu onboarding                                                                                                                                                                                                                                                                                                  |
| `selphid_selector_country_label`                | ¿De qué país es tu documento?                                                                                                                                                                                                                                                                                          |
| `selphid_selector_country_search_label`         | Elige un país                                                                                                                                                                                                                                                                                                          |
| `selphid_selector_country_search_placeholder`   | Busca un país                                                                                                                                                                                                                                                                                                          |
| `selphid_selector_country_no_results`           | Sin resultados                                                                                                                                                                                                                                                                                                         |
| `selphid_selector_document_label`               | ¿Qué documento utilizarás?                                                                                                                                                                                                                                                                                             |
| `selphid_selector_document_dialog_title`        | Elige el documento                                                                                                                                                                                                                                                                                                     |
| `selphid_selector_continue`                     | CONTINUAR                                                                                                                                                                                                                                                                                                              |
| `selphid_selector_type_id_card`                 | Documento de identidad                                                                                                                                                                                                                                                                                                 |
| `selphid_selector_type_passport`                | Pasaporte                                                                                                                                                                                                                                                                                                              |
| `selphid_selector_type_drivers_license`         | Licencia de conducir                                                                                                                                                                                                                                                                                                   |
| `selphid_selector_type_foreign_card`            | Tarjeta de residencia                                                                                                                                                                                                                                                                                                  |
| `selphid_selector_type_credit_card`             | Tarjeta de crédito                                                                                                                                                                                                                                                                                                     |
| `selphid_selector_type_custom`                  | Personalizado                                                                                                                                                                                                                                                                                                          |
| `selphid_selector_type_visa`                    | Visado                                                                                                                                                                                                                                                                                                                 |
| `selphid_selector_exit_alert_finish`            | Finalizar                                                                                                                                                                                                                                                                                                              |
| `selphid_selector_exit_alert_question`          | ¿Seguro que quiere finalizar el proceso?                                                                                                                                                                                                                                                                               |
| `selphid_selector_exit_alert_accept`            | Aceptar                                                                                                                                                                                                                                                                                                                |
| `selphid_selector_exit_alert_cancel`            | Cancelar                                                                                                                                                                                                                                                                                                               |

#### **Animaciones**

Las animaciones del tip previo y tutoriales son **Lottie (.json)**.

Para sustituirlas:

* Añade el archivo en la carpeta `Resources`.
* Mantén exactamente el mismo nombre del archivo.

Si no se sustituyen, se mostrarán las animaciones por defecto.

<table><thead><tr><th width="258.640625">Nombre</th><th>Uso</th></tr></thead><tbody><tr><td>selphid_anim_tip_id_male</td><td>Animación para el tip previo del documento de identidad</td></tr><tr><td>selphid_anim_tip_pass_male</td><td>Animacion para el tip previo del pasaporte</td></tr><tr><td>selphid_anim_tip_driver_male</td><td>Animacion para el tip previo de la licencia de conducir</td></tr><tr><td>selphid_anim_tuto_id_1</td><td>Primera animación del tutorial del documento de identidad</td></tr><tr><td>selphid_anim_tuto_id_2</td><td>Segunda animación del tutorial del documento de identidad</td></tr><tr><td>selphid_anim_tuto_id_3</td><td>Tercera animación del tutorial del documento de identidad</td></tr><tr><td>selphid_anim_tuto_pass_1</td><td>Primera animación del tutorial del pasaporte</td></tr><tr><td>selphid_anim_tuto_pass_2</td><td>Segunda animación del tutorial del pasaporte</td></tr><tr><td>selphid_anim_tuto_pass_3</td><td>Tercera animación del tutorial del pasaporte</td></tr><tr><td>selphid_anim_tuto_driving_1</td><td>Primera animación del tutorial de la licencia de conducir</td></tr><tr><td>selphid_anim_tuto_driving_2</td><td>Segunda animación del tutorial de la licencia de conducir</td></tr><tr><td>selphid_anim_tuto_driving_3</td><td>Tercera animación del tutorial de la licencia de conducir</td></tr><tr><td>selphid_anim_tuto_custom_1</td><td>Primera animacion del tutorial para un documento customizado</td></tr><tr><td>selphid_anim_tuto_custom_2</td><td>Segunda animacion del tutorial para un documento customizado</td></tr><tr><td>selphid_anim_tuto_custom_3</td><td>Tercera animacion del tutorial para un documento customizado</td></tr></tbody></table>


# Captura de huellas - Phingers

Este componente necesita una versión mínima de iOS13

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

El *Componente* tratado en el documento actual recibe el nombre de ***Phingers Component***. Éste se encarga de realizar la captura de las huellas de los dedos (fingerprints) del usuario y la posterior extracción de las plantillas de las huellas posteriores. Sus principales funcionalidades son las siguientes:

* Dos modos de funcionamiento: extracción de los cuatro dedos de la mano (excepto el pulgar), o extracción únicamente del pulgar.
* Gestión interna de cámara.
* Gestión de permisos.
* Detección de vivacidad incorporada.
* Asistente en los procesos de captura de las huellas.
* Generación de las plantillas con las características de las huellas, imágenes y puntuaciones.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## **Dependencias**

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la **SDKMobile**.

### Cocoapods

```sh
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente actual deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```sh
pod 'FPHISDKPhingersTFComponent', '~> $VERSION'
```

* Una vez instaladas las dependencias, se podrá hacer uso de las diferentes funcionalidades del componente.

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar el componente de Selphid deberá incluirse en los módulos del proyecto:

<pre class="language-swift"><code class="lang-swift"><strong>//HTTPS
</strong>https://github.com/facephi-clienters/SDK-PhingersTF_Component-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-PhingersTF_Component-SPM.git
</code></pre>

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist**:

```
Es necesario permitir el uso de la cámara (Privacy - Camera Usage Description)
```

## Configuración del Info.plist (widget KMP)

{% hint style="warning" %}
**IMPORTANTE:** El componente **Phingers** utiliza un widget **KMP** con ficheros de recursos. Es imprescindible añadir la siguiente clave en el **Info.plist** de la aplicación para evitar un crash (**EXC\_BAD\_ACCESS**) en tiempo de ejecución.
{% endhint %}

```xml
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
```

## Controladores disponibles

<table data-header-hidden><thead><tr><th width="184.63671875"></th><th></th></tr></thead><tbody><tr><td><strong>Controlador</strong></td><td><strong>Descripción</strong></td></tr><tr><td>PhingersController</td><td>Controlador principal de captura de huellas</td></tr></tbody></table>

## Lanzamiento simplificado

```swift
let controller = PhingersController(data: phingersConfigurationData, output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)

```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *PhingersConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```swift
static var phingersConfiguration: PhingersConfigurationData{
   var configPhingers = PhingersConfigurationData()
   configPhingers.reticleOrientation = .LEFT
   configPhingers.fingerFilter = .SLAP
   return configPhingers
}
```

Las diferentes orientaciones son:

* LEFT
* RIGHT

Los diferentes filtros son:

* SLAP
* ALL\_4\_FINGERS\_ONE\_BY\_ONE
* ALL\_5\_FINGERS\_ONE\_BY\_ONE
* INDEX\_FINGER
* MIDDLE\_FINGER
* RING\_FINGER
* LITTLE\_FINGER
* THUMB\_FINGER

## Recepción del resultado <a href="#id-7-recepcion-del-resultado" id="id-7-recepcion-del-resultado"></a>

Los controllers devolverán la información necesaria en formato SdkResult.

### Recepción de errores <a href="#id-71-recepcion-de-errores" id="id-71-recepcion-de-errores"></a>

En la parte del error, dispondremos de la clase común *ErrorType:*

* PHG\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* PHG\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* PHG\_EMPTY\_LICENSE: El String de licencia está vacío.
* PHG\_INITIALIZATION\_ERROR: Error de inicialización.
* PHG\_INTERNAL\_ERROR: Error interno.
* PHG\_LOW\_QUALITY: Baja calidad de la imagen.
* PHG\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* PHG\_CAMERA\_PERMISSION\_DENIED: El usuario ha rechazado los permisos.
* PHG\_CAMERA\_FAILURE: Fallo de la cámara.
* PHG\_FINGERPRINT\_TEMPLATE\_IO\_ERROR: Fallo IO
* PHG\_NO\_FINGERS\_DETECTED: Error en la detección de huellas
* PHG\_TIMEOUT: Timeout en el proceso.

### Recepción de ejecución correcta - *data* <a href="#id-72-recepcion-de-ejecucion-correcta-data" id="id-72-recepcion-de-ejecucion-correcta-data"></a>

En la parte de *data*, dispondremos de la clase *PhingersResult*.

El campo *data* es variable y dependerá de qué componente se ha devuelto el resultado. En el caso de este componente, los campos devueltos son los siguientes:

#### **Fingers**

**position**

Devuelve un entero que representa el elemento capturado. Este valor se establece según las instrucciones del NIST\_POS\_CODE.

**displayImage**

Contiene la imagen procesada.

**wsq**

La huella dactilar en formato WSQ.

**minutiaesNumber**

Devuelve el número de minucias encontradas en la captura biométrica.

**quality**

Entero que representa la calidad del elemento procesado.

**nistQuality**

Entero que representa la calidad del elemento procesado usando los estándares NIST.

**nist2Quality**

Entero que representa la calidad del elemento procesado usando una versión alternativa de los estándares NIST.

**livenessScore**

Contiene un valor del indicador de confianza en la captura.

**template**

Contiene la template generada.

#### **SlapImages**

**position**

Devuelve un entero que representa el elemento capturado. Este valor se establece según las instrucciones del NIST\_POS\_CODE.

**image**

Contiene la imagen procesada.

**livenessScore**

Contiene un valor del indicador de confianza en la captura.

## Información avanzada

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *PhingersConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

**reticleOrientation**

Configura qué mano se va a proceder a capturar. Los valores permitidos son:

* **LEFT**: Activa la captura de los dedos de la mano **izquierda**.
* **RIGHT**: Activa la captura de los dedos de la mano **derecha**.

**fingerFilter**

Configura el modo de detección de huellas dactilares que se usará durante la captura. Los valores permitidos son:

* **INDEX\_FINGER**: Configura la captura con el dedo **índice**.
* **MIDDLE\_FINGER**: Configura la captura con el dedo **corazón**.
* **RING\_FINGER**: Configura la captura con el dedo **anular**.
* **LITTLE\_FINGER**: Configura la captura con el dedo **meñique**.
* **THUMB\_FINGER**: Configura la captura con el dedo **pulgar**.
* **SLAP**: Configura la captura de los **cuatro** dedos con una solo foto.
* **ALL\_4\_FINGERS\_ONE\_BY\_ONE**: Configura la captura de los **cuatro** dedos haciendo una foto por cada uno de ellos.
* **ALL\_5\_FINGERS\_ONE\_BY\_ONE**: Configura la captura de los **cinco** dedos haciendo una foto por cada uno de ellos.

**templateType**

Especifica la plantilla con la que se devolverá la huella dactilar en el resultado. El enumerado ***TemplateType*** tiene los siguientes valores posibles:

* **ISO\_TEMPLATE**: Este template hace referencia al estandar **ISO/IEC 19794-4**.
* **NIST\_TEMPLATE**: Este template hace referencia al estandar NIST.
* **NIST\_TF\_TEMPLATE**: **Este es el valor por defecto.** Este template hace referencia a una variante del estandar NIST que facilita el procesado y evaluación de la muestra.

**extractionTimeout**

Establece el tiempo máximo que se puede realizar la lectura.

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

**showTutorial**

Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**vibrationEnabled**

Si se le da valor true, se activa la vibración en errores y si la respuesta del widget es OK.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso.

**livenessThreshold**

Configura el umbral de **liveness** del detector de huellas. Sustituye al antiguo parámetro único **`threshold`** (desde **2.8.1**). **Valor por defecto: 0.9.**

**detectorThreshold**

Configura el umbral del **detector** de huellas. Sustituye al antiguo parámetro único **`threshold`** (desde **2.8.1**). **Valor por defecto: 0.9.**

{% hint style="warning" %}
En versiones **2.8.0** y anteriores existía un único parámetro **`threshold`** (por defecto **0.7**). Al actualizar a **2.8.1**, sustitúyelo por **`livenessThreshold`** y **`detectorThreshold`** (por defecto **0.9**).
{% endhint %}

**enableFlash**

Activa el flash durante la captura. **Valor por defecto: `false`.** Desde **2.8.1**, el flash también puede activarse de forma automática si el proceso detecta **poca luz** en la imagen para mejorar el proceso de captura, aunque el parámetro esté en `false`.

**showEllipses**

Dibuja una elipsa durante la captura cuando se detecta una posible huella.

**cropWidth & cropHeight**

Indica un ancho y alto para realizar un recorte de la captura.

**showPreviousFingerSelector**

Indica si se muestra o no la pantalla "showPreviousFingerSelector".

**fingerSelectorHandOrientation**

Indica qué opciones de mano se mostrarán en la pantalla `PreviousFingerSelectorView`.

**fingerSelectorOptions**

Indica qué opciones de dedos se mostrarán en la pantalla `PreviousFingerSelectorView`.

## Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse sobrescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***VoiceOver***.

```xml
<!-- Previous Tip -->
    <string name="phingers_widget_tip_title">Captura de huellas</string>
    <string name="phingers_widget_tip_message">Coloca tu dedo dentro de la marca</string>
    <string name="phingers_widget_tip_message_alt">Coloca tu dedo dentro de la marca</string>
    <string name="phingers_widget_tip_button">Comenzar</string>
    <string name="phingers_widget_tip_button_alt">Comenzar captura de huellas</string>
    <string name="phingers_widget_tip_close_button_alt">Volver</string>
    <string name="phingers_widget_tip_info_button_alt">Ver consejos</string>
    <string name="phingers_widget_tip_anim_desc">Animación de instrucciones para la captura de huella</string>
    <!-- Previous Tip (tipos específicos) -->
    <string name="phingers_widget_tip_title_left_slap">Huellas mano izquierda</string>
    <string name="phingers_widget_tip_message_left_slap">Junta tus dedos. Acerca o aleja la mano hasta que se enfoquen tus huellas.</string>
    <string name="phingers_widget_tip_title_right_slap">Huellas mano derecha</string>
    <string name="phingers_widget_tip_message_right_slap">Junta tus dedos. Acerca o aleja la mano hasta que se enfoquen tus huellas.</string>
    <string name="phingers_widget_tip_title_left_finger">Huellas mano izquierda</string>
    <string name="phingers_widget_tip_message_left_finger">Enfoca el dedo índice en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <string name="phingers_widget_tip_title_right_finger">Huellas mano derecha</string>
    <string name="phingers_widget_tip_message_right_finger">Enfoca el dedo índice en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <string name="phingers_widget_tip_title_thumb">Huella dedo pulgar</string>
    <string name="phingers_widget_tip_message_thumb">Enfoca el dedo pulgar en el recuadro. Acerca o aleja el dedo hasta que se enfoque tu huella.</string>
    <!-- Selector de dedos -->
    <string name="phingers_widget_selector_hand_question">¿Qué mano utilizarás?</string>
    <string name="phingers_widget_selector_hand_left">Izquierda</string>
    <string name="phingers_widget_selector_hand_right">Derecha</string>
    <string name="phingers_widget_selector_secondary_question">¿Qué huellas quieres escanear?</string>
    <string name="phingers_widget_selector_option_index">Dedo índice</string>
    <string name="phingers_widget_selector_option_middle">Dedo corazón</string>
    <string name="phingers_widget_selector_option_ring">Dedo anular</string>
    <string name="phingers_widget_selector_option_little">Dedo meñique</string>
    <string name="phingers_widget_selector_option_thumb">Dedo pulgar</string>
    <string name="phingers_widget_selector_option_all4">4 dedos (índice, corazón, anular y meñique)</string>
    <string name="phingers_widget_selector_option_all4_sequence">4 dedos (uno a uno)</string>
    <string name="phingers_widget_selector_option_all5_sequence">5 dedos (uno a uno)</string>
    <string name="phingers_widget_selector_primary_button">Continuar</string>
    <!-- Capture -->
    <string name="phingers_widget_capture_close_button_alt">Volver</string>
    <!-- Tutorial -->
    <string name="phingers_widget_tutorial_message_1">Coloca tu cara en el centro y mira de frente a la cámara.</string>
    <string name="phingers_widget_tutorial_message_2">Retira cualquier elemento que cubra tu cara.</string>
    <string name="phingers_widget_tutorial_message_3">Busca un entorno bien iluminado, sin sombras sobre tu rostro.</string>
    <string name="phingers_widget_tutorial_message_1_anim_desc">La foto se realiza cuando la persona está en el centro.</string>
    <string name="phingers_widget_tutorial_message_2_anim_desc">Una persona se quita las gafas de sol y se retira el pelo de los ojos.</string>
    <string name="phingers_widget_tutorial_message_3_anim_desc">La imagen aparece oscura y una persona enciende la luz.</string>
    <string name="phingers_widget_tutorial_close_button_alt">Volver al tutorial previo</string>
    <!-- Confirmation -->
    <string name="phingers_widget_image_captured">Imagen capturada</string>
    <string name="phingers_widget_confirmation_message">¿Tu foto se ve de forma clara y nítida?</string>
    <string name="phingers_widget_confirmation_retry">Reintentar</string>
    <string name="phingers_widget_confirmation_continue">Continuar</string>

    <!-- Camera status (ES) -->
    <string name="phingers_widget_camera_status_position_fingers">Coloca tus dedos dentro de la marca</string>
    <string name="phingers_widget_camera_status_processing">Procesando…</string>
    <string name="phingers_widget_camera_status_too_far">Acerca la mano</string>
    <string name="phingers_widget_camera_status_too_close">Aleja la mano</string>
    <string name="phingers_widget_camera_status_low_focus">Mueve el dedo para enfocar</string>
    <string name="phingers_widget_camera_status_good_focus">Mantén el dedo quieto</string>
    <string name="phingers_widget_camera_status_wrong_angle">Coloca el dedo en vertical</string>
    <string name="phingers_widget_camera_status_too_few">No se ha detectado el dedo</string>
    <string name="phingers_widget_camera_status_too_many">Varios dedos detectados</string>
    <string name="phingers_widget_camera_status_wrong_hand_left">Debes poner el dedo de la mano izquierda</string>
    <string name="phingers_widget_camera_status_wrong_hand_right">Debes poner el dedo de la mano derecha</string>
    <string name="phingers_widget_camera_status_error">Error en la captura</string>
    <string name="phingers_widget_camera_status_timeout">Tiempo de captura agotado</string>
    <string name="phingers_widget_camera_status_success">¡Huella capturada!</string>
    <string name="phingers_widget_camera_status_keep_hand_steady">Mantén tu mano firme</string>
    <string name="phingers_widget_timeout_desc">La captura ha superado el tiempo. Inténtalo de nuevo.</string>

    <!-- Dynamic finger hint (ES) -->
    <!-- %1$s = lado (izquierdo/derecho), %2$s = dedo (índice/medio/anular/meñique/pulgar) -->
    <string name="phingers_widget_hint_place_finger_mark">Coloca tu %2$s %1$s dentro de la marca</string>
    <string name="phingers_widget_side_left">izquierdo</string>
    <string name="phingers_widget_side_right">derecho</string>
    <string name="phingers_widget_finger_index">índice</string>
    <string name="phingers_widget_finger_middle">medio</string>
    <string name="phingers_widget_finger_ring">anular</string>
    <string name="phingers_widget_finger_little">meñique</string>
    <string name="phingers_widget_finger_thumb">pulgar</string>
```

De este modo, si se desea modificar por ejemplo el texto “*Comenzar*” de la clave `phingers_widget_tip_button` para el idioma **es**, se deberá ir al archivo **Localizable.strings** de la carpeta **es.lproj** si es que existe (si no, se deberá crear) y ahí, añadir:

`"phingers_widget_tip_button"="Start";`

Si un mensaje no se especifica en el fichero del idioma, este se rellenará con el mensaje por defecto.

## Animaciones

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta Resources de la aplicació.

```
phingers_anim_left_finger
phingers_anim_left
phingers_anim_right_finger
phingers_anim_right
phingers_anim_thumb_right
phingers_anim_thumb_left
```


# Captura de voz - VoiceID

Este componente necesita una versión mínima de iOS13

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

El *Componente* tratado en el documento actual recibe el nombre de ***Voice Component***. Éste se encarga de realizar la captura de voz del usuario y la posterior extracción de las plantillas correspondientes. Sus principales funcionalidades son las siguientes:

* Entrada de cierto número de frases para posteriormente leer cada una en un paso.
* Gestión interna del micrófono.
* Gestión de permisos.
* Análisis de los silencios.
* Análisis del progreso.
* Asistente en los procesos de captura.
* Generación de las plantillas con las características de la voz y puntuaciones.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## **Dependencias**

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la **SDKMobile**.

### Cocoapods

```sh
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente actual deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```sh
pod 'FPHISDKVoiceIDComponent', '~> $VERSION'
```

* Una vez instaladas las dependencias, se podrá hacer uso de las diferentes funcionalidades del componente.

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar el componente de Selphid deberá incluirse en los módulos del proyecto:

<pre class="language-swift"><code class="lang-swift"><strong>//HTTPS
</strong>https://github.com/facephi-clienters/SDK-VoicePackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-VoicePackage-SPM.git
</code></pre>

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist**:

```
Es necesario permitir el uso del micrófono (NSMicrophoneUsageDescription - Privacy - Microphone Usage Description)
```

## Controladores disponibles <a href="#id-4-controladores-disponibles" id="id-4-controladores-disponibles"></a>

| **Controlador** | **Descripción**                         |
| --------------- | --------------------------------------- |
| VoiceController | Controlador principal de captura de voz |

## Lanzamiento simplificado

```swift
let controller = VoiceController(data: voiceConfigurationData, output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

## Configuración básica

Para lanzar el componente actual, se deberá crear un objeto *VoiceConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```swift
static var voiceIDConfiguration: VoiceConfigurationData {
    let configVoiceID = VoiceConfigurationData(
            phrases: ["Tu nombre completo y tu dirección",
                      "Tu número de documento con letra"])
    return configVoiceID
}
```

Se puede editar el listado de frases que se van a mostrar al usuario.

## Recepción del resultado <a href="#id-7-recepcion-del-resultado" id="id-7-recepcion-del-resultado"></a>

Los controllers devolverán la información necesaria en formato SdkResult.

### Recepción de errores <a href="#id-71-recepcion-de-errores" id="id-71-recepcion-de-errores"></a>

En la parte del error, dispondremos del enumerado común *ErrorType*:

* VOC\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VOC\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VOC\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VOC\_EMPTY\_LICENSE: El String de licencia está vacío
* VOC\_INITIALIZATION\_ERROR: Error de inicialización
* VOC\_INTERNAL\_LICENSE\_ERROR: Error interno relacionado con la licencia
* VOC\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VOC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VOC\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* VOC\_TIMEOUT: Timeout en el proceso

### Recepción de ejecución correcta - *data* <a href="#id-72-recepcion-de-ejecucion-correcta-data" id="id-72-recepcion-de-ejecucion-correcta-data"></a>

En la parte de *data*, dispondremos de la clase *VoiceResult*.

El campo *data* es variable y dependerá de qué componente se ha devuelto el resultado. En el caso de este componente, los campos devueltos son los siguientes:

**audios**

Contiene un listado de audios capturados en formato ByteArray.

**tokenizedAudios**

Contiene el listado de audios capturados en formato tokenizado de Facephi.

## Información avanzada

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-5-configuracion-del-componente" id="id-5-configuracion-del-componente"></a>

Para configurar el componente actual, una vez inicializado, se deberá crear un objeto

*VoiceConfigurationData* y pasarlo como parámetro al SDKController durante el lanzamiento del componente.

En el siguiente apartado se mostrarán los campos que forman parte de esta clase y para qué se utiliza cada uno de ellos.

**phrases**

Indica la/las frases necesarias para capturar.

**vibrationEnabled**

Indica la activación de la vibración cuando el widget termine satisfactoriamente.

**showTutorial**

Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**extractionTimeout**

Establece el tiempo máximo que se puede realizar la captura.

**showDiagnostic**

Mostrar pantallas de diagnóstico al final del proceso

**enableQualityCheck**

Activa o desactiva la comprobación de calidad del audio. Se recomienda tenerla siempre activa.

**showPreviousTip**

Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.

## Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos

Los textos pueden ser customizados sobreescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***voice over***.

| **Name**                                               | **Value**                                                                   |
| ------------------------------------------------------ | --------------------------------------------------------------------------- |
| voice\_component\_success\_records\_message            | %d/%d grabaciones exitosas                                                  |
| voice\_component\_read\_message                        | Di en voz alta:                                                             |
| voice\_component\_speech\_message                      | Habla claro y cercano al micrófono                                          |
| voice\_component\_speech\_noisy\_message               | Hay demasiado ruido. Intenta estar en un entorno silencioso.                |
| voice\_component\_success\_message                     | Grabación registrada                                                        |
| voice\_component\_phrase\_generic\_error\_message      | Por favor, repite la frase.                                                 |
| voice\_component\_phrase\_long\_silence\_message       | Habla durante 2 segundos o más.                                             |
| voice\_component\_phrase\_long\_reverberation\_message | Demasiado eco. Prueba en otro entorno.                                      |
| voice\_component\_tip\_title                           | Reconocimiento de voz                                                       |
| voice\_component\_tip\_message                         | Habla claro y en voz alta.\n\nAsegúrate de estar en un entorno silencioso   |
| voice\_component\_tip\_button                          | COMENZAR                                                                    |
| voice\_component\_exit\_alert\_accept                  | Aceptar                                                                     |
| voice\_component\_exit\_alert\_cancel                  | Cancel                                                                      |
| voice\_component\_exit\_alert\_question                | ¿Seguro que finalizar el proceso?                                           |
| voice\_component\_multiple\_speakers\_error\_message   | Se ha detectado voces de fondo. Asegúrate de estar en un entorno silencioso |
| voice\_component\_short\_recorded\_speech\_message     | La grabación ha sido muy corta.                                             |
| voice\_component\_quality\_check\_error\_message       | La calidad del audio es insuficiente.                                       |
| voice\_component\_close\_button\_alt                   | Cerrar                                                                      |
| voice\_component\_logo\_alt                            | Logo                                                                        |
| voice\_component\_tip\_anim\_alt                       |                                                                             |
| voice\_component\_timeout\_title                       | Tiempo superado                                                             |
| voice\_component\_timeout\_desc                        | No hemos podido identificarte. Inténtalo de nuevo.                          |

De este modo, si se desea modificar por ejemplo el texto “*COMENZAR*” de la clave `voice_component_tip_button_message` para el idioma **es**, se deberá ir al archivo **Localizable.strings** de la carpeta **es.lproj** si es que existe (si no, se deberá crear) y ahí, añadir:

```xml
"voice_component_success_records_message" = "%d/%d grabaciones exitosas";
"voice_component_read_message" = "Di en voz alta:";
"voice_component_speech_message" = "Habla claro y cercano al micrófono";
"voice_component_speech_noisy_message" = "Hay demasiado ruido. Intenta estar en un entorno silencioso.";
"voice_component_success_message" = "Grabación registrada";
"voice_component_phrase_generic_error_message" = "Por favor, repite la frase.";
"voice_component_phrase_long_silence_message" = "Habla durante 2 segundos o más.";
"voice_component_phrase_long_reverberation_message" = "Demasiado eco. Prueba en otro entorno.";
"voice_component_tip_title" = "Reconocimiento de voz";
"voice_component_tip_message" = "Habla claro y en voz alta.\n\nAsegúrate de estar en un entorno silencioso";
"voice_component_tip_button" = "COMENZAR";
"voice_component_exit_alert_accept"="Aceptar";
"voice_component_exit_alert_cancel"="Cancelar";
"voice_component_exit_alert_question" = "¿Seguro que quiere finalizar el proceso?";
"voice_component_multiple_speakers_error_message" = "Se ha detectado voces de fondo. Asegúrate de estar en un entorno silencioso";
"voice_component_short_recorded_speech_message" = "La grabación ha sido muy corta.";
"voice_component_quality_check_error_message" = "La calidad del audio es insuficiente.";
"voice_component_close_button_alt" = "Cerrar";
"voice_component_logo_alt" = "Logo";
"voice_component_tip_anim_alt"="Animación en la que aparece una persona que sujeta el teléfono delante de su cara y habla directamente dirigiéndose a él. Antes de empezar, si usas lector de pantalla, utiliza auriculares.";
"voice_component_timeout_title"="Tiempo superado";
"voice_component_timeout_desc"="No hemos podido identificarte. Inténtalo de nuevo.";

```

Si un mensaje no se especifica en el fichero del idioma, este se rellenará con el mensaje por defecto.

### Animaciones <a href="#id-84-animaciones" id="id-84-animaciones"></a>

Las animaciones a usar se inicializan similarmente en la variable animations con un diccionario, teniendo como valor una string con el nombre de la animación que se encuentre en xcassets que se desee usar.

```
case voice_anim_enroll
case voice_anim_enroll_error
case voice_anim_enroll_ok
case voice_anim_intro
```


# Captura de NFC

Este componente necesita una versión mínima de iOS13

### Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

El *Componente* tratado en el documento actual recibe el nombre de ***NFC Component***. Éste se encarga de realizar la lectura de nfc de documentos de identidad y pasaportes. Sus principales funcionalidades son las siguientes:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencias <a href="#id-21-dependencias-requeridas-para-la-integracion" id="id-21-dependencias-requeridas-para-la-integracion"></a>

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

### **Cocoapods**

* Las dependencias obligatorias que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```
pod 'FPHISDKMainComponent', '~> $SDK_VERSION'
```

* Para instalar el componente de NFC deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```
pod 'FPHISDKNFCComponent', '~> $NFC_VERSION'
```

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git

```

* Para instalar el componente de NFC deberá incluirse en los módulos del proyecto:

```
//HTTPS
https://github.com/facephi-clienters/SDK-NFC_component-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-NFC_component-SPM.git
```

## Controladores disponibles <a href="#id-4-controladores-disponibles" id="id-4-controladores-disponibles"></a>

| **Controlador** | **Descripción**                      |
| --------------- | ------------------------------------ |
| NFCController   | Controlador principal de lectura NFC |

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura:

```swift
let controller = NfcController(data: nfcConfigurationData, viewController: viewController,  output: { sdkResult in
        // Do whatever with the result
        ...
    }, stateDelegate: nil)
SDKController.shared.launch(controller: controller)
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *NFCConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```swift
static var nfcConfiguration: NfcConfigurationData {
        return NfcConfigurationData(documentNumber: // Num soporte,
                                    birthDate: // "dd/MM/yyyy",
                                    expirationDate: // "dd/MM/yyyy")
}
```

Los datos necesarios son los del documento que se va a capturar.

## Recepción del resultado <a href="#id-7-recepcion-del-resultado" id="id-7-recepcion-del-resultado"></a>

Los controllers devolverán la información necesaria en formato SdkResult.

### Recepción de errores <a href="#id-71-recepcion-de-errores" id="id-71-recepcion-de-errores"></a>

En la parte del error, **internamente** disponemos de la clase NFCPassportReaderError. Este enumerado contiene muchos errores específicos que no aportan información útil si son devueltos al integrador, por lo que son transformados a un tipo más simple (**ErrorType**):

* NFC\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso.
* NFC\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta.
* NFC\_EMPTY\_LICENSE: El String de licencia está vacío.
* NFC\_EXTRACT\_DATA\_ERROR: Error en los datos extraídos.
* NFC\_INITIALIZATION\_ERROR: Error de inicialización.
* NFC\_LAST\_COMMAND\_EXPECTED: Error en el comando de finalización
* NFC\_ERROR: Error general
* NFC\_ERROR\_DATA: Error en los datos de entrada
* NFC\_ERROR\_DISABLED: NFC deshabilitado
* NFC\_ERROR\_ILLEGAL\_ARGUMENT: NFC con un tag incorrecto
* NFC\_ERROR\_IO: Error de entrada/salida
* NFC\_ERROR\_NOT\_SUPPORTED: NFC no soportado
* NFC\_ERROR\_TAG\_LOST: Conexión perdida
* NFC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso.
* NFC\_TIMEOUT: Timeout en el proceso.

**NOTA**: `NFC_INVALID_MRZ_KEY` *implica que la conexión no se ha podido establecer por culpa de que los datos de entrada de la configuración (documentNumber, birthDate, expiryDate) no son correctos. Todos los lanzamientos de lectura para ese NFC fallarán mientras no se inicialice un NFCController nuevo con los datos correctos.*

### Recepción de ejecución correcta - *data* <a href="#id-72-recepcion-de-ejecucion-correcta-data" id="id-72-recepcion-de-ejecucion-correcta-data"></a>

En la parte de *data*, dispondremos de la clase *NfcResult*.

```
public class NfcResult {
    public let nfcRawData: NfcRawData
    public private(set) var nfcDocumentInformation: NfcDocumentInformation?
    public private(set) var nfcPersonalInformation: NfcPersonalInformation?
    public let nfcImages: NfcImages?
    public let nfcSecurityData: NfcSecurityData
    public private(set) var nfcValidations: NfcValidations?
}

extension NfcResult {
    public var personalData: [String: String]
    {
        ...
    }
}
```

En el caso de este componente, los campos devueltos son los siguientes:

**nfcRawData**

Información obtenida por cada tipo de dato en formato crudo.

**nfcDocumentInformation**

Información obtenida del documento ordenada por:

* type
* documentNumber
* issuer
* expirationDate
* mrzString

**nfcPersonalInformation**

Información obtenida del documento ordenada por:

* name
* surname
* address
* nationality
* personalNumber
* birthdate
* placeOfBirth
* gender

**nfcImages**

Información de imágenes obtenida del documento ordenada por:

* facialImage
* fingerprintImage
* signatureImage

**nfcSecurityData**

Información de datos de seguridad del documento ordenada por:

* ldsVersion
* dataGroupsHashes
* dataGroupsRead
* documentSigningCertificateData
* issuerSigningCertificateData

**nfcValidations**

Información de las validaciones del documento ordenada por:

* accessProtocol
* activeAuthenticationSupported
* activeAuthenticationValidation
* chipAuthenticationValidation
* dataGroupsHashesValidation
* documentSigningValidation
* issuerSigningValidation

**personalData**

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

## Información avanzada

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-51-class-nfcconfigurationdata" id="id-51-class-nfcconfigurationdata"></a>

Para lanzar el componente actual, se deberá crear un objeto *NFCConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

**documentNumber**

Indica el número de documento o número de soporte dependiendo del documento a realizar la lectura.

Éste campo es obligatorio.

**birthDate**

Indica la fecha de nacimiento que aparece en el documento ("dd/MM/yyyy").

Éste campo es obligatorio.

**expirationDate**

Indica la fecha de expiración que aparece en el documento ("dd/MM/yyyy").

Éste campo es obligatorio.

**extractionTimeout**

Establece el tiempo máximo que se puede realizar la lectura.

**showTutorial**

Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.

**vibrationEnabled**

iOS no permite añadir vibración mientras se hacen lecturas de NFC.

**enableDebugMode**

Activación del modo depuración del componente.

**skipPace**

Indica que solo se desea realizar la lectura BAC de NFC. Es una lectura con información más simple y rápida que permite la lectura de más variedad de documentos.

**showDiagnostic**

Si se le da valor true, al producirse un error o una falta de permisos, el sdk mostrará una pantalla con el error devuelto por el widget.

**issuer**

Indicamos el pais de origen del documento a leer.

**documentType**

Indica el tipo de documento que se va a leer: - ID\_CARD - PASSPORT - FOREIGN\_CARD

**activeAuthenticationChallenge**

Este parámetro permite inyectar un desafío personalizado que puede comprobarse posteriormente para proteger contra ataques de repetición.

**onlyPACE**

Si es verdadero, solo detectará documentos PACE/SAC. Disponible únicamente a partir de iOS ≥ 16. Requiere la cadena PACE en el archivo de *entitlements*.

**tagConnectionLostTimer**

Antes existía un único temporizador que podía abarcar más de una petición cuando la respuesta era grande.

## Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos

Los textos pueden ser customizados sobreescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***voice over***.

| **Name**                                                   | **Value**                                                                                          |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| nfc\_component\_start\_message                             | \nDesliza el documento\nhasta que el dispositivo lo detecte\n                                      |
| nfc\_component\_reading\_face\_message                     | Extrayendo imagen de la cara.                                                                      |
| nfc\_component\_reading\_images\_message                   | Extrayendo imágenes.                                                                               |
| nfc\_component\_reading\_document\_message                 | Extrayendo los datos del documento.                                                                |
| nfc\_component\_error\_retrieving\_document\_data\_message | Ha ocurrido un error durante la captura de los datos del documento                                 |
| nfc\_component\_read\_successful\_title                    | NFC leído exitosamente                                                                             |
| nfc\_component\_error                                      | ¡Ups! El NFC no ha podido ser leído                                                                |
| text\_error\_tag\_connection\_lost                         | Lectura interrumpida. Vuelve a poner el documento en la parte superior.                            |
| text\_error\_tag\_connection\_lost\_timer                  | Hubo un error en la lectura. Por favor, cancela para reiniciar el proceso.                         |
| nfc\_component\_timeout\_desc                              | Has excedido el tiempo de lectura de NFC. Por favor intenta de nuevo                               |
| text\_chip\_duplicated\_session\_error                     | El proceso de captura se ha duplicado, por favor vuelva a intentarlo tras desaparecer este mensaje |
| text\_chip\_security\_serial\_number\_title                | Número de serie                                                                                    |
| text\_chip\_security\_algorithm\_sign\_title               | Algoritmo de firma                                                                                 |
| text\_chip\_security\_algorithm\_public\_key\_title        | Algoritmo de clave pública                                                                         |
| text\_chip\_security\_certificated\_impress\_title         | Impresión de certificado                                                                           |
| text\_chip\_security\_editor\_title                        | Editor                                                                                             |
| text\_chip\_security\_subject\_title                       | Sujeto                                                                                             |
| text\_chip\_security\_valid\_from\_title                   | Válido desde                                                                                       |
| text\_chip\_security\_valid\_still\_title                  | Válido hasta                                                                                       |
| text\_loading\_optional\_description                       | Leyendo, por favor, no mueva el documento                                                          |
| icon\_loading\_filled\_circle                              | 🟢                                                                                                 |
| icon\_loading\_void\_circle                                | ⚪️                                                                                                 |
| nfc\_component\_end\_confirmation\_title                   | Finalizar                                                                                          |
| nfc\_component\_end\_confirmation\_message                 | ¿Seguro que finalizar el proceso?                                                                  |
| nfc\_component\_cancel                                     | Cancelar                                                                                           |
| nfc\_component\_agree                                      | Aceptar                                                                                            |
| nfc\_component\_tutorial                                   | Pon **en contacto** el documento con la parte trasera de tu dispositivo.                           |
| nfc\_component\_tutorial\_iphone\_15                       | Pon **en contacto** el documento con la parte delantera de tu dispositivo.                         |
| text\_tutorial\_nfc\_title                                 | Lectura de NFC                                                                                     |
| text\_tutorial\_nfc\_button\_ok                            | COMENZAR                                                                                           |
| text\_tutorial\_nfc\_button\_tip                           | MIRA ESTOS CONSEJOS                                                                                |
| nfc\_component\_tutorial\_title                            | Escanear NFC                                                                                       |
| nfc\_component\_tutorial\_button\_disabled                 | PREPARANDO NFC                                                                                     |
| nfc\_component\_tutorial\_1                                | Cuando pasamos una tarjeta por un sensor, hay un intercambio de información llamado NFC.           |
| nfc\_component\_tutorial\_2                                | En tu móvil, el sensor está en la zona marcada. Aquí deberás juntar tu documento.                  |
| nfc\_component\_tutorial\_3                                | Para una mejor lectura, quita la funda de tu móvil.                                                |
| nfc\_component\_tutorial\_3\_pass                          | Mantén **cerrado** el pasaporte para hacer la lectura.                                             |
| nfc\_component\_next                                       | SIGUIENTE                                                                                          |
| nfc\_component\_previous                                   | ANTERIOR                                                                                           |
| nfc\_component\_more\_info\_finish                         | FINALIZAR                                                                                          |
| diagnostic\_tag\_connection\_lost\_title                   | La lectura no finalizó                                                                             |
| diagnostic\_tag\_connection\_lost\_description             |                                                                                                    |

De este modo, si se desea modificar por ejemplo el texto “*COMENZAR*” de la clave `text_tutorial_nfc_button_ok` para el idioma **es-MX**, se deberá ir al archivo **Localizable.strings** de la carpeta **es-MX.lproj** si es que existe (si no, se deberá crear) y ahí, añadir:

`"text_tutorial_nfc_button_ok"="EMPEZAR";`

Si un mensaje no se especifica en el fichero del idioma, este se rellenará con el mensaje por defecto.

### Animaciones <a href="#id-84-animaciones" id="id-84-animaciones"></a>

Las animaciones a usar se inicializan similarmente en la variable animations con un diccionario, teniendo como valor una string con el nombre de la animación que se encuentre en xcassets que se desee usar.

```
case nfc_anim_tuto_id_male
case nfc_anim_tuto_id_male_iphone_15
case nfc_anim_tuto_id_female
case nfc_anim_tuto_passport
case nfc_anim_tuto_1
case nfc_anim_tuto_2
case nfc_anim_tuto_2_iphone_15
case nfc_anim_tuto_3
case nfc_anim_tuto_3_pass
```

<br>


# Subida de ficheros y gestión de QR - Capture

Este componente necesita una versión mínima de iOS14

## Introducción

La subida de ficheros y la lectura y generación de códigos QR se realizan con el ***Capture Component***.

Este componente permite la subida de documentos realizando una foto con la cámara del dispositivo o desde la galería. FileUploader, QR Reader y QR Generator usan el widget KMP **FPHICaptureWidget** (no hay UI nativa propia). Sus principales funcionalidades son:

* Subida de documentos mediante cámara o galería.
* Lectura de códigos QR.
* Generación de códigos QR.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

***

## Dependencias

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (Widgets), éstos deberán eliminarse por completo antes de la instalación de los componentes de la **SDKMobile**.

### **Cocoapods**

* Actualmente las librerías de Facephi se distribuyen de forma remota a través de diferentes gestores de dependencias, en este caso Cocoapods. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente de Captura deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```swift
pod 'FPHISDKCaptureComponent', '~> $VERSION'
```

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar el componente de Selphid deberá incluirse en los módulos del proyecto:

<pre class="language-swift"><code class="lang-swift"><strong>//HTTPS
</strong>https://github.com/facephi-clienters/SDK-CapturePackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-CapturePackage-SPM.git
</code></pre>

***

## Configuración del Info.plist (widget KMP)

{% hint style="warning" %}
**IMPORTANTE:** El componente **Capture** utiliza el widget KMP **FPHICaptureWidget** y ficheros de recursos. Es imprescindible añadir la siguiente clave en el **Info.plist** de la aplicación para evitar un crash (**EXC\_BAD\_ACCESS**) en tiempo de ejecución.
{% endhint %}

```xml
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
```

***

## Controladores disponibles <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**        | **Descripción**                           |
| ---------------------- | ----------------------------------------- |
| FileUploaderController | Controlador para la captura de documentos |
| QrReaderController     | Controlador para la captura de QRs        |
| QrGeneratorController  | Controlador para la generación de QRs     |

***

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura de documentos:

```swift
let controller = FileUploaderController(data: fileUploaderConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

Lanzamiento de la captura de QR:

```swift
let controller = QrReaderController(data: qrReaderConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

Lanzamiento de la generación de QR:

```swift
let controller = QrGeneratorController(data: qrGeneratorConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

***

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para los controladores de captura de componentes y captura de QR se puede generar la configuración con los parámetros por defecto. Para el caso de la geneación del QR se necesitará el texto que se va a utilizar:

```
QrGeneratorConfiguration(source:"QR text")
```

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SdkResult.

* errorType
* finishStatus
* data

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'CaptureError'.

Listado de errores:

* CAP\_ACTIVITY\_RESULT\_MSG\_ERROR: El resultado devuelto por la actividad es incorrecto o no contiene la información necesaria para continuar.
* CAP\_APPLICATION\_CONTEXT\_ERROR: El contexto de aplicación requerido es nulo o no válido, impidiendo inicializar correctamente el módulo de captura.
* CAP\_CAMERA\_ERROR: Ha ocurrido un error interno relacionado con la cámara del dispositivo (fallo de apertura, inicialización o captura).
* CAP\_CAMERA\_PERMISSION\_DENIED: El usuario ha denegado los permisos necesarios para acceder a la cámara.
* CAP\_CANCEL\_BY\_USER: El usuario ha cancelado manualmente el proceso de captura.
* CAP\_CANCEL\_LAUNCH: El proceso ha sido cancelado de forma general por el SDK o por una acción externa.
* CAP\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es válida, ha expirado o no coincide con la configuración requerida.
* CAP\_EMPTY\_LICENSE: La cadena de licencia está vacía o no se ha proporcionado.
* CAP\_FETCH\_DATA\_ERROR: Se ha producido un error al obtener o procesar los datos necesarios para ejecutar el flujo. *(Incluye información adicional en el campo `error`.)*
* CAP\_FLOW\_ERROR: Se ha producido un error interno durante la ejecución del flujo de captura. *(Incluye información adicional en el campo `error`.)*
* CAP\_INITIALIZATION\_ERROR: Error al inicializar los componentes necesarios del SDK. *(Incluye información detallada en el campo `error`.)*
* CAP\_FILE\_UPLOADER\_CAPTURE\_ERROR: Error durante el proceso de subida de los archivos generados en la captura.
* CAP\_MANAGER\_NOT\_INITIALIZED: Los managers necesarios para ejecutar el proceso no han sido inicializados correctamente.
* CAP\_NO\_DATA\_ERROR: Los datos de entrada requeridos son nulos, inexistentes o insuficientes para continuar el proceso.
* CAP\_OPERATION\_NOT\_CREATED: No se ha podido crear o recuperar una operación activa necesaria para continuar. *(Incluye información detallada en el campo `error`.)*
* CAP\_QR\_CAPTURE\_ERROR: Error durante la captura o lectura del código QR.
* CAP\_QR\_GENERATION\_ERROR: Error al generar el código QR solicitado.
* CAP\_TIMEOUT: Se ha alcanzado el tiempo máximo permitido en alguna de las fases del proceso.
* CAP\_FLOW\_VIDEO\_RECORDING\_ERROR: Error durante la grabación de vídeo dentro del flujo establecido.
* CAP\_FLOW\_TRACKING\_ERROR: Error al realizar el tracking necesario para completar el flujo de captura.

### Recepción del resultado correcto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

#### **Recepción del resultado de la captura de documentos**

En la parte de SdkResult.Success - *data*, dispondremos de la clase *FileUploaderResult*.

Los campos devueltos en el resultado son los siguientes:

***capturedDocumentList***

Listado de ficheros capturados. Pueden ser imágenes o PDFs. Los campos devueltos de cada uno son:

* mimeType
* timestampMillis
* content: FileContent -> determina si es una imagen o un documento PDF. Si es una imagen también se indica si se ha capturado con la cámara o desde la galería.

```
public enum FileContent {
    case uploaderImage(UploaderImage)
    case uploaderDocument(UploaderDocument)
    
    // MARK: - Nested types
    public struct UploaderImage {
        public let image: UIImage
        public let rotationDegrees: Int
        public let source: FileUploaderSource
    }
    
    public struct UploaderDocument {
        public let frontPageImage: UIImage?
        public let bytes: Data
    }
}

public enum FileUploaderSource: String {
    case CAMERA
    case GALLERY
}
```

Por ejemplo para leer el primer elemento del array:

```
(..., output: { fileUploaderResult in
    guard fileUploaderResult.errorType == .NO_ERROR else {
        print("\(fileUploaderResult.errorType)")
        return
    }
    ...
    let firstElement = fileUploaderResult.data?.documentImages.first
    
    switch firstElement?.content {
    case .uploaderDocument(let doc):
        // Do something with the file
        break
    case .uploaderImage(let image):
        // Do something with the image
        break
    case .none:
        break
    }
})
```

#### **Recepción del resultado de la captura de QR**

En la parte de SdkResult.Success - *data*, dispondremos de la clase *QrResult*.

Los campos devueltos en el resultado son los siguientes:

***qrText***

Texto obtenido del QR

#### **Recepción del resultado de la generación de QR**

En la parte de SdkResult.Success - *data*, dispondremos de una SdkImage con el QR creado.

***

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

#### **Configuración de la captura de documentos**

Para lanzar el componente actual, se deberá crear un objeto *FileUploaderConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `vibrationEnabled`: Indica la activación de la vibración cuando el widget termine satisfactoriamente.
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.
* `showDiagnostic`: Mostrar pantallas de diagnóstico al final del proceso.
* `showPreviousTip`: Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.
* `maxScannedDocs`: Número máximo de documentos que se podrán capturar
* `allowGallery`: Se habilita el acceso a la galería para la obtención de imágenes o PDFs
* `onlyGalleryMode`: Abre el flujo directamente en modo galería, sin mostrar la captura con cámara. Por defecto `true`.
* `maxGalleryImageSizeKb`: Tamaño máximo permitido para imágenes seleccionadas desde galería, en KB. Por defecto `2048`. Si una imagen supera este límite, el componente devuelve `CAP_IMAGE_TOO_LARGE`.

#### **Configuración de la captura de QR**

Para lanzar el componente actual, se deberá crear un objeto *QrCaptureConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

* `vibrationEnabled`: Indica la activación de la vibración cuando el widget termine satisfactoriamente.
* `extractionTimeout`: Establece el tiempo máximo que se puede realizar la captura.
* `showDiagnostic`: Mostrar pantallas de diagnóstico al final del proceso.
* `showPreviousTip`: Muestra una pantalla previa al lanzamiento de la captura con información sobre el proceso a realizar y un botón para el lanzamiento.
* `showTutorial`: Indica si el componente activa la pantalla de tutorial. En esta vista se explica de forma intuitiva cómo se realiza la captura.
* `cameraShape`: Permite elegir entre una máscara cuadrada y una redonda.

***

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden personalizarse sobrescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***VoiceOver***.

```xml
<resources>
    <!-- Previous Tip -->
    <string name="capture_component_qr_tip_title">Escanea el código QR</string>
    <string name="capture_component_qr_tip_message">&lt;b&gt; Enfoca &lt;/b&gt; el código QR &lt;b&gt; dentro del recuadro &lt;/b&gt;</string>
    <string name="capture_component_qr_tip_button">Comenzar</string>
    <string name="capture_component_qr_tip_anim_desc">Animación de un teléfono móvil haciendo una foto a un código QR. En la pantalla del móvil aparece un recuadro. Cuando el código QR encaja dentro del recuadro, la aplicación hace una foto.</string>
    <string name="capture_component_qr_tutorial_1_anim_desc">Se muestra un código QR sobre un fondo blanco. Los bordes del código QR no se distinguen con claridad. Mediante una animación, el fondo cambia de color.</string>
    <string name="capture_component_qr_tutorial_2_anim_desc">Un teléfono móvil hace una foto a un código QR. El código QR aparece en horizontal, y el móvil en posición vertical. En la pantalla del móvil aparece un recuadro. Cuando el código QR encaja dentro del recuadro, la aplicación hace una foto.</string>
    <!-- Tutorial -->
    <string name="capture_component_qr_tutorial_1">Asegúrate de que el código QR tiene &lt;b&gt; luz suficiente &lt;/b&gt; y &lt;b&gt; no hay reflejos &lt;/b&gt; o destellos sobre el código.</string>
    <string name="capture_component_qr_tutorial_2">Encaja los bordes del código QR dentro del recuadro.</string>
    <!-- Process -->
    <string name="capture_component_qr_camera_message">Mantén el QR en el centro</string>
    <string name="capture_component_button_message">Capturar</string>
    <!-- Diagnostic -->
    <string name="capture_component_timeout_title">Tiempo superado</string>
    <string name="capture_component_timeout_desc">Pedimos disculpas. No se ha podido hacer la captura</string>
    <string name="capture_component_internal_error_title">Hubo un problema técnico</string>
    <string name="capture_component_internal_error_desc">Pedimos disculpas. No se ha podido hacer la captura</string>

    <!-- WIDGET -->
    <!-- Previous Tip -->
    <string name="capture_widget_tip_title">Escanear documentos</string>
    <string name="capture_widget_tip_message">Haz una foto al documento, o sube una imagen.&lt;br&gt;&lt;br&gt; Puedes escanear varios documentos antes de finalizar.</string>
    <string name="capture_widget_tip_message_alt">Haz una foto al documento, o sube una imagen. Puedes escanear varios documentos antes de finalizar.</string>
    <string name="capture_widget_tip_button">Comenzar</string>
    <string name="capture_widget_tip_button_alt">Comenzar captura de documentos</string>
    <string name="capture_widget_tip_close_button_alt">Volver</string>
    <string name="capture_widget_tip_info_button_alt">Ver consejos</string>
    <string name="capture_widget_tip_anim_desc">Animación de un teléfono móvil haciendo una foto a un documento. En la pantalla del móvil aparece un recuadro. Cuando el documento encaja dentro del recuadro, la aplicación hace una foto.</string>
    <!-- Camera -->
    <string name="capture_widget_document_camera_button_gallery">Galería</string>
    <string name="capture_widget_document_camera_button_capture">Capturar</string>
    <string name="capture_widget_document_camera_button_cancel">Cancelar captura</string>
    <string name="capture_widget_document_camera_button_finish">Finalizar</string>
    <!-- Gallery -->
    <string name="capture_widget_gallery_images">Imágenes</string>
    <string name="capture_widget_gallery_pdf">Seleccionar PDF</string>
    <string name="capture_widget_gallery_cancel">Cancelar</string>
    <!-- Confirmation -->
    <string name="capture_widget_image_captured">Imagen capturada</string>
    <string name="capture_widget_confirmation_message">¿Todos los datos se leen de forma clara y nítida?</string>
    <string name="capture_widget_confirmation_retry">NO, QUIERO REPETIR LAS FOTOGRAFÍAS</string>
    <string name="capture_widget_confirmation_continue">Sí, finalizar</string>
    <string name="capture_widget_confirmation_delete">Borrar foto</string>
    <string name="capture_widget_confirmation_image_unavailable">Vista previa no disponible</string>
    <string name="capture_widget_confirmation_no_images">No hay capturas disponibles</string>
    <string name="capture_widget_confirmation_delete_dialog_title">¿Quieres eliminar este documento?</string>
    <string name="capture_widget_confirmation_delete_dialog_message">Al eliminar este documento no vas a poder recuperarlo. Deberás realizar una nueva fotografía.</string>
    <string name="capture_widget_confirmation_delete_dialog_cancel">CANCELAR</string>
    <string name="capture_widget_confirmation_delete_dialog_confirm">ELIMINAR DOCUMENTO</string>
    <!-- Diagnostic -->
    <string name="capture_widget_timeout_title">Tiempo superado</string>
    <string name="capture_widget_timeout_desc">Pedimos disculpas. No se ha podido hacer la captura</string>
    <string name="capture_widget_internal_error_title">Hubo un problema técnico</string>
    <string name="capture_widget_internal_error_desc">Pedimos disculpas. No se ha podido hacer la captura</string>

</resources>
```

De este modo, si se desea modificar por ejemplo el texto “*Comenzar*” de la clave `capture_widget_tip_button` para el idioma **es**, se deberá ir al archivo **Localizable.strings** de la carpeta **es.lproj** si es que existe (si no, se deberá crear) y ahí, añadir:

`"capture_widget_tip_button"="Start";`

Si un mensaje no se especifica en el fichero del idioma, este se rellenará con el mensaje por defecto.

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
qr_anim_tip_1.json
qr_anim_tip_2.json
capture_anim_tip.json
```


# Videollamada - Videocall

Este componente necesita una versión mínima de iOS13

## Introducción

La videollamada se gestiona con el ***VideoCall Component***.

Este componente se encarga de gestionar la comunicación entre un usuario y un agente (videoasistencia). Sus principales procesos son:

* Gestión interna de cámaras, micro y permisos.
* Conexión con los servicios.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencias <a href="#id-21-dependencias-requeridas-para-la-integracion" id="id-21-dependencias-requeridas-para-la-integracion"></a>

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

### **Cocoapods**

* Las dependencias obligatorias que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente de Videollamada deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```
pod 'FPHISDKVideoCallComponent', '~> $VERSION'
```

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git

```

* Para instalar el componente de Videollamada deberá incluirse en los módulos del proyecto:

```
//HTTPS
https://github.com/facephi-clienters/SDK-VideoCallPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-VideoCallPackage-SPM.git
```

## Controladores disponibles <a href="#id-4-controladores-disponibles" id="id-4-controladores-disponibles"></a>

| **Controlador**     | **Descripción**                       |
| ------------------- | ------------------------------------- |
| VideoCallController | Controlador principal de videollamada |

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento:

```swift
let controller = VideoCallController(
    data: videoCallConfigurationData,
    extensionIdentifier: "com.organization.app.videocallExtension",
    output: { sdkResult in
        // Do whatever with the result
        ...
    },
    viewController: viewController)
SDKController.shared.launch(controller: controller)
```

`extensionIdentifier` debe coincidir con el **Bundle Identifier** de la **Broadcast Upload Extension** de compartir pantalla que añadas en tu app (ver [Extensión de compartir pantalla](#extension-de-compartir-pantalla)).

## Extensión de compartir pantalla

Desde la versión **2.8.1**, la **Broadcast Upload Extension** para compartir pantalla durante la videollamada se configura en la **app integradora** y se asocia al componente **Video Call** mediante **`extensionIdentifier`**.

### Pasos en la app integradora

1. En Xcode, añade un target **Broadcast Upload Extension** al proyecto de la app (p. ej. *File → New → Target → Broadcast Upload Extension*).
2. Define un **Bundle Identifier** único para la extensión (p. ej. `com.organization.app.videocallExtension`).
3. Usa ese identificador como **`extensionIdentifier`** al crear **`VideoCallController`** (véase el ejemplo de lanzamiento anterior).
4. En el target y la extensión se debe añadir una capability de tipo `App Group`. Al hacerlo, se debe introducir el mismo nombre tanto en el target como la extensión.
5. En el `Info.plist` de la extensión se debe modificar `NSExtensionPrincipalClass` para que su valor sea `videocallComponent.VideoExtensionHandler`.
6. Si se instala mediante Cocoapods, se debe añadir el target de la extensión al Podfile y su dependencia con Videocall. Si se instala con SPM, se debe añadir la dependencia de Videocall al target de la extensión.
7. Activa **`activateScreenSharing`** en **`VideoCallConfigurationData`** cuando quieras ofrecer compartir pantalla en la llamada.

Existe un [ejemplo de programación con esta funcionalidad incorporada](https://github.com/facephi/sdk-mobile-ios-samples/tree/master/sdkmobile-demo-videocall-pods) y configurada.

{% hint style="info" %}
En versiones **2.8.0** y anteriores, la extensión de broadcast podía asociarse al flujo de **Video Recording**. A partir de **2.8.1** esa responsabilidad pasa a **Video Call**.
{% endhint %}

## Configuración básica

La configuración básica necesaria no necesitará ningún parámetro.

```swift
static var videoCallConfiguration: VideoCallConfigurationData{
        var configVideoCall = VideoCallConfigurationData()
        return configVideoCall
}
```

## Recepción del resultado <a href="#id-7-recepcion-del-resultado" id="id-7-recepcion-del-resultado"></a>

Los controllers devolverán la información necesaria en formato SdkResult.

### Recepción de errores <a href="#id-71-recepcion-de-errores" id="id-71-recepcion-de-errores"></a>

En la parte del error, dispondremos de la clase común *ErrorType*.

* VCL\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VCL\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VCL\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VCL\_EMPTY\_LICENSE: El String de licencia está vacío
* VCL\_FACE\_DETECTION\_TIMEOUT: No se ha detectado cara
* VCL\_INITIALIZATION\_ERROR: Error de inicialización
* VCL\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* VCL\_NETWORK\_CONNECTION: Error en la conexión a internet
* VCL\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VCL\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VCL\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* VCL\_SOCKET\_ERROR: Error en la conexión de los servicios
* VCL\_TIMEOUT: Timeout en el proceso
* VCL\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VCL\_UNKNOWN\_ERROR: Error desconocido
* VCL\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de vídeo grabación está activo

### Recepción de ejecución correcta - *data* <a href="#id-72-recepcion-de-ejecucion-correcta-data" id="id-72-recepcion-de-ejecucion-correcta-data"></a>

En la ejecución correcta, simplemente se informa de que todo ha ido bien con el SdkResult.Success.

Cuando el resultado sea Success y esté activo el flag *sharingScreen* se podrá activar compartir pantalla.

## Información avanzada <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-51-class-nfcconfigurationdata" id="id-51-class-nfcconfigurationdata"></a>

Los campos incluidos en la configuración, normalmente **no es necesario que sean informados** ya que se completan internamente a través de la licencia usada.

**activateScreenSharing**

Activar la opción de compartir pantalla en la llamada.

**url**

Ruta al socket de video

**apiKey**

ApiKey necesaria para la conexión con el socket de video

**tenantId**

Identificador del tenant que hace referencia al cliente actual, necesario para la conexión con el servicio de video.

**vibrationEnabled**

Si se le da valor true, se activa la vibración en errores y si la respuesta del widget es OK

## Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos

Los textos pueden ser customizados sobreescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***voice over***.

| **Name**                                            | **Value**                                 |
| --------------------------------------------------- | ----------------------------------------- |
| video\_call\_component\_exit\_alert\_question       | ¿Seguro que quieres finalizar la llamada? |
| video\_call\_component\_exit\_alert\_finish         | Finalizar                                 |
| video\_call\_component\_exit\_alert\_accept         | Aceptar                                   |
| video\_call\_component\_exit\_alert\_cancel         | Cancelar                                  |
| video\_call\_component\_skip                        | OMITIR                                    |
| video\_call\_component\_restart                     | REINTENTAR                                |
| video\_call\_component\_agent                       | Asistente                                 |
| video\_call\_component\_text\_waiting\_agent\_title | Conectando con un asistente...            |
| video\_call\_component\_close\_button\_alt          | Cerrar                                    |
| video\_call\_component\_back\_button\_alt           | Atrás                                     |
| video\_call\_component\_timeout\_title              | Tiempo superado                           |
| video\_call\_component\_timeout\_desc               | No se ha podido conectar con un agente.   |

De este modo, si se desea modificar por ejemplo el texto “*Finalizar*” de la clave `video_call_component_exit_alert_finish` para el idioma **es**, se deberá ir al archivo **Localizable.strings** de la carpeta **es.lproj** si es que existe (si no, se deberá crear) y ahí, añadir:

`"video_call_component_exit_alert_finish"="Terminar";`

Si un mensaje no se especifica en el fichero del idioma, este se rellenará con el mensaje por defecto.

### Colores <a href="#id-82-colores" id="id-82-colores"></a>

Los colores se inicializan similarmente en la variable colors con un diccionario, teniendo como valor un UIColor que se desee.

```
sdkPrimaryColor
sdkBackgroundPrimaryColor
sdkSecondaryColor
sdkBodyTextColor
sdkTitleTextColor
sdkSuccessColor
sdkErrorColor
sdkNeutralColor
sdkAccentColor
sdkTopIconsColor
sdkBackgroundDisabled
```

### Animaciones <a href="#id-84-animaciones" id="id-84-animaciones"></a>

Las animaciones a usar se inicializan similarmente en la variable animations con un diccionario, teniendo como valor una string con el nombre de la animación que se encuentre en xcassets que se desee usar.

```
video_call_anim_waiting
```


# Videoidentificación - VideoID

Este componente necesita una versión mínima de iOS13

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***VideoID Component***.

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

* Gestión interna de cámaras, micro y permisos.
* Conexión con los servicios.
* Lectura del OCR y captura del documento.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencia

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

### **Cocoapods**

* Las dependencias obligatorias que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente de NFC deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```
pod 'FPHISDKVideoIDComponent', '~> $VERSION'
```

### **SPM**

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git

```

* Para instalar el componente de Vídeo identificación deberá incluirse en los módulos del proyecto:

```
//HTTPS
https://github.com/facephi-clienters/SDK-VideoIDPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-VideoIDPackage-SPM.git
```

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar los siguientes elementos en el fichero **Info.plist**:

```
Es necesario permitir el uso de la cámara (Privacy - Camera Usage Description)
Es necesario permitir el uso del micrófono (NSMicrophoneUsageDescription - Privacy - Microphone Usage Description)
```

## Controladores disponibles <a href="#id-4-controladores-disponibles" id="id-4-controladores-disponibles"></a>

| **Controlador**            | **Descripción**                                    |
| -------------------------- | -------------------------------------------------- |
| VideoIdController          | Controlador principal de video identificación      |
| SignatureVideoIdController | Controlador para firmar un proceso con una Captura |

## Lanzamiento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento:

```
let controller = VideoIdController(
  data: videoIdConfigurationData,
  output: { sdkResult in
    // Do whatever with the result
    ...
  }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoIdConfigurationData* que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```swift
static var videoIDConfiguration: VideoIDConfigurationData {
    return VideoIDConfigurationData(mode: .FACE_DOCUMENT_FRONT_BACK)
}
```

Los diferentes modos son:

* .ONLY\_FACE
* .FACE\_DOCUMENT\_FRONT
* .FACE\_DOCUMENT\_FRONT\_BACK

## Recepción del resultado <a href="#id-7-recepcion-del-resultado" id="id-7-recepcion-del-resultado"></a>

Los controllers devolverán la información necesaria en formato SdkResult.

### Recepción de errores <a href="#id-71-recepcion-de-errores" id="id-71-recepcion-de-errores"></a>

En la parte del error, dispondremos del enumerado común *ErrorType*:

* VID\_CANCEL\_BY\_USER: El usuario ha cancelado el proceso
* VID\_CANCEL\_LAUNCH: Se ha hecho una cancelación general del SDK
* VID\_COMPONENT\_LICENSE\_ERROR: La licencia del componente no es correcta
* VID\_EMPTY\_LICENSE: El String de licencia está vacío
* VID\_FACE\_DETECTION\_TIMEOUT: No se ha detectado cara
* VID\_INITIALIZATION\_ERROR: Error de inicialización
* VID\_MANAGER\_NOT\_INITIALIZED: Los managers son nulos
* VID\_NETWORK\_CONNECTION: Error en la conexión a internet
* VID\_NO\_DATA\_ERROR: Los datos de entrada son nulos
* VID\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VID\_PERMISSION\_DENIED: El usuario ha rechazado los permisos
* VID\_SOCKET\_ERROR: Error en la conexión de los servicios
* VID\_TIMEOUT: Timeout en el proceso
* VID\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VID\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de vídeo grabación está activo

### Recepción de ejecución correcta - *data* <a href="#id-62-recepcion-de-ejecucion-correcta-data" id="id-62-recepcion-de-ejecucion-correcta-data"></a>

En la parte de SdkResult.Success - *data*, dispondremos de la clase VideoIdResult.

El resultado devuelve las imágenes en formato **SdkImage**, es posible extraer el bitmap accediendo a *image.bitmap*. Si se quisiera convertir a base64 se puede utilizar la función:

`Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)`

Los campos devueltos en el resultado son los siguientes:

**frontDocumentData**

Datos del frente del documento. Incluye:

* documentImage: Imagen del documento
* documentFullImage: Imagen completa capturada
* documentFaceImage: Si se ha encontrado una cara en el documento se devuelve la imagen de la misma.
* iqaOverExposure: Valor numérico entre 0 y 1 que indica el nivel de sobreexposición de la imagen; un valor alto sugiere que la imagen está demasiado iluminada, lo que puede dificultar la lectura del documento.
* iqaReadable: Valor numérico entre 0 y 1 que indica la legibilidad del texto del documento; valores más altos implican que el texto es más claro y fácil de reconocer.
* iqaSharpness: Valor numérico entre 0 y 1 que indica la nitidez de la imagen del documento; valores altos reflejan una imagen más enfocada, lo que mejora la capacidad de extracción de datos.
* documentFaceImageTokenized: Si se ha encontrado una cara en el documento se devuelve la imagen cifrada de la misma.

**backDocumentData**

Datos del reverso del documento. Incluye:

* documentImage: Imagen del documento
* documentFullImage: Imagen completa capturada
* documentFaceImage: Si se ha encontrado una cara en el documento se devuelve la imagen de la misma.
* iqaOverExposure: Valor numérico entre 0 y 1 que indica el nivel de sobreexposición de la imagen; un valor alto sugiere que la imagen está demasiado iluminada, lo que puede dificultar la lectura del documento.
* iqaReadable: Valor numérico entre 0 y 1 que indica la legibilidad del texto del documento; valores más altos implican que el texto es más claro y fácil de reconocer.
* iqaSharpness: Valor numérico entre 0 y 1 que indica la nitidez de la imagen del documento; valores altos reflejan una imagen más enfocada, lo que mejora la capacidad de extracción de datos.
* documentFaceImageTokenized: Si se ha encontrado una cara en el documento se devuelve la imagen cifrada de la misma.

**faceImage**

Imagen del usuario capturada en la primera sección del proceso.

**ocrMap**

Mapa del OCR extraído del documento.

**ocrDiagnostic**

Diccionario con el diagnóstico OCR del documento. Las claves son los campos a validar y los valores son instancias de OcrDiagnostic.

Diagnóstico OCR extraído del documento.

* OK: El OCR es correcto.
* NOT\_FOUND: No se encuentra la clave OCR.
* TOLERANCE\_ERROR: El OCR no es correcto.
* WARNING: El OCR no es correcto, pero es solo una advertencia porque es un campo opcional.

**matchingSidesScore**

Valor numérico entre 0 y 1 que estima el nivel de coincidencia entre las caras del documento (frontal y trasera).

**documentType**

Tipo de documento obtenido.

**personalData**

Conjunto reducido de datos obtenidos del usuario:

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

**speechText**

Texto que el usuario deberá pronunciar durante la grabación del video.

**faceImageTokenized**

Imagen cifrada del usuario capturada en la primera sección del proceso.

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Aparte de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de *Personalización del SDK*), este componente en concreto permite la modificación de su interfaz.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Los textos pueden ser customizados sobreescribiendo el valor de las siguientes claves en un **Localizable.strings**. Las claves que contienen el sufijo ***\_alt*** son los literales utilizados en las etiquetas de accesibilidad necesarias para la funcionalidad de ***voice over***.

| **Name**                                                      | **Value**                                                                                      |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| video\_id\_component\_init\_message\_face\_content\_desc      | Coloca tu rostro y el frente de tu documento en las marcas                                     |
| video\_id\_component\_finish\_message                         | ¡Video grabación finalizada!                                                                   |
| video\_id\_component\_finish\_button                          | FINALIZAR                                                                                      |
| video\_id\_component\_restart\_button                         | REPETIR GRABACIÓN                                                                              |
| video\_id\_component\_ready\_button                           | CONTINUAR                                                                                      |
| video\_id\_component\_exit\_alert\_cancel                     | Cancelar                                                                                       |
| video\_id\_component\_exit\_alert\_question                   | ¿Seguro que quiere finalizar el proceso?                                                       |
| video\_id\_component\_exit\_alert\_finish                     | Finalizar                                                                                      |
| video\_id\_component\_exit\_alert\_accept                     | Aceptar                                                                                        |
| video\_id\_component\_timeout\_title                          | Tiempo superado                                                                                |
| video\_id\_component\_timeout\_desc                           | No pudimos hacer la grabación a tiempo. Probemos de nuevo.                                     |
| video\_id\_component\_internal\_error\_title                  | Se ha producido un error                                                                       |
| video\_id\_component\_internal\_error\_desc                   | Probemos de nuevo.                                                                             |
| video\_id\_component\_close\_button\_alt                      | Cerrar                                                                                         |
| video\_id\_component\_back\_button\_alt                       | Atrás                                                                                          |
| video\_id\_component\_logo\_alt                               | Logo                                                                                           |
| video\_id\_component\_document\_front\_message                | Coloca el frente de tu documento en las marcas                                                 |
| video\_id\_component\_document\_front\_message\_readable      | Mantén el frente de tu documento en las marcas                                                 |
| video\_id\_component\_document\_front\_message\_not\_readable | Acerca el frente de tu documento a las marcas                                                  |
| video\_id\_component\_document\_back\_message                 | Ahora coloca el reverso de tu documento                                                        |
| video\_id\_component\_document\_back\_message\_readable       | Mantén el reverso de tu documento en las marcas                                                |
| video\_id\_component\_document\_back\_message\_not\_readable  | Acerca el reverso de tu documento a las marcas                                                 |
| video\_id\_component\_switch\_camera\_message                 | Prepara el documento mientras se procede al cambio de cámara                                   |
| video\_id\_component\_face\_message                           | Coloca tu cara dentro del marco.                                                               |
| video\_id\_component\_multiple\_face\_message                 | Varias caras detectadas. Coloca solo tu cara dentro del marco                                  |
| video\_id\_component\_speech\_message                         | Di en voz alta: "Yo (nombre y apellidos) acepto los términos y condiciones".                   |
| video\_id\_component\_front\_document\_captured\_message      | Frente del documento capturado correctamente                                                   |
| video\_id\_component\_document\_back\_finish\_message         | Reverso del documento capturado correctamente                                                  |
| video\_id\_component\_face\_timeout\_title                    | No hemos detectado tu rostro                                                                   |
| video\_id\_component\_face\_timeout\_desc                     | Por favor, coloca tu rostro en la marca para iniciar el proceso                                |
| video\_id\_component\_ocr\_error\_desc                        | El documento no se ha podido leer. Por favor, revisa la iluminación y la distancia a la cámara |

### Animaciones <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Si se desea modificar las animaciones (lottie) de la SDK habría que incluir las animaciones con el mismo nombre en la carpeta res/raw/ de la aplicación.

```
video_id_anim_doc_and_face.json
video_id_anim_face.json
video_id_anim_loading.json
```


# Videograbación - Videorecording

Este componente necesita una versión mínima de iOS13

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

El *Componente* tratado en el documento actual recibe el nombre de ***VideoRecording Component***. Éste se encarga de capturar la pantalla del dispositivo en segundo plano. Está orientado principalmente para la grabación del proceso de onboarding.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información para el lanzamiento de este componente.

## Dependencias

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

### Cocoapods

* Actualmente las librerías de FacePhi se distribuyen de forma remota a través de diferentes gestores de dependencias, en este caso Cocoapods. Las dependencias **obligatorias** que deberán haberse instalado previamente (añadiéndolas en el fichero Podfile del proyecto) son:

```swift
  pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente de Selphi deberá incluirse la siguiente entrada en el Podfile de la aplicación:

```swift
  pod 'FPHISDKVideoRecordingComponent', '~> $VERSION'
```

### SPM

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```sh
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar el componente de SELPHI deberá incluirse en los módulos del proyecto:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-VideoRecording-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-VideoRecording-SPM.git
```

## Permisos

En la aplicación cliente donde se vayan a integrar los componentes es necesario incorporar el siguiente elemento en el fichero **Info.plist** cuando la grabación vaya a incluir audio:

```
Es necesario permitir el uso del micrófono (NSMicrophoneUsageDescription - Privacy - Microphone Usage Description)
```

{% hint style="info" %}
El permiso de micrófono solo es necesario si activas **`enableAudio`** en **`VideoRecordingConfigurationData`**. Por defecto **`enableAudio`** es **`false`** y la grabación no captura audio.
{% endhint %}

## Controladores disponibles

| **Controlador**          | **Descripcion**                         |
| ------------------------ | --------------------------------------- |
| VideoRecordingController | Controlador principal de Videograbación |

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

### Declaración de controlador

```swift
private var videoRecordingController: VideoRecordingController?
```

### Lanzamiento de la captura

Para iniciar la grabación de pantalla:

```swift
public func launchVideoRecording(viewController: UIViewController) {
    let data = VideoRecordingConfigurationData()
    let videoRecordingController = VideoRecordingController(
        data: data,
        viewController: viewController,
        output: {
            print("videoRecordingController output: \($0.errorType)")
        })
    SDKController.shared.launch(controller: videoRecordingController)
    self.videoRecordingController = videoRecordingController
}
```

### Detener la captura

Para detener la grabación de pantalla:

```swift
public func stopVideoRecording() {
    self.videoRecordingController?.stopVideoRecording()
}
```

### Recepción de errores <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Los errores se devolverán como un objeto 'VideoRecordingError'.

Lista de errores:

* VRC\_EMPTY\_LICENSE: El String de licencia está vacío
* VRC\_INITIALIZATION\_ERROR: Error de inicialización
* VRC\_OPERATION\_NOT\_CREATED: No hay ninguna operación en curso
* VRC\_NETWORK\_CONNECTION: Error en la conexión a internet
* VRC\_PERMISSION\_ERROR: El usuario ha rechazado los permisos
* VRC\_SOCKET\_ERROR: Error en la conexión de los servicios
* VRC\_UNKNOWN\_ERROR: Error desconocido
* VRC\_VIDEO\_CALL\_ACTIVE: No se puede iniciar porque hay una videollamada activa
* VRC\_VIDEO\_ERROR: Error en el procesamiento del vídeo
* VRC\_VIDEO\_RECORDING\_ACTIVE: No se puede iniciar porque el proceso de grabación de vídeo está activo

## Información avanzada

Este apartado amplía la información del componente.

### Configuración avanzada del componente <a href="#id-51-configuracion-avanzada-del-componente" id="id-51-configuracion-avanzada-del-componente"></a>

Para lanzar el componente actual, se deberá crear un objeto *VideoRecordingConfigurationData* que será la configuración del controlador del componente.

A continuación se detallan todos los campos que forman parte de esta clase.

Los campos incluidos en la configuración, normalmente **no es necesario que sean informados** ya que se completan internamente a través de la licencia usada.

Estos campos suelen informarse **solo** cuando el **servidor** es **OnPremise**.

#### **url**

Ruta al socket de video

#### **apiKey**

ApiKey necesaria para la conexión con el socket de video

#### **tenantId**

Identificador del tenant que hace referencia al cliente actual, necesario para la conexión con el servicio de video.

#### **enableAudio**

Flag que permite configurar si la videograbación dispondrá de audio o no. Por defecto a `false`.

{% hint style="info" %}
Si **`enableAudio`** es **`true`**, debes declarar el permiso de micrófono en **Info.plist** (véase la sección [Permisos](#permisos)).
{% endhint %}


# Términos y condiciones

Este componente necesita una versión mínima de iOS13

## Introducción

La aceptación de términos y condiciones de uso se realiza mediante el ***TermsConditions Component***.

Este componente se encarga de gestionar la captura de la respuesta del usuario ante unos términos y condiciones de uso. Sus principales procesos son:

* Lanzamiento de un visor de texto HTML.
* Captura de la respuesta del usuario.

En el apartado de [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado) se detallan los pasos necesarios para la integración básica del SDK. En esta sección se añade la información específica para el lanzamiento de este componente.

***

## Dependencias

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi, estas deberán eliminarse por completo antes de instalar los componentes de **SDK Mobile**.

### Cocoapods

* Las dependencias obligatorias que deberán haberse instalado previamente (añadiéndolas en el fichero `Podfile` del proyecto) son:

```swift
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar el componente de términos y condiciones de uso, añade la siguiente dependencia en el `Podfile` del proyecto:

```swift
pod 'FPHISDKTermsConditionsComponent', '~> $VERSION'
```

### Swift Package Manager (SPM)

* Las dependencias obligatorias que deberán haberse instalado previamente son:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar el componente de términos y condiciones de uso, inclúyelo en los módulos del proyecto:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-TermsConditionsComponent-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-TermsConditionsComponent-SPM.git
```

***

## Controladores disponibles

| **Controlador**           | **Descripción**                                            |
| ------------------------- | ---------------------------------------------------------- |
| TermsConditionsController | Controlador principal de captura de aceptación de términos |

***

## Lanzamiento simplificado

Una vez iniciado el SDK y creada una nueva operación, el componente puede lanzarse utilizando su controlador principal.

```swift
let controller = TermsConditionsController(
    data: termsConditionsConfigurationData,
    output: { sdkResult in
        // Do whatever with the result
        ...
    }
)
SDKController.shared.launch(controller: controller)
```

***

## Configuración básica

Para lanzar el componente, se debe crear un objeto `TermsConditionsConfigurationData`, que define la configuración del controlador.

La configuración básica necesaria es la siguiente:

```swift
TermsConditionsConfigurationData(
    termsConditions: "...html..."
)
```

Los parámetros disponibles son:

* `termsConditions`: texto HTML de condiciones y términos de uso que se mostrará al usuario.
* `extractionTimeout`: tiempo máximo permitido para completar el proceso.
* `orientation`: orientación de la pantalla del SDK.

***

## Recepción del resultado

El lanzamiento devolverá la información en formato `SdkResult`. Se puede diferenciar entre un lanzamiento correcto y uno incorrecto.

### Recepción de errores

En la parte del error, se dispondrá de la clase común `ErrorType`.

Listado de errores:

* `TER_APPLICATION_CONTEXT_ERROR`: El contexto de aplicación necesario es nulo.
* `TER_CANCEL_BY_USER`: El usuario ha cancelado el proceso.
* `TER_CANCEL_LAUNCH`: Se ha hecho una cancelación general del SDK.
* `TER_COMPONENT_LICENSE_ERROR`: La licencia del componente no es correcta.
* `TER_EMPTY_LICENSE`: El String de licencia está vacío.
* `TER_FLOW_ERROR`: Error en el proceso de flow.
* `TER_INITIALIZATION_ERROR`: Error de inicialización.
* `TER_MANAGER_NOT_INITIALIZED`: Los managers son nulos.
* `TER_NO_DATA_ERROR`: Los datos de entrada son nulos.
* `TER_OPERATION_NOT_CREATED`: No hay ninguna operación en curso.
* `TER_PERMISSION_DENIED`: El usuario ha rechazado los permisos.
* `TER_TIMEOUT`: Timeout en el proceso.
* `TER_UNKNOWN_ERROR`: Error desconocido.

### Recepción del resultado correcto - data

En la parte de `SdkResult.Success - data`, dispondremos de la clase `TermsConditionsResult`.

`TermsConditionsResult` no expone campos adicionales. Si el usuario acepta los términos, el componente devuelve un resultado correcto; si los rechaza, devuelve un error `OTHER("USER_REJECTED_TERMS_AND_CONDITIONS")`.

***

## Información avanzada

### Configuración avanzada del componente

Para lanzar el componente, se debe crear un objeto `TermsConditionsConfigurationData`.

A continuación se detallan los campos de esta clase:

* `termsConditions`: texto de condiciones y términos de uso que se mostrará al usuario.
* `extractionTimeout`: establece el tiempo máximo que se puede realizar la captura.
* `orientation`: orientación de la interfaz del SDK.

***

## Personalización del componente

Aparte de los cambios que se pueden realizar a nivel de SDK, este componente permite la personalización de su interfaz mediante el sistema de temas del wrapper iOS.

### Tema

La personalización visual se define mediante `ThemeTermsConditionsProtocol`.

Los temas disponibles en el wrapper son:

* `ThemeTermsConditions`: tema por defecto del componente.
* `ThemeTermsConditionsFlow`: tema aplicado cuando se resuelve la personalización externa.

Los recursos de color y dimensiones del componente se resuelven a partir de las claves del sistema de personalización del SDK:

* `sdkPrimaryColor`
* `sdkSecondaryColor`
* `sdkBackgroundPrimaryColor`
* `sdkErrorColor`
* `sdkSuccessColor`
* `sdkNeutralColor`
* `sdkAccentColor`
* `sdkTitleTextColor`
* `sdkBodyTextColor`
* `sdkTopIconsColor`
* `sdkButtonTextColor`

La dimensión configurable disponible es:

* `radiusCorner`

***


# Manejo de Errores Genéricos

El lanzamiento del SDK siempre devuelve un resultado. El resultado puede ser negativo y contener un error.

El SDK iOS dispone de errores genéricos que aportan feedback al integrador sobre el motivo por el que se ha detenido el proceso.

#### Comunes - Básicos

Estados generales que no entran en una categoría funcional específica.

* `.NO_ERROR`: Estado por defecto; indica que la operación se completó sin incidencias.
* `.UNKNOWN_ERROR`: Se ha producido un error que no ha sido identificado o categorizado específicamente.
* `.OTHER(String)`: Error genérico para casos no contemplados. Incluye un mensaje personalizado mediante un `String`.

#### Comunes - Requisitos

Errores relacionados con la disponibilidad de datos, el ciclo de vida de los procesos o la conectividad.

* `.NO_DATA_ERROR`: El proceso necesita un valor de configuración que no ha sido informado correctamente o es nulo.
* `.OPERATION_NOT_CREATED`: La operación no pudo inicializarse correctamente.
* `.NETWORK_CONNECTION`: Error de comunicación; el dispositivo no tiene acceso a internet o el servidor no responde.

#### Comunes - Permisos

Se activan cuando el usuario o el sistema operativo deniegan el acceso a hardware o archivos.

* `CAMERA_PERMISSION_DENIED`: El acceso a la cámara del dispositivo fue bloqueado.
* `MIC_PERMISSION_DENIED`: El acceso al micrófono fue bloqueado.
* `LOCATION_PERMISSION_DENIED`: Los servicios de ubicación (GPS) no están autorizados.
* `STORAGE_PERMISSION_DENIED`: Se denegó el permiso de lectura/escritura en el almacenamiento local.

#### Comunes - Interacción del Usuario

Errores derivados del comportamiento del usuario o restricciones de la sesión.

* `CANCEL_BY_USER`: El proceso fue cancelado explícitamente por el usuario.
* `SDK_TIMEOUT`: El proceso de captura excedió el tiempo máximo de espera configurado.

#### Comunes - Errores de Licencia

Errores de validación relacionados con la clave de licencia o los componentes del SDK.

* `.LICENSE_CHECKER_ERROR(String)`: Error general durante la validación de la licencia con el servidor. El parámetro `String` indica el detalle de forma más explícita.
* `.MISSING_COMPONENT_LICENSE_DATA`: El componente que se está intentando lanzar necesita datos que no se han configurado correctamente en la licencia.
* `.COMPONENT_LICENSE_ERROR`: El componente que se intenta utilizar no está habilitado en la licencia.
* `.EMPTY_LICENSE`: El campo de la licencia está vacío.

**Además de los genéricos, cada módulo puede contener errores específicos que se verán detallados en sus respectivas páginas de la documentación.**


# Personalización

Esta guía explica cómo personalizar la apariencia del SDK en tus aplicaciones iOS. Se recomienda agregar las modificaciones tanto en el tema claro como oscuro (night).

## Colores y logo

Para cambiar los colores y el logo del SDK, se deben incluir **Assets** en la carpeta `Resources` de la aplicación del cliente.

<div align="left"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-7b1f72bc24479bae837b8cdedf9c422cfb56ff72%2Fimage.png?alt=media" alt="" width="272"><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-1e42025e441467f28453dc980c039f844e55d51c%2Fimage.png?alt=media" alt="" width="414"><figcaption></figcaption></figure></div>

### Generales

```
sdkAccentColor
sdkBackgroundPrimaryColor
sdkBackgroundSecondaryColor
sdkBackgroundDisabled
sdkBodyTextColor
sdkDisabledBackgroundColor
sdkButtonTextColor
sdkErrorColor
sdkNeutralColor
sdkPrimaryColor
sdkSecondaryColor
sdkSuccessColor
sdkTitleTextColor
sdkTopIconsColor
```

### Específicos de componentes

* Video llamadas: `sdkActionsBackgroundColor`, `sdkButtonBackgroundColor`
* Video identificación: `sdkTopIconsVideoColor`

**Nota:** cambiar los colores principales (`sdkPrimaryColor`, `sdkErrorColor`, `sdkSuccessColor`, `sdkNeutralColor`, `sdkAccentColor`) también afectará a las animaciones.

{% hint style="info" %}
Los componentes **Selphi** y **SelphID** utilizan su propio paquete de recursos (`zip`), por lo que **no se ven afectados** por esta personalización.
{% endhint %}

## Animaciones <a href="#id-2-animaciones" id="id-2-animaciones"></a>

Si se desea modificar las animaciones (**Lottie**) de la SDK, basta con incluir las nuevas animaciones con el **mismo nombre** en la aplicación.

Los nombres exactos de las animaciones están documentados en la sección de personalización de cada componente.

## Textos <a href="#id-3-textos" id="id-3-textos"></a>

Los textos pueden personalizarse sobreescribiendo el valor de las claves en un fichero `Localizable.strings`.

* Las claves con sufijo **`_alt`** son los textos utilizados en las etiquetas de **accesibilidad** necesarias para la funcionalidad de **VoiceOver**.
* Cada componente incluye el listado de claves disponibles para modificación.

## Fuentes <a href="#id-4-fuentes" id="id-4-fuentes"></a>

* Añade los archivos `.ttf` a la aplicación.
* Asigna el **nombre exacto** esperado por el SDK. Si el nombre no coincide, la fuente no se aplicará.

<div align="left"><figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-3451c0ac6611ee68cc68ed39d8aa32b95dbe4dec%2Ffonts.png?alt=media" alt=""><figcaption></figcaption></figure></div>

## Iconos genéricos <a href="#id-6-iconos-de-la-barra-superior" id="id-6-iconos-de-la-barra-superior"></a>

Para personalizar los múltiples iconos que aparecen en el SDK, crea los recursos en los ASSETS de la aplicación con los siguientes nombres:

```
sdk_logo
ic_sdk_close
ic_sdk_close_arrow
ic_sdk_error_connection
ic_sdk_error_timeout
ic_sdk_unknown_error
ic_sdk_permission_camera
ic_sdk_permission_micro
ic_sdk_permission_generic
ic_sdk_info
ic_sdk_pager_back
ic_sdk_pager_forward
```


# Aplicaciones de Ejemplo

Una vez que hayas instalado el SDK de Facephi en tu proyecto iOS, es necesario realizar la configuración inicial para que las soluciones biométricas funcionen correctamente.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

[Repositorio IOS](https://github.com/facephi/sdk-mobile-ios-samples/tree/master)

## Configurar y ejecutar aplicaciones <a href="#pasos-para-configurar-y-ejecutar-las-aplicaciones" id="pasos-para-configurar-y-ejecutar-las-aplicaciones"></a>

1. Añadir el repositorio privado como se indica en *Instalación*.
2. Rellenar los datos en la clase `SdkConfigurationManager`.

## SdkConfigurationManager - Datos necesarios para el uso del SDK <a href="#sdkdata---datos-necesarios-para-el-uso-del-sdk" id="sdkdata---datos-necesarios-para-el-uso-del-sdk"></a>

Para que la aplicación funcione correctamente se deberán rellenar los siguientes datos.

```swift
// Datos para licencia online
static let APIKEY_LICENSING = "...."
static let LICENSING_URL = "...."

// Datos para licencia offline
static let LICENSE = "...."
static let LICENSE_ONLINE = false

// Identificador del cliente y tipo de operación
static let CUSTOMER_ID = "...."
var OPERATION_TYPE = OperationType.ONBOARDING

// Selphi, con nombre del zip de recursos y datos de configuración
let resourcesSelphi: String = {
let selphiZipName = "fphi-selphi-widget-resources-sdk"
return Bundle.main.path(forResource: selphiZipName, ofType: "zip") ?? ""
}()

// SelphID, con nombre del zip de recursos y datos de configuración
let resourcesSelphID: String = {
let selphidZipName = "fphi-selphid-widget-resources-sdk"
return Bundle.main.path(forResource: selphidZipName, ofType: "zip") ?? ""
}()

// URL de servicios de verificación
static let BASE_URL = "..."
```

***


# Ajustes avanzados

En esta sección se amplía la información del apartado [Lanzamiento simplificado](/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado).

### Añadir repositorio privado

Para tener acceso a nuestro repositorio privado, se requiere haber instalado previamente **Cocoapods** en la máquina.

Por cuestiones de seguridad y mantenimiento, los nuevos componentes de la ***SDKMobile*** se almacenan en unos repositorios privados que requieren de unas credenciales específicas para poder acceder a ellos. Esas credenciales deberá obtenerlas a través del equipo de soporte de Facephi. A continuación se indica como preparar el entorno para consumir los componentes:

* Primero instalamos el comando que nos dará acceso a usar cocoapods con **Artifactory**.

```
sudo gem install cocoapods-art
```

* En un Mac con **chip M1** pueden surgir errores durante la instalación; en ese caso, use el siguiente comando:

```
sudo arch -arm64 gem install ffi; sudo arch -arm64 gem install cocoapods-art
```

En caso de tener problemas con la instalación, desinstalar completamente cocoapods y todas sus dependencias para hacer una instalación limpia.

* Necesitaremos añadir el repositorio a la lista del fichero **netrc**. Para ello, desde un Terminal, se ejecuta el siguiente comando:

```
$ nano ~/.netrc
```

Y copiamos el siguiente fragmento con los datos correspondientes al final del fichero:

```
machine facephicorp.jfrog.io
  login <USERNAME>
  password <TOKEN>
```

Es importante copiar de manera **exacta** el anterior fragmento de código. El indentado previo a las palabras **login** y **password** está formado por dos espacios.

* Finalmente se añadirá el repositorio que contiene dependencias privada:

```
pod repo-art add cocoa-pro-fphi "https://facephicorp.jfrog.io/artifactory/api/pods/cocoa-pro-fphi"
```

### Dependencias requeridas para la integración <a href="#id-22-dependencias-requeridas-para-la-integracion" id="id-22-dependencias-requeridas-para-la-integracion"></a>

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

* Actualmente las librerías FacePhi se distribuyen remotamente a través de diferentes gestores de dependencias, en este caso, ***Cocoapods***. **Dependencias obligatorias** que deben ser instaladas previamente (añadiéndolas al *Podfile*):

```ruby
plugin 'cocoapods-art', :sources => [
  'cocoa-pro-fphi'
]

source 'https://cdn.cocoapods.org/'

target 'Example' do
  pod 'FPHISDKMainComponent', '~> $VERSION'

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
        config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
        config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
      end
    end
  end
end
```

* Cuando se quiera actualizar dependencias, antes de ejecutar **`pod install`** use el siguiente comando para actualizar el repositorio local:

```sh
pod repo-art update cocoa-pro-fphi
```

### Posibles incidencias <a href="#id-23-posibles-incidencias" id="id-23-posibles-incidencias"></a>

En el caso de que el integrador utilice un Macbook con Chip **M1**, cabe la posibilidad de que la instalación de cocoapods-art no se realice correctamente. Por ello, se debe tener en cuenta los siguientes puntos:

* Si cocoapods se ha instalado mediante Homebrew puede haber problemas.
* Se recomienda instalar cocoapods y cocoapods-art usando gem.

A continuación incluimos un script que permite realizar todos los pasos necesarios para dejar el entorno preparado para poder funcionar correctamente:

```
 #! /bin/zsh

install_cocoapods () {
    echo "Installing cocoapods with gem"
    # Creating new gems home if it doesnt't exist
    if [ ! -d "$HOME/.gem" ]; then
        mkdir "$HOME/.gem"
    fi
    # Adding to current session
    export GEM_HOME="$HOME/.gem"
    export PATH="$GEM_HOME/bin:$PATH"

    # Adding for future sessions
    if test -f "$HOME/.zshrc"; then
        echo 'Adding $GEM_HOME env var and then adding it to your $PATH'
        echo '' >> "$HOME/.zshrc"
        echo 'export GEM_HOME="$HOME/.gem"' >> "$HOME/.zshrc"
        echo 'export PATH="$GEM_HOME/bin:$PATH"' >> "$HOME/.zshrc"
        echo 'alias pod="arch -x86_64 pod"' >> "$HOME/.zshrc"
    fi

    # Installing cocoapods
    gem install cocoapods
    sudo arch -x86_64 gem install ffi
    which pod
    pod --version
    gem install cocoapods-art
}

uninstall_cocoapods_homebrew () {
    which -s brew
    if [[ $? != 0 ]] ; then
        echo "Homebrew not installed, skipping uninstalling cocoapods from homebrew"
    else
        brew uninstall cocoapods
    fi
}

if ! type "pod" > /dev/null; then
    echo "You don't have cocoapods installed..."
else
    echo "Trying to uninstall it from homebrew first"
    uninstall_cocoapods_homebrew
fi

install_cocoapods
```

En caso de usar ***xCode15*** se deberá realizar la siguiente configuración:

<figure><img src="https://2359030012-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUo71Qbj6jZQDavjc0U5X%2Fuploads%2Fgit-blob-03c66ae3502566407290ae37eb7be78dad31ed6d%2Ffix_ldClassic-18c668c14649e02798c4250d1af70c05.png?alt=media" alt=""><figcaption></figcaption></figure>

Se deberá añadir ***-ld\_classic*** en Other Linker Flags, en el Build Settings de la aplicación.

### SDK initialization <a href="#id-3-sdk-initialization" id="id-3-sdk-initialization"></a>

**Debe evitarse inicializar un controlador que no vaya a usarse.**

Cada uno de los componentes tiene un controlador (*Controller*) que permitirá acceder a su propia funcionalidad. Antes de poder utilizarse, deberán inicializarse correctamente. Los pasos a seguir en la inicialización son:

1. Inicializar los controladores que se van a utilizar.
2. Decidir si la licencia se incluirá como `String` o mediante un servicio de licenciamiento remoto (consultar [Inyección de licencias](#id-31-inyeccion-de-licencias)) e invocar la inicialización del SDK.
3. Si la inicialización devuelve `FinishStatus.STATUS_OK`, el SDK quedará listo para su uso.

```swift
let trackingController = TrackingController(trackingError: { trackingError in
    self.log("TRACKING ERROR: \(trackingError)")
})

// MANUAL License
SDKController.shared.initSdk(license: SdkConfigurationManager.LICENSE, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licencia manual seteada correctamente")
    } else {
        self.log("La licencia manual no es correcta")
    }
}, trackingController: trackingController)

// AUTO License
SDKController.shared.initSdk(
    licensingUrl: SdkConfigurationManager.LICENSING_URL,
    apiKey: SdkConfigurationManager.APIKEY_LICENSING,
    output: { sdkResult in
        if sdkResult.finishStatus == .STATUS_OK {
            self.log("Licencia automática seteada correctamente")
        } else {
            self.log("Ha ocurrido un error al intentar obtener la licencia: \(sdkResult.errorType)")
        }
    },
    trackingController: trackingController)
```

#### Inyección de licencias <a href="#id-31-inyeccion-de-licencias" id="id-31-inyeccion-de-licencias"></a>

Como se ha comentado previamente, actualmente existen dos formas de inyectar la licencia:

**a. Obteniendo la licencia a través de un servicio**

A través de un servicio que simplemente requerirá una URL y un API-KEY como identificador. Esto evitaría problemas a la hora de manipular la licencia, así como la constante sustitución de dichas licencias a la hora de surgir algún problema con ella (malformación o modificación indebida, expiración de la licencia...)

```swift
// AUTO License
SDKController.shared.initSdk(licensingUrl: SdkConfigurationManager.LICENSING_URL, apiKey: SdkConfigurationManager.APIKEY_LICENSING, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licencia automática seteada correctamente")
    } else {
        self.log("Ha ocurrido un error al intentar obtener la licencia: \(sdkResult.errorType)")
    }
}, trackingController: trackingController)
```

**b. Inyectando la licencia como String**

Se puede asignar la licencia directamente como un String, de la siguiente manera:

```swift
// MANUAL License
SDKController.shared.initSdk(license: SdkConfigurationManager.LICENSE, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licencia manual seteada correctamente")
    } else {
        self.log("La licencia manual no es correcta")
    }
}, trackingController: trackingController)
```

### Iniciar nueva operación <a href="#id-4-iniciar-nueva-operacion" id="id-4-iniciar-nueva-operacion"></a>

Cada vez que se desee iniciar el flujo de alguna operación nueva (ejemplos de operaciones serían: onboarding, authentication, videoCall,…) es esencial indicarle al **SDKController** que ésta va a comenzar, y así la SDK sabrá que las próximas llamadas de **Componentes** (también llamados **Steps**) formarán parte de dicha operación. Esto es necesario para trackear a la plataforma la información global de esta operación de forma satisfactoria.

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método **newOperation**

Este método tiene 3 parámetros de entrada:

1. **operationType**: Indica si se va a hacer un proceso de ONBOARDING o de AUTHENTICATION
2. **customerId**: Id único del usuario si se tiene (controlado a nivel de aplicación)
3. **steps**: Lista de pasos de la operación si se han definido previamente

Hay 2 maneras de realizar este inicio de operación, dependiendo de si **se conocen los pasos** que formarán el flujo del proceso de registro o autenticación (en caso de que los componentes se ejecuten de forma secuencial y siempre de la misma forma) o, en caso contrario, de que el flujo **no esté definido** y sea desconocido (por ejemplo, el cliente final es el que decide el orden de ejecución de los componentes).

* Flujo **conocido** (aparecerá la operación trackeada en la plataforma con todos los pasos de la lista). Ejemplo de implementación:

```swift
SDKController.shared.newOperation(
    operationType: OperationType.X,
    customerId: "customerId",
    steps: [.SELPHI, .SELPHID, .OTHER("CUSTOM_STEP")],
    output: { _ in })
```

* Flujo **desconocido** (aparecerá la operación trackeada en la plataforma con puntos suspensivos). Ejemplo de implementación:

```swift
SDKController.shared.newOperation(
    operationType: OperationType.X,
    customerId: "customerId",
    output: { _ in })
```

En **`SdkResult.Success`**, el campo **`data`** contiene la información de la operación creada.

**Una vez creada la operación** se podrán ejecutar los componentes de la SDK asociados a esta operación. Consultar la documentación específica de cada componente para saber cómo hacerlo.

#### Tipos de operación existentes <a href="#id-41-tipos-de-operacion-existentes" id="id-41-tipos-de-operacion-existentes"></a>

En la actualidad, existen las siguientes operaciones, durante las cuales se hacen uso de unos determinados **Componentes (STEPS)**. A continuación se muestra una tabla con la relación entre operaciones y steps:

| **Operación (OperationType)** | **Componente (Step)**                          | Descripción                                                                                                                              |
| ----------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| ONBOARDING                    | <p>SELPHI\_COMPONENT<br>SELPHID\_COMPONENT</p> | <p>- Validación facial de un selfie contra la cara de un documento<br>- Extracción del OCR del documento<br>- Detección de vivacidad</p> |
| AUTHENTICATION                | SELPHI\_COMPONENT                              | <p>- Validación facial mediante plantillas<br>- Detección de vivacidad</p>                                                               |

Esta lista se irá ampliando en próximas actualizaciones de la SDK, según vayan apareciendo nuevos componentes y casos de uso.

### Opciones para el lanzamiento del componente

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Hay dos formas de lanzar el componente:

* **\[CON TRACKING]** Lanza el componente y **envía eventos** al servidor de *tracking*:

```swift
let controller = ExampleController(
    data: exampleConfigurationData,
    output: { sdkResult in
        // Do whatever with the result
    },
    viewController: viewController)
SDKController.shared.launch(controller: controller)
```

* **\[SIN TRACKING]** Lanza el componente **sin enviar eventos** al servidor de *tracking*:

```swift
let controller = ExampleController(
    data: exampleConfigurationData,
    output: { sdkResult in
        // Do whatever with the result
    },
    viewController: viewController)
SDKController.shared.launchMethod(controller: controller)
```

El método **launch** debe usarse **por defecto**. Este método permite utilizar ***tracking*** en caso de estar su componente activado, y no lo usará cuando esté desactivado (o no se encuentre el componente instalado).

Por el contrario, el método **launchMethod** cubre un caso especial, en el cual el integrador tiene instalado y activado el tracking, pero en un flujo determinado dentro de la aplicación no desea trackear información. En ese caso se usa este método para evitar que se envíe esa información a la plataforma.

### Retorno de resultado <a href="#id-6-retorno-de-resultado" id="id-6-retorno-de-resultado"></a>

El resultado de cada componente será devuelto a través de la SDK manteniendo siempre la misma estructura de 3 campos:

1. **finishStatus**: Que nos indicará si la operación ha finalizado correctamente. Posibles valores `FinishStatus.STATUS_OK`, `FinishStatus.STATUS_ERROR`
2. **errorType**: Si *finishStatus* indica que ha habido un error, este campo tendrá la descripción del mismo.
3. **data**: Datos de respuesta del SDK; su estructura depende del componente ejecutado (véase la documentación de cada módulo).

### Métodos auxiliares <a href="#id-6-controladores-auxiliares" id="id-6-controladores-auxiliares"></a>

En este apartado se incluyen otros controladores y operaciones auxiliares, algunos de ellos opcionales, y que pueden ser necesarios para la correcta finalización del flujo.

Estos campos son necesarios para la comunicación con el servicio de **Facephi**, en caso de querer realizar cualquier **verificación** y de desear realizar el *tracking* de una operación determinada.

#### Obtención del OperationId <a href="#id-61-obtencion-del-operationid" id="id-61-obtencion-del-operationid"></a>

```swift
SDKController.shared.getOperationId()
```

#### Obtención del OperationType <a href="#id-62-obtencion-del-operationtype" id="id-62-obtencion-del-operationtype"></a>

```swift
SDKController.shared.getOperationType()
```

#### Obtención del SessionId <a href="#id-63-obtencion-del-sessionid" id="id-63-obtencion-del-sessionid"></a>

```swift
SDKController.shared.getSessionId()
```

#### Obtención del CustomerID <a href="#id-64-obtencion-del-customerid" id="id-64-obtencion-del-customerid"></a>

```swift
SDKController.shared.getCustomerId()
```

#### Asignación del CustomerID <a href="#id-65-asignacion-del-customerid" id="id-65-asignacion-del-customerid"></a>

```swift
SDKController.shared.setCustomerId(customerId: customerId)
```


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del SDK de Facephi para iOS. Se recomienda mantener siempre tu integración actualizada a la última versión estable.

**Nota:** La librería **Licensing** está obsoleta; su funcionalidad ha sido incluida dentro de **SDK Main** desde la versión v2.4.X.

***

### Última versión

### **Versión: 2.12.2**

**Octubre 2026**

* SelphID
  * Corregida una fuga de memoria que podía producirse en algunos dispositivos al ejecutar varias veces el proceso con wizardMode = false.
  * Se ha actualizado el bundle de recursos con mejoras en los siguientes documentos
    * Cédula de Honduras
    * Cédula de El Salvador
    * Cédula de Costa Rica
    * Cédula de Nicaragua
    * Nuevo modelado del Permiso Laboral de Costa Rica
    * Nuevo modelado del Documento de Extranjería de Costa Rica (DIMEX)

***

#### Versión: 2.12.0

**Septiembre 2026**

#### General

* Actualizada la versión menor del **core a la 2.12.0** y publicación alineada de componentes nativos en **2.12.0**.

#### Selphi - Captura facial

* Actualizada la dependencia del widget **Selphi**; nueva versión del widget: **6.4.1**.
* Actualizado **IAD** a la versión **2.6.0**.
* Mejora de la estabilización IAD; el proceso debería resultar más sencillo.

#### SelphID - Captura de documento

* Actualizada la dependencia del widget **SelphID**; nueva versión del widget: **1.41.5**.
* Mejoras en el sistema de trazas/logs (versión MBSDR)
* **Fix:** corrección del escaneo de documento en **2 pasos**: **1.41.X**.
* **Fix:** se conserva el extractor previo hasta capturar correctamente el reverso; corrige la repetición del dorso en escaneo en 2 pasos.

#### Tracking - Conexión con la plataforma

* Actualizada la dependencia del widget **Tracking**; nueva versión del widget: **1.4.11**.
* Servicio de obtención de tiempo remoto.

***

### Versiones anteriores

#### Versión: 2.11.0

**Septiembre 2026**

#### General

* Actualizada la versión menor del **core a la 2.11.0** y publicación alineada de componentes nativos en **2.11.0**.

#### Selphi - Captura facial

* Actualizada la dependencia del widget **Selphi**; nueva versión del widget: **6.4.0**.
* Plataforma mínima del paquete SPM: **iOS 13**.

#### SelphID - Captura de documento

* Nuevo parámetro de entrada *encodedDataFocusEnabled* que activa el modo de lectura de códigos de barras cuando hay dificultad de lectura (solo activo en el flavor MBSDR y con zip de recursos de una versión > 1.41.4).
* Nuevos parámetros de salida *encodedDataImages* y *tokenEncodedDataImages* con los resultados de una lectura de códigos de barras (solo activo en el flavor MBSDR y con zip de recursos de una versión > 1.41.4).

#### VideoID - Identificación por vídeo

* Actualizado **FPHISelphidDocumentReaderBundle** a **3.3.8**.

#### Capture - Subida de ficheros / captura

* **Breaking change:** FileUploader, QR Reader y QR Generator pasan a **FPHICaptureWidget** (KMP). Se elimina la UI nativa (Invoice, galería y QR propios). Widget **1.4.3**.

#### Phingers - Captura de huellas

* Actualizada la dependencia del widget **Phingers**; nueva versión del widget: **1.5.5**.

#### Tracking - Conexión con la plataforma

* Actualizada la dependencia del widget **Tracking** a **1.4.9**.

#### NFC 2.19.0 - Lectura de documento NFC

* Actualizada la dependencia de **Core** a **2.11.0**.
* **Fix:** el indicador de progreso de la sesión NFC muestra **6 puntos** en una línea independiente bajo la descripción.

***

### Versiones anteriores

#### Versión: 2.10.0

**Julio 2026**

#### General

* Nuevos colores para la personalización.

#### Términos y condiciones de uso

* Creación del nuevo componente.
* **Breaking change / migración:** el componente **Disclaimer** pasa a llamarse **TermsConditions**. Actualizar referencias de integración de `FPHISDKDisclaimerComponent`, `DisclaimerController`, `DisclaimerConfigurationData`, `DisclaimerResult` y temas `ThemeDisclaimer*` a sus equivalentes `FPHISDKTermsConditionsComponent`, `TermsConditionsController`, `TermsConditionsConfigurationData`, `TermsConditionsResult` y `ThemeTermsConditions*`.

#### Tracking - Conexión con la plataforma

* Eventos para los términos y condiciones de uso.

#### Phingers - Captura de huellas

* Mejoras en la interfaz y experiencia de usuario.
* Mejoras en el proceso de captura.
* Mejoras en el proceso de captura con baja iluminación.
* Mejoras en el enfocado de la imagen con distintos dispositivos.
* **Breaking change / migración (literales):** las claves de personalización de textos dejan de usar el prefijo `phingers_tf_component_*` y pasan a `phingers_widget_*`. Si la aplicación sobrescribe literales en **Localizable.strings**, hay que actualizar las claves. Consulta el [listado completo](/sdks/sdk-mobile/ios-sdk/modulos/captura-de-huellas#id-81-textos).

#### Subida de ficheros y gestión de QR - Capture

* **Breaking change / migración (literales):** se alinean las claves de personalización de textos con Android. Desaparecen claves iOS específicas como `capture_component_invoice_*` y `capture_component_qr_tutorial_title` / `*_desc` / `*_button_message`, y se usan `capture_component_*` y `capture_widget_*` según el [listado completo](/sdks/sdk-mobile/ios-sdk/modulos/subida-de-ficheros-y-gestion-de-qr#id-81-textos). Si la aplicación sobrescribe literales en **Localizable.strings**, hay que actualizar las claves.

#### Captura de documentos - SelphID

* **Fix:** corrección del problema de layout en el estado **CaptureBackError**.
* **Fix:** corrección de imágenes recortadas en **RGL**. Ahora los componentes rojo y azul son correctos.
* **Fix:** corregida la orientación del reconocedor `DocumentDetector` en los flavors **ML** y **MBSDR**.

#### Captura facial con IAD - Selphi

* **Fix:** eliminado el zoom de cámara no deseado en el flavor **IAD**.
* **Fix:** corregida la estabilización con `LivenessMode = NONE`. La estabilización deja de ser obligatoria en este modo.

***

### Versiones anteriores

#### Versión: 2.8.1

**Junio 2026**

#### General

* Release parcial de componentes con actualizaciones requeridas.

#### Phingers - Captura de huellas

* **Breaking change:** el parámetro **`threshold`** se sustituye por **`livenessThreshold`** y **`detectorThreshold`** en **`PhingersConfigurationData`**. El valor por defecto pasa de **0.7** a **0.9** en ambos parámetros.
* **Breaking change (comportamiento):** **`enableFlash`** puede activarse aunque esté en `false` si el proceso detecta poca luz en la imagen para mejorar el proceso de captura.

#### SelphID - Captura de documento

* Nuevo parámetro **`animateDismiss`** en **`SelphIDConfigurationData`**: indica si se anima el cierre del SDK al finalizar el proceso.

#### Selphi - Captura facial

* Nuevo parámetro **`animateDismiss`** en **`SelphiConfigurationData`**: indica si se anima el cierre del SDK al finalizar el proceso.

#### Video Call

* **Breaking change / migración:** la **extensión de compartir pantalla** (Broadcast Upload Extension) pasa a configurarse en el componente **Video Call**. La app integradora debe crear la extensión y pasar su **`extensionIdentifier`** al lanzar **`VideoCallController`**. Consulta la [documentación del módulo](/sdks/sdk-mobile/ios-sdk/modulos/videollamada#extension-de-compartir-pantalla).

***

### Versiones anteriores

#### Versión: 2.8.0

**Mayo 2026**

#### General

* Actualizada la versión menor del **core a la 2.8.0** y publicación alineada de componentes en **2.8.0** donde aplica.
* **Breaking change (personalización de recursos):** la clave del color de fondo del SDK pasa de `sdkBackgroundColor` a **`sdkBackgroundPrimaryColor`**; hay que actualizarla o el tema no aplicará el fondo esperado. También se añade **`sdkBackgroundSecondaryColor`** (entre otros usos, en la vista de selector de documentos de SelphID).
* **Breaking change (personalización de recursos):** el recurso `ic_sdk_logo` se renombra a `sdk_logo` en todos los componentes. Afecta a integradores que personalicen recursos.

#### Selphi - Captura facial

* Actualizada la dependencia del widget **Selphi**; nueva versión del widget: **6.2.0**.
* **Fix:** se limpia la caché de personalización del **Flow** al inicializar el controller (evita estilos residuales entre instancias).

#### SelphID - Captura de documento

* Actualizada la dependencia del widget **SelphID**; nueva versión del widget en esta entrega: **1.39.1**.
* **Fix:** se limpia la caché de personalización del **Flow** al inicializar el controller (evita estilos residuales entre instancias).

#### Capture - Subida de ficheros / captura

* **Breaking change:** en **`FileUploaderConfigurationData`** se añaden **`onlyGalleryMode`** (por defecto **`true`**) y **`maxGalleryImageSizeKb`** (por defecto **2048**).
* **Fix:** el envío de datos a **tracking** usa el **tipo MIME** resuelto desde el resultado del widget (incluida selección desde galería), en lugar de asumir siempre PDF o imagen genérica.

#### Phingers - Captura de huellas

* **Fix:** corrección de la selección de tutoriales según el modo de captura por dedo.

#### NFC 2.16.0 - Lectura de documento NFC

* **Feature:** soporte de imágenes en formato **JPEG2000** en **DG2** y **DG7**.
* **Fix:** la UI de **tutorial** respeta el flag **`showTutorial`** (dejaba de aplicarse al estar forzado a `true`).
* **Diagnóstico:** ampliación de **logs** en **DG2** para facilitar el soporte y la depuración.

#### Video Call

* **Breaking change:** dependencia de **streaming de video** actualizada por cambios breaking del SDK nativo (configuración de *frame rate* del encoder y versión mínima del SDK).

#### VideoID - Identificación por vídeo

* **Breaking change:** dependencia de **streaming de video** actualizada por cambios breaking del SDK nativo (configuración de *frame rate* del encoder y versión mínima del SDK).
* **Fix:** tratamiento explícito de **errores de red** en el flujo.
* **Fix:** se conserva el **progreso de la captura facial** al cambiar de modo (p. ej. solo cara frente a flujos mixtos).
* Actualizado y adaptado **FPHISelphidDocumentReaderBundle** a **2.1.0**.

#### Video Recording

* **Breaking change:** dependencia de **streaming de video** actualizada por cambios breaking del SDK nativo (configuración de *frame rate* del encoder y versión mínima del SDK).
* **Breaking change:** nuevo parámetro de configuración **`enableAudio`**. Su valor por defecto es **`false`**.
* **Fix:** posible **fuga de memoria** por retención cíclica en **`VideoRecordingController`**.
* **Fix:** refactor relacionado con **audio** y **subida** tras la actualización de la dependencia de **streaming de video**.

#### Tracking - Conexión con la plataforma

* Actualización de la dependencia del componente **Tracking** relacionada con identificación de dispositivo (2.6.0 → 2.14.x).
* Las credenciales pueden resolverse desde la configuración de la licencia en los componentes **Tracking** o **IDV**, según el despliegue.
* Nuevos metadatos en el envío de eventos de tracking: **versión del SDK** en *tags* y **`operationId`** en **LinkedId** donde aplica.

#### Status

* **Fix:** color de fondo del elemento de "descripción" en el diagnóstico de **Permission's**..

***

#### Versión: 2.7.X

**Marzo 2026**

#### General

* Actualizada la versión menor del core a la 2.7.0 (SDK Main)
* La distribución mediante SPM ahora exporta binarios alojados en Artifactory. Los integradores deben incluir sus credenciales en el archivo `.netrc` para descargarlos.
* Mejorada la gestión de errores de red y el feedback hacia la app del integrador.

#### Selphi - Captura facial

* Envío del identificador de flavor del widget a la plataforma.
* Fix: el vídeo capturado no se elimina automáticamente tras guardar sus datos en el resultado.
* Añadido soporte para IAD en IDV.

#### SelphID - Captura de documento

* Feature: añadido selector de documento y país. Este selector es una vista UI personalizable que permite al usuario elegir el tipo de documento y el país emisor.
* Nuevos parámetros en **SelphIDConfigurationData**:

```
showDocumentSelector: Bool? -> valor por defecto false
enabledCountries: [String]? -> lista de países especificada en ISO2
enabledDocumentTypes: [SelphIDDocumentType]? -> valor por defecto [.ID_CARD, .PASSPORT, .FOREIGN_CARD, .DRIVERS_LICENSE]
```

#### VoiceId - Captura de voz

* Envío del identificador del widget y la versión del widget a la plataforma.

***

#### Versión: 2.6.X

**Febrero 2026**

#### General

* Actualizada la versión menor del core a la 2.6.0 (SDK Main)

#### Tracking - Conexión con la plataforma

* Corregido el parsing del mapa de **Steps**

#### Selphi - Captura facial

* Actualizada la dependencia de Selphi para resolver el problema de navegación en blanco en IAD
* Nueva versión del widget: 6.0.2

#### SelphID - Captura de documento

* Actualizada la dependencia de Core y refactorizado **SDK\_TIMEOUT**
* Añadido **DOC\_TYPE** a **FlowController extraData**
* Nueva versión del widget: 1.37.0
* Corregida referencia a archivo inexistente

#### Phingers - Captura de huellas

* Añadido soporte para detección de múltiples caras
* Refactorizado **DetectFaceServiceProtocol** para soluciones nativas y basadas en helper
* Movida la lógica de **RecognitionHelper** a su propio servicio; refactorizada la inicialización de **GlobalSettings** y **ReaderHelper**
* Corregido literal portugués para “Cancel”
* Revertido el uso del servicio Reader y restaurada la implementación legacy con funcionalidades nativas

#### VoiceId - Captura de voz

* Modificados los literales de accesibilidad (voice-over) en la pantalla de grabación para mejorar la UX

#### Video Call

* Corregido literal incorrecto para la acción Cancel en el modal “Are you sure you want to close?” para localizaciones en portugués

#### VideoID - Identificación por vídeo

* Actualizada la versión de **FPHISelphidDocumentReaderBundle** para corregir fuga de memoria
* Añadido soporte para detección de múltiples caras
* Refactorizado **DetectFaceServiceProtocol** para soluciones nativas y basadas en helper
* Movida la lógica de **RecognitionHelper** a su propio servicio; refactorizada la inicialización de **GlobalSettings** y **ReaderHelper**
* Corregido literal portugués para “Cancel”
* Revertido el uso del servicio Reader y restaurada la implementación legacy con funcionalidades nativas

#### Video Recording

* Refactorizada la gestión de errores en el método **start**
* Mejorado el manejo de errores y el reporting de tracking
* Añadido soporte para usar **integrationId** desde **TrackingConfigurationData sharedContainer** pasa a ser un parámetro opcional en lugar de implícitamente desempaquetado
* Corregido que la feature **DEMOS** no soportaba la inyección de **integrationId** en VideoRecording
* Corregido problema por el que VideoRecording se detenía tras completar NFC cuando el modal nativo de iOS se cerraba durante el flujo IDV

***

#### Versión: 2.5.X

**Diciembre 2025**

#### General

* Breaking change: **ErrorType.TIMEOUT** ha sido renombrado a **ErrorType.SDK\_TIMEOUT** (SDK Core)
* Actualizada la versión menor del core a la 2.5.0 (SDK Main)
* Los flujos IDV pueden reanudarse usando los nuevos parámetros **resumeOperationId** y **resumeSessionId** (SDK Main)

#### Tracking - Conexión con la plataforma

* Nueva versión del widget: 1.1.25
* Actualizada la versión menor del core a la 2.5.0
* Añadido soporte para **IDV Proxy**
* Añadido soporte para el step de **NFC** en IDV
* Corregido el parámetro **steps** en la función **newOperation**, que no se parseaba correctamente en algunos casos de uso
* Añadido **Privacy Manifest** para evitar errores ITMS al subir la app a App Store

#### Selphi - Captura facial

* Actualizada la versión menor del core a la 2.5.0\
  Creado nuevo flavor **FPHISDKSelphiIADComponent** para prevenir ataques de inyección

#### SelphID - Captura de documento

* Nueva versión del widget: 1.36.3
* Actualizada la versión menor del core a la 2.5.0
* Añadidos parámetros capturados al Flow para usarlos como entrada del lector NFC de documentos

#### Tokenize

* Actualizada la versión menor del core a la 2.5.0

#### Phingers - Captura de huellas

* Actualizada la versión menor del core a la 2.5.0
* Actualizada la versión mayor de **SelphID Document’s Reader (SDR)** a 2.0.0
* Refactorizado **ErrorType.TIMEOUT** a **ErrorType.SDK\_TIMEOUT**
* Nuevos modos (**VideoIdMode.DOCUMENT\_FRONT** y **VideoIdMode.DOCUMENT\_FRONT\_BACK**) para captura solo de documento

#### VoiceId - Captura de voz

* Actualizada la versión menor del core a la 2.5.0
* Refactorizado **ErrorType.TIMEOUT** a **ErrorType.SDK\_TIMEOUT**

#### Video Call

* Actualizada la versión menor del core a la 2.5.0
* Refactorizado **ErrorType.TIMEOUT** a **ErrorType.SDK\_TIMEOUT**
* Corregido evento de tracking duplicado al lanzar el diagnóstico

#### VideoID - Identificación por vídeo

* Actualizada la versión menor del core a la 2.5.0
* Actualizada la versión mayor de **SelphID Document’s Reader (SDR)** a 2.0.0
* Refactorizado **ErrorType.TIMEOUT** a **ErrorType.SDK\_TIMEOUT**
* Nuevos modos (**VideoIdMode.DOCUMENT\_FRONT** y **VideoIdMode.DOCUMENT\_FRONT\_BACK**) para captura solo de documento

#### Video Recording

* Actualizada la versión menor del core a la 2.5.0
* Refactorizado **ErrorType.TIMEOUT** a **ErrorType.SDK\_TIMEOUT**
* Añadido timestamp en la parte inferior de las grabaciones de vídeo
* Corregido que la grabación se detuviera tras finalizar la lectura NFC en flujo IDV
* Corregido crash cuando el componente se utilizaba con licencia vacía

***

#### Versión: 2.4.X

**Octubre 2025**

#### General

* Añadido **integrationId** como parámetro obligatorio (no omitible); añadido a **TrackingConfigurationData** (SDK Core)
* Eliminado evento único innecesario **sendAdvanceTracking** (SDK Core)
* Adaptadas funciones de **ITrackingController** para funcionar con flujos IDV (SDK Core)
* Creadas extensiones **Data** y **FileManager**; refactorizado **ITrackingController** (SDK Core)
* Refactorizado **NO\_OPERATION\_CREATED\_ERROR → OPERATION\_NOT\_CREATED** (SDK Core)
* Devuelto **OcrDiagnostic** en **OCR\_ERROR** en VideoID (SDK Core)
* Actualizado **LicenseChecker** a v2.3.3 (SDK Core)
* Corregidos **attributedText** y **setBold()** en **UITextView** (SDK Core)
* Devuelto **operationId** en cada **SdkFlowResult** (SDK Main)
* Actualizada dependencia Core a v2.3.3; eliminados **flowPreview** y **cache** en **GetFlowService** (SDK Main)
* Añadido **integrationId** para **VideoRecording**; evento **finish flow change\_step** (SDK Main)
* Método público para recuperar IDs y tipos de Flow; refactorizadas clases al directorio **Data** (SDK Main)
* Eliminados **activateFlow** e **iaModels** de **initSdk()**; **FlowData IDs** y **operationType** públicos (SDK Main)
* Refactorizados **SDKController** y **Flow**; **IdvLicense**; **LicensingComponent** interno (SDK Main)
* Nuevo método público de personalización; fixes para **operationId**, **customization.colors**, **licensing check**, **step reference** (SDK Main)

#### Tracking - Conexión con la plataforma

* Limpieza y refactorización del código y de los modelos internos
* Actualizados eventos de **TrackingController** y llamadas a assets; **trackingWidget v1.1.19 → v1.1.22**
* Añadido **authenticationId**; **Core v2.3.3**; **integrationId** en **configurationData**
* Eliminado evento único innecesario **sendAdvanceTracking**
* Detección automática de país en **sendDocumentData**; tracking completo de IDV
* Refactorizado **NO\_OPERATION\_CREATED\_ERROR → OPERATION\_NOT\_CREATED**; SDK v2.4.0
* Adaptado a **Tracking v1.0.16** para mejorar estabilidad

#### Selphi - Captura facial

* Widget con personalización completa; **setParam** para **UseSdkCustomization**
* Nueva versión del widget: **5.19.2**
* **AuthenticationId**; inclusión condicional de **includeClip**; **ACTIVE\_LIVENESS\_ERROR**; **livenessDiagnostic** en **SELPHI\_TIMEOUT**
* Release IDV v2.4.0; **SelfieData** para tracking IDV; **LivenessDiagnostic** en Core
* Core v2.3.3; widget y **SelphiKMP** actualizados; eliminado **cameraId**
* **sendSelfie** en success; errores unificados en Tracking; integración **SelphiKMP** y **KMP Widget**
* Refactors: lógica, gestión de errores, estructura de carpetas, **SelphiWidgetController.start()** para licencia inválida
* Fixes: **stepData**, **videoFilename**, **liveness** en Tracking, modo **MOVE**, **bestImage**, conflictos con Core

#### SelphID - Captura de documento

* Nueva versión del widget: **1.35.2**; personalización completa; **setParam** para **UseSdkCustomization**
* Adaptado a **trackingWidget v1.1.23**; **generateRawImages** por defecto **true**
* Flag de inicialización siempre **true**; fixes en **stepData** y **generateRawImages null**

#### Tokenize

* Primera release **v2.4.0**
* Establecida fuente **fpbtokenizer** desde **clienters** para comportamiento correcto de inicialización

#### Phingers - Captura de huellas

* Actualizado y adaptado al último **trackingWidget**; **SDR v1.8.0**; **trackAssets** para IDV
* **sendVideoIdData**; renombrado **matchingSidesScore**; eliminado **OcrDiagnostic** duplicado; unificado **Core OCR\_ERROR**
* Mejorado **ErrorParser**; primera versión estable **v2.4.0**; **Core v2.3.3**
* Ajustado umbral mínimo de tamaño facial para captura con mascarilla
* Fixes: **IdvResultData** solo en error terminal; **stepData**; manejo de **NETWORK ERROR**

#### VoiceId - Captura de voz

* SDK versión **5.3.0**; **ErrorParser** con **toNameError**, **toCodeError**, **toReasonError**
* Core v2.3.3; proceso **matching** deprecated (ya no soportado local matching); primera versión **v2.4.0**
* Revisión UX de layout y accesibilidad; fix en **stepData**

#### Video Call

* Actualizado y adaptado al último **trackingWidget**; **ErrorParser** (**toNameError**, **toCodeError**, **toReasonError**)
* Core v2.3.3; revisión general UX para animaciones, literales y flow
* Fixes en **stepData**; fixes en nombres de literales y animaciones

#### VideoID - Identificación por vídeo

* Actualizado y adaptado al último **trackingWidget**; **SDR v1.8.0**; **trackAssets** para IDV
* **sendVideoIdData**; renombrado **matchingSidesScore**; eliminado **OcrDiagnostic** duplicado; unificado **Core OCR\_ERROR**
* Mejorado **ErrorParser**; primera versión estable **v2.4.0**; **Core v2.3.3**
* Ajustado umbral mínimo de tamaño facial para captura con mascarilla
* Fixes: **IdvResultData** solo en error terminal; **stepData**; manejo de **NETWORK ERROR**

#### Video Recording

* Eliminado **presenter**; código retorno **VIDEO\_RECORDING\_ACTIVE**; output en **STOPVRController**
* **integrationId** en servicios; **StopVideoRecordingController** para IDV; **Core v2.3.3**
* Fixes en **stepData** y corner case con instancia activa

***

#### Versión: 2.3.X

**Junio 2025 / Julio 2025**

#### General

* **License Manager 0.5.5**; **LicenseChecker** actualizado (SDK Core)
* **AnalyticsManager** refactorizado y optimizado; **StepData** e **ITrackingController** refactorizados (SDK Core)
* Función auxiliar **Locale.swift**; **AnalyticsManager** y eventos analytics (SDK Core)
* Analytics para **Status** y **CheckPermissions**; **Core 2.3.0**; analytics en **IStatusController** (SDK Core)
* Locale/language desde **initSdk()**; **AnalyticsManager → IAnalyticsController** (SDK Core)
* Fix import **Foundation** (SDK Core)
* Renombrado **AnalyticsManager**; **License Manager 0.5.5**; **Core v2.3.2** (SDK Main)
* Cifrado IDV (desde 2.3.1); analytics completos en SDK; language desde **initSdk()** (SDK Main)
* **integrationId** opcional en **initSdk()**; **FlowPreviewController**; **FlowOffline**; operación inyectable (SDK Main)
* Refactor **AnalyticsManager → IAnalyticsController** (SDK Main)
* Fixes: inyección **initSdk**, personalización color flow, **ColorFlowKeys**, **PR #90** (SDK Main)

#### Licensing

* Core actualizado a **v2.3.2**; protocolo **HTTP → SSH**
* Fix dependencia Core cacheada durante generación

#### Tracking - Conexión con la plataforma

* **Core v2.3.2**; nuevos **TrackingWidgetErrors**; **idv** en **TrackingLicense**
* **tracking-widget-kmp v1.1.8**; interfaz **TrackingController**; **TrackingXWidgetController** para IDV
* **TrackingWidget 1.1.7 → 1.1.5**; integración mejorada de identificación de dispositivos; SPM para **FPHITrackingWidget-SPM**
* Refactor **sendAdvTracking()**; tests con IDV
* Fixes: **TrackingError public**, enum asset, background-thread, desajuste de versiones entre Core y tracking, crash **initOperation v3**, ajuste de **constraints**

#### Selphi - Captura facial

* Commit reversible con comentarios/logs para auditoría; versión accesible (SDK Main 2.3)
* **License Manager 0.5.5**; revisión completa accesibilidad; **Core v2.3.1**
* Tracking de assets vídeo con IDV; locale desde **initSdk()**; integración analytics
* Core v2.3.0; portugués; language desde **initSdk()**; event tracking desde widget
* **hasOperationCreated** antes de **createStep()**; **AnalyticsManager → IAnalyticsController**

#### SelphID - Captura de documento

* Widget **1.35.0, 1.34.7, 1.34.6**; **Core v2.3.3**; **MBSDR arm64**; **Widget 1.34.4 → 1.34.6**
* Widget **1.34.3**; scheme **MBSDR**; **SelphIDWidget 1.33.4**; naming **selphidComponent.xcframework**
* Refactor **AnalyticsManager** (reversible); **Core v2.3.2**; **Widget 1.33.1**
* Imágenes como **JPEG 95%**; tests IDV y tracking de assets vídeo; **SelphIDWidget 1.32.1 → 1.32.2**
* **Package-RGL-template**; SPM para **RGL**; **Core v2.3.0**; parsing **licenseManager**; locale del dispositivo
* Fixes: literales/animaciones, **Podfile/MBSDR**, revert analytics, compresión, **hasOperationCreated**, enums, **AnalyticsManager → IAnalyticsController**, configuración

#### Tokenize

* **Core v2.3.2, v2.3.1, v2.3.0**
* Añadida validación de datos vacíos antes de enviarlos a **Core Tokenizer** para prevenir crashes

#### Phingers - Captura de huellas

* Dependencia **Reader** y modelos; **documentFaceImageMapTokenized**; claves **OcrMap FRONT/BACK**
* **isReadyToRecord**; modo **FACE + FRONT**; **documentFullImage**; constantes **2.3.17**; tamaño reducido
* **documentQualityThreshold**, **faceQualityThreshold**; **TrackAssetsService**, **GetReaderModelsService**
* **Core v2.3.2**, **Reader v1.5.0**; **DetectDocumentService** y OCR; animaciones y UX; **UIFontMetrics**
* Dependencias **SDR**; lógica cambio de lado; overlay captura documento; captura voz; **Core Analytics v2.3.0**
* Catalán, Portugués (PT/BR), Español; fixes FRONT/BACK, background thread, memory leaks, capturas, literales, **AnalyticsManager → IAnalyticsController**

#### VoiceId - Captura de voz

* **Core v2.3.2**; **UIFontMetrics** para escalado dinámico de texto; analytics y eventos tracking
* **Core v2.3.0**; fix Lottie; logging del componente; **Voices SDK**; unificado con Android
* Control previo de tips y feedback háptico; fix **hasOperationCreated** antes de **createStep**; **AnalyticsManager → IAnalyticsController**

#### Video Call

* **2.3.5**: reducción tamaño componente y peso binario; mejora screen sharing; fix mute durante screen sharing
* **2.3.3**: **Core v2.3.2**
* **2.3.2**: **UIFontMetrics**; fix **hasOperationCreated** y **fromNib main thread**; **AnalyticsManager → IAnalyticsController**
* **2.3.0**: analytics en SDK; **Core v2.3.0**; unificado con Android; Catalán y Portugués; language desde **initSdk()**; mejoras layout

#### VideoID - Identificación por vídeo

* Dependencia **Reader** y modelos; **documentFaceImageMapTokenized**; claves **OcrMap FRONT/BACK**
* **isReadyToRecord**; modo **FACE + FRONT**; **documentFullImage**; constantes **2.3.17**; tamaño reducido
* **documentQualityThreshold**, **faceQualityThreshold**; **TrackAssetsService**, **GetReaderModelsService**
* **Core v2.3.2**, **Reader v1.5.0**; **SDR**; lógica cambio lado; overlay captura documento; captura voz; **Core Analytics v2.3.0**
* Catalán, Portugués (PT/BR), Español; fixes FRONT/BACK, background thread, memory leaks, capturas, literales, **AnalyticsManager → IAnalyticsController**

#### Video Recording

* Timestamp en metadata de grabación; **Core v2.3.2**; servicio **stopCapture**
* Eliminada referencia **Resources** y extensión screen recording; **Core v2.3.1**
* Eventos: **COMPONENT\_START**, **STOP**, modal permiso screen sharing; **Core v2.3.0**
* Fix nombre componente, modal permisos; **AnalyticsManager → IAnalyticsController**

***

#### Versión: 2.2.X

**Enero 2025 / Marzo 2025**

#### General

* Actualizaciones **ThemeManager** y **UIView**; **LicenseChecker v2.2.0**; **SdkColor** con **UIColor** (SDK Core)
* **StepData** y **stepData** en **ITrackingController**; **sendAdvanceTracking** (SDK Core)
* Fix **Test.podspec 2.2.1**, **UIColor(hex:)**; limpieza interfaz **Status** (SDK Core)
* Personalización interfaz Flow (SDK Core 2.1); fix **IDiagnosticView Main Thread** (SDK Core 2.1)
* Actualizado **Core v2.2.2**; licensing; **PR #89**; **Tracking StepData screensharing** (SDK Main)
* Eliminado **flow preview**; **json → jsonX**; fix persistencia configuración flow; manifest **Package-template** (SDK Main)
* **fix\_customization\_flow**; revert cambios incorrectos; eliminada lógica **flow preview**

#### Licensing

* Estabilidad Core y **v2.2.0**; eliminada lógica validación success/failure
* Fix **Tracking StepData screensharing**

#### Tracking - Conexión con la plataforma

* **XCFrameworks v1.1.0 → v1.1.2**; constantes **2.2.1**; **sendAdvanceTrackingEvent()**
* Nuevo parámetro debug; dos nuevos errores widget; **Core v2.2.0**
* **TrackingControllerKMP**; widget KMP; **trackingWidget v1.0.1**; **LocationManager**
* Refactor **TrackingError**; workaround Core antiguo
* Fixes: crash **advanceTracking()**, **setTrackingError before start()**, compilación, race condition, **tenantId private**

#### Selphi - Captura facial

* Idioma por defecto = dispositivo; flash cámara trasera; **Core (SM-4399)**; **Widget v5.16.3**
* **Back Camera MOVE mode**; **cameraPreferred**; **SelphiWidget v5.16.0**
* Lotties accesibles; navegación y feedback; **PR #74 UX**; wrapping errores
* **RawTemplateWidgetController**; **FPBLivenessDiagnostic**; Advance Tracking; **Core v2.2.0**
* Personalización animaciones; **PR #69 literal/UI**; **TutorialTipsConfigurationData** y constantes
* Fixes: launch background thread, navegación, crashes captura widget

#### SelphID - Captura de documento

* **Core v2.2.2**; **SelphIDWidget v1.31.0 → v1.31.2**; Lotties accesibles
* **dismissViewController**; producto/workspace **MLRGL**; **Core v2.2.1**; parámetros VISA
* **Widget v1.27.2 → v1.28.1**; **SDR v0.32.2**; **Widget v1.27.0**; **TVeryLong → VERY\_LONG**
* **selphIDResult.statistics** para demo Advance Tracking; botón info tutorial; personalización completa
* **Core v2.2.0**; flow solo tutorial
* Fixes: puntero **MLRGL**, **StepData screensharing**, **Widget v1.28.2**

#### Tokenize

* Última versión **FPBTokenizer**; compatibilidad Core; dependencia Tokenizer y breaking changes; **Core v2.2.0**
* Fix error **Tracking StepData** durante screensharing

#### Phingers - Captura de huellas

* **autoFaceDetection** y botón cámara; selección cámara y fuentes custom; progress bar y UX
* Dark Mode; navegación diagnósticos; refactor **VideoIdSteps**
* Timeout e imagen color custom; fallback timeout 3 segundos; rotación imagen y **StepData**
* **Core v2.2.0**; detección facial y modo sin tutorial; literales
* Fixes: **cameraPreferred**, pasos UI, conflictos Core, **successResponse**, literales detección facial y firma

#### VoiceId - Captura de voz

* Core actualizado; soporte color Dark Mode; parámetro **minSpeechLength**
* Logs y checks micrófono; warning **MultipleSpeakers** si **enableQualityCheck = false**
* **Voice SDK v4.1.0**; animaciones custom; refactor tutorial (flow basado en estado)
* Timeouts y dismiss solo en **retryAction**
* Fixes: navegación **TIMEOUT**, cancel/restart recording, **StepData screensharing**, **VoiceEnvironment**, **PrivacyInfo.xcprivacy**

#### Video Call

* **2.2.5**: Core latest; fuentes custom y toggle cámara; **VideoCallController**; colores modo e iconos; **timeoutDispatcher**
* **2.2.3**: pantalla retry y recuperación conexión; finalizar call cuando agente sale; color imagen custom; valores timeout
* Fixes: **StepData screensharing**, dismiss, false success tracking
* **2.2.0**: **Core v2.2.0**; **extensionName → extensionIdentifier** (breaking); eventos hangout
* Fixes switch, crash diagnósticos, timeout timer, **disableAudio()**

#### Versión: 2.1.X

**Agosto 2024 / Septiembre 2024 / Octubre 2024**

#### General

* Personalización de la interfaz **Flow** (SDK Core)
* Añadido **Selphix Step** (SDK Main)

#### Licensing

* Adaptado a **Core v2.1.X**

#### Tracking - Conexión con la plataforma

* **sdkVersion** en **initOperation**; constantes **2.1.1**; **Core v2.1.X**
* Retry en **sendEvents()**; timestamp **AssetResponse Int/String**; **apiKey** en **TrackingLicense** y **Api.shared**
* Headers HTTP; eliminado **token** (**Api.shared**); detalles **PayloadModel**
* Fixes: parsing, recursión **ITrackingController**, race condition, **libraryPackageVersion**, merge conflicts

#### Selphi - Captura facial

* **CommonCustomization**; **SelphiTheme**; tutorial y tips; **LivenessDiagnostic** en **SelphiResult**
* **Core v2.1.X**; i18n a Core; **RawTemplate tokenizeController**
* Fixes: jerarquía diagnóstico, race **SignatureProof**, compilación, Lotties, accesibilidad, **MOVE (PR #54)**

#### SelphID - Captura de documento

* **SelphID 1.26.X**; **SelphIDRGLComponent** vía Pods; **CommonCustomization**
* Animación health y accesibilidad; **Widget v1.25.1**, constantes **v2.0.10**
* **Core v2.1.X**; **SignatureProof**; **Main Thread** para widget; tip tutorial previo
* Fixes: **diagnosticViewController**, captura, compilación, nombres Lottie, **Liveness MOVE**

#### Tokenize

* Adaptado a **Core v2.1.X**; implementaciones movidas a extensión **Interface** para modularidad

#### Phingers - Captura de huellas

* **Core v2.1.X**; colores custom, animaciones, labels accesibilidad; área vídeo expandida; paleta neutral
* Fixes: casing localización, race chained tracking, nombre animación y gestión permisos

#### VoiceId - Captura de voz

* **Core v2.1.X**; chained tracking; **showTutorial = true** por defecto; paleta neutral y constantes
* Nuevos Lotties, labels accesibilidad, tags; mínimo iOS **11 → 13**; color y tint iconos
* **enableCheckQuality**; frases en entorno; eliminado código duplicado; métodos Core; accesibilidad
* Fixes: permisos y reproducción audio; **UIView\.fromNib** en main thread

#### Video Call

* **CommonCustomization** y **themeFlow**; screen sharing y control **shareScreen**
* Lotties custom, personalización color, tint iconos; timeout llamadas largas; **Core v2.1.X**
* Fixes: pantalla permisos, prevención landscape, switch cases, unwrap vistas, **Package.swift** y template

#### VideoID - Identificación por vídeo

* **Core v2.1.X**; colores custom, animaciones, labels accesibilidad; área vídeo expandida; paleta neutral
* Fixes: casing localización, race chained tracking, nombre animación y gestión permisos

#### Video Recording

* **Core v2.1.X**; **CommonCustomization**; **SdkResult** en success; eliminadas extensiones **String**
* Fix broadcast no iniciaba; stop recording fuera del lifecycle app

***

#### Versión: 2.0.X

**Abril 2025 / Mayo 2024 / Junio 2024**

#### General

* **FPHISDKLicenseCheckerComponent 2.0.0**; diagnóstico **IStatusController** y tutorial (SDK Core)
* Refactor **launchDiagnostic(...)**; **launchTutorial()** (SDK Core)
* Actualizaciones **ErrorType**; **NO\_DATA\_ERROR**; **LICENSE\_CHECKER\_ERROR(String)**; **MISSING\_COMPONENT\_LICENSE\_DATA** (SDK Core)
* Adaptado a **Core v2.0.0** (SDK Main)

#### Licensing

* Dependencias y constantes alineadas con **Core v2.0.0**

#### Tracking - Conexión con la plataforma

* **Privacy Manifest** y campos privacidad; localización **privacyInfo**; **Core v2.0.0**; bundle **.xcprivacy**
* Check SIM condicional — **nil** en iOS **16+**

#### Selphi - Captura facial

* **bestImageTokenized**; retry en timeout; **logImages**; **Core v2.0.0**; **Privacy Manifest**
* Validación licencia y propagación errores
* Fix nombre step **SIGNATURE\_SELPHI\_CONTROLLER → SIGNATURE\_SELPHI\_COMPONENT**
* Callbacks licencia; **TrackAssetType.SELPHI\_SIGNATURE**

#### SelphID - Captura de documento

* **SelphIDWidget v1.24.3 – v1.25.0**; retry en timeout; accesibilidad front/back tras timeout
* Constantes **v2.0.6**; **DocumentReader v7.1.X**; **Privacy Manifest**; **FPhiSelphIDWidgetiOSSim v1.23.3**
* Fixes: permisos, **selphidwidgetiosSim → selphidwidgetios**, **defaultLocalization**, frecuencia tutorial, mensaje instruccional

#### Tokenize

* **FPBTokenizer v2.0.8**; **bestImageTokenized**; dependencias y **Core v2.0.0**

#### Phingers - Captura de huellas

* Widget y constantes **v2.0.0**; **Privacy Manifest** y **.xcprivacy**; **Core v2.0.0**, **Streaming de Video v4.3.0**, **Lottie v4.4.0**
* Gestión errores (vídeo y documento en logs); retry en timeout
* Fixes: race en librería de **streaming de video**, vídeo en blanco y secuencia step flow, init background thread, UX (firma, dark mode, permisos)

#### VoiceId - Captura de voz

* **Privacy Manifest**; **Core v2.0.0**; constantes; **streaming de video a versión 4.3.0** y **Lottie 4.4.0**
* **VoiceEnrollmentResult**
* Fixes: timing display frase, retry timeout, callback y stop recording, localización **privacy info**

#### Video Call

* **Privacy Manifest** y localización; **Core v2.0.0**; constantes **v2.0.0**
* Bundle **.xcprivacy**; **streaming de video a v4.3.0**, **Lottie v4.4.0**
* Fixes: **appId** desde socket response; icono flecha cierre desactualizado

#### VideoID - Identificación por vídeo

* Widget y constantes **v2.0.0**; **Privacy Manifest** y **.xcprivacy**
* **Core v2.0.0**, **streaming de video a v4.3.0**, **Lottie v4.4.0**
* Gestión errores (vídeo y documento en logs); retry timeout
* Fixes: race en librería de **streaming de video**, vídeo en blanco y secuencia step flow, init background thread, UX (firma, dark mode, permisos)

#### Video Recording

* **streaming de video** y constantes; **Privacy Manifest** y **.xcprivacy**
* **Core v2.0.0** y **streaming de video en v4.3.0**
* **UserDefaults reason** en **PrivacyInfo**
* Dependencias menores
* Fix errores sesión grabación; upgrade de **streaming de video** temporalmente **v4.3.0** hasta **v4.3.1**

***

#### Versión: 1.5.X

**Marzo 2024 / Abril 2024**

#### General

* Tutorial **Status**; gestión errores (SDK Core)
* Nuevos eventos y **getExtraParams()**; **signatureProofEvent**; **checkPermissionStatus**; hápticos (SDK Core)
* **IStatusableController**, **IFlowController**, **IFlowableController**; **SdkColor**; **ICustomizableController** (SDK Core)
* **retryAction → secondaryAction**; eliminado **PersonalData**
* **IMethodableController** extiende **ITokenizableController**
* **startNextController SdkResult**; **dataString** en **IConfigurableController**
* **Core 1.5.8**; **Flow v2**; **FlowController**; gestión errores (SDK Main)
* **FlowConfigurationData**; **SdkFlowResult**; **cancelFlow()**; **IStatusController**
* **GetModels IA\_OCR**, **iaModels**; **GetFlowConfiguration**, **GetFlowPreviewConfiguration**
* **ExternalStepController**
* **onlineFlow**; **FlowController.controllers**; **flowOutput unified**
* Eliminado **newOperation** de **FlowConfigurationData**
* **activateFlow**; **launchNextStep public**
* **cancelFlow automatic**
* **enableTracking**
* IDs y targets
* Personalización
* Fixes: **LICENSE\_CHECKER\_ERROR initSdk**, **flowOutput n+1**, orden steps

#### Licensing

* **Core v1.5.6**
* Referencias **Core v1.5.0**
* Gestión errores

#### Tracking - Conexión con la plataforma

* **Core v1.5.8**
* Arquitectura tracking y flow eventos
* **Core v1.5.0**
* Nuevos eventos plataforma
* **osName "iOS"**
* Parámetros **Payload**
* **signatureProofEvent**
* Eliminado **PersonalData**
* Fix evento firma, **OCR\_DATA**, **newOperation setupToken**

#### Selphi - Captura facial

* **SignatureSelphi** extiende controller principal
* **Core v1.5.8**
* Flow y eventos
* **SignatureSelphiController**
* Eventos plataforma
* **vibrationEnabled**
* Hápticos
* **SelphiConfigurationData** desde JSON
* Inicializador **RawTemplateController Data**
* **SelphiFaceLivenessMode.MOVE**
* **extractionTimeout min/max**
* Defaults: **showTutorial**, **showDiagnostic**, **showResultAfterCapture**, **debug**
* Sin fallback ZIP por defecto
* Fix inicialización **RawTemplateController**

#### SelphID - Captura de documento

* **Core v1.5.8**
* **FPhiSelphIDWidgetiOSSim**
* **arm64** y **arm64-simulator**
* Nuevos eventos plataforma
* **extractionTimeout min/max**
* Sin ZIP por defecto
* **Widget 1.23.2**
* Fix **CANCEL\_BY\_USER** con **showDiagnostic == true**

#### Tokenize

* **Core v1.5.8**
* Compatibilidad **Core v1.5.6**
* Referencias **Core v1.5.0**
* Gestión errores

#### Phingers - Captura de huellas

* **SignatureVideoId** y gestión errores red
* **HapticNotification** y vibración
* **Starscream** y constantes
* **Core v1.5.6** y configuraciones
* Core y constantes
* Pantallas diagnóstico y configuración flow
* Progress bar por step
* Inicialización configuración basada en JSON
* Fixes: naming step tracking, URL/API/Tenant null o vacío, timeout y restart firma, literales y payload

#### VoiceId - Captura de voz

* Cambios mayores funcionales y UI
* **Core v1.5.8**
* Interacción usuario y feedback
* Controller extiende **IFlowableController**
* **IStatusController**
* **showDiagnostic**
* **vibrationEnabled**
* **FPHIVoiceSDK v3.13.0**
* Eventos plataforma
* Timeout **60000 → 30000 ms**
* Hápticos
* **RecorderView**
* **startRecording viewDidLoad**
* **extractionTimeout min/max**
* Sistema gestión errores

#### Video Call

* **1.5.9**: **Core v1.5.8**; permisos cámara y diagnóstico; estabilidad y control flow; eventos plataforma; **IStatusController**; hápticos y **vibrationEnabled**; diagnóstico y permisos vía **StatusController**; validación red; **extractionTimeout**; fixes URL/apiKey/tenantId null
* **1.5.0**: controller extiende **IFlowableController**; sistema gestión errores

#### VideoID - Identificación por vídeo

* **SignatureVideoId** y gestión errores red
* **HapticNotification** y vibración
* **Starscream** y constantes
* **Core v1.5.6** y configuraciones
* Core y constantes
* Pantallas diagnóstico y configuración flow
* Progress bar por step
* Inicialización configuración basada en JSON
* Fixes: naming step tracking, URL/API/Tenant null o vacío, timeout y restart firma, literales y payload

#### Video Recording

* **Starscream 4.0.8**
* **Core v1.5.4**, **v1.5.6**, **v1.5.8**
* Estabilidad y flow
* Nuevos eventos de plataforma: **VideoRecordingComponent**


# Changelog ENG


# Framework plugins

Además de los SDKs nativos, Facephi proporciona plugins oficiales para facilitar la integración en aplicaciones híbridas y multiplataforma.

Actualmente ofrecemos soporte para los siguientes entornos:

* [Cordova](/sdks/sdk-mobile/framework-plugins/cordova)
* [Flutter](/sdks/sdk-mobile/framework-plugins/flutter)
* [React Native](/sdks/sdk-mobile/framework-plugins/react-native)
* [Capacitor](/sdks/sdk-mobile/framework-plugins/capacitor)

***

### ¿Por qué usar los Framework Plugins?

* Integración rápida en proyectos híbridos.
* Soporte para verificación biométrica en iOS y Android.
* Reducción de complejidad técnica al evitar el uso directo de SDKs nativos.
* Documentación y ejemplos adaptados a cada plataforma.

***

### Requisitos generales

Antes de integrar un plugin híbrido:

* Verifica los Requisitos mínimos de SDK Mobile.
* Asegúrate de cumplir las versiones mínimas requeridas por cada framework (ver secciones específicas).
* Obtén tus credenciales de desarrollador desde el Portal de Administración.

***

### Siguiente paso

Elige la plataforma que deseas integrar:

* [Cordova](/sdks/sdk-mobile/framework-plugins/cordova)
* [Flutter](/sdks/sdk-mobile/framework-plugins/flutter)
* [React Native](/sdks/sdk-mobile/framework-plugins/react-native)
* [Capacitor](/sdks/sdk-mobile/framework-plugins/capacitor)

Para dudas adicionales, contacta al Soporte Técnico.

| Framework    | Documentación técnica | Changelog                                                                  |
| ------------ | --------------------- | -------------------------------------------------------------------------- |
| Cordova      | Guía Cordova          | [Ver changelog](/sdks/sdk-mobile/framework-plugins/cordova/changelog)      |
| Flutter      | Guía Flutter          | [Ver changelog](/sdks/sdk-mobile/framework-plugins/flutter/changelog)      |
| React Native | Guía React Native     | [Ver changelog](/sdks/sdk-mobile/framework-plugins/react-native/changelog) |
| Capacitor    | Guía Capacitor        | [Ver changelog](/sdks/sdk-mobile/framework-plugins/capacitor/changelog)    |


# Cordova

Facephi proporciona un plugin oficial para Cordova que permite integrar la SDK Mobile en aplicaciones híbridas, siendo compatible tanto con plataformas Android como iOS.

### ¿Por qué usar el plugin Cordova?

* Integración rápida en aplicaciones híbridas.
* Acceso sencillo a los flujos biométricos de Facephi desde JavaScript.
* Evita la complejidad de gestionar SDKs nativos en cada plataforma.

***

### Índice de contenidos

* [Instalación](/sdks/sdk-mobile/framework-plugins/cordova/instalacion)\
  Cómo instalar y configurar el plugin en tu proyecto Cordova.
* [Ejemplos de uso](/sdks/sdk-mobile/framework-plugins/cordova/ejemplos-de-uso)\
  Casos prácticos para realizar procesos de verificación de identidad.
* [Changelog](/sdks/sdk-mobile/framework-plugins/cordova/changelog)\
  Historial de versiones y actualizaciones importantes.
* [Componentes/módulos](/sdks/sdk-mobile/framework-plugins/cordova/componentes)

  Más información acerca de los productos incluidos en la SDK.

***

### Requisitos previos

Antes de comenzar, asegúrate de cumplir los Requisitos mínimos de SDK Mobile.

¿Listo para integrar Facephi en tu app híbrida? Comienza por la Guía de instalación.


# Instalación

Integra las soluciones biométricas de Facephi en tus aplicaciones híbridas basadas en Cordova, de forma rápida y compatible con iOS y Android.

### Requisitos previos

Antes de integrar el plugin de Facephi para Cordova, verifica que cumples con:

* Cordova CLI versión 11 o superior.
* Proyecto configurado para Android (AGP 8.9.x y Kotlin 2.2.x) y/o iOS (13+).
* Tener configurados los permisos de cámara y conexión a internet.
* Acceso a tus credenciales desde el Portal de Administración.

***

### Instalación del plugin

Ejecuta el siguiente comando en la raíz de tu proyecto Cordova:

```bash
cordova plugin add @facephi/sdk-<pluginName>-cordova@<versión>
```

Reemplaza `<versión>` por la última versión disponible que puedes consultar en el Changelog, y `<pluginName>` con el nombre del componente a instalar.

Este comando descarga e instala el plugin oficial de Facephi compatible con Android e iOS. Si no se agrega el @\<version>, Cordova busca en los repositorios de Facephi la última versión disponible.

***

## Configuración adicional

### Guía de instalación nativa para Android: <a href="#android" id="android"></a>

{% content-ref url="/pages/tc6Zady978xIFiZBoWnZ" %}
[Android](/sdks/sdk-mobile/framework-plugins/extras/android)
{% endcontent-ref %}

***

### Guía de instalación nativa para iOS:

{% content-ref url="/pages/Fwjszqg04wLRrI05uyVW" %}
[iOS](/sdks/sdk-mobile/framework-plugins/extras/ios)
{% endcontent-ref %}

***

### Próximos pasos

* Revisa los *Ejemplos de uso* para implementar flujos de verificación.
* Consulta el *Changelog* para conocer las últimas versiones y cambios.
* Profundiza en la funcionalidad de la SDK en la sección *Componentes*/módulos[.](/sdks/sdk-mobile)
* Si tienes dudas, contacta con el Soporte Técnico.


# Ejemplos de uso

A continuación, te mostramos ejemplos prácticos de cómo utilizar el plugin oficial de Facephi en tus aplicaciones híbridas basadas en Cordova.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

{% embed url="<https://github.com/facephi/sdk-mobile-cordova-samples>" %}

***

### Recomendaciones de integración

* Realiza pruebas completas en entorno `sandbox` antes de ir a producción.
* Verifica que los permisos de cámara e internet estén correctamente configurados.
* Valida los resultados de verificación siempre en backend, nunca solo en cliente.
* Actualiza el plugin a la última versión disponible consultando el Changelog.

Para dudas adicionales, contacta con nuestro Soporte Técnico.


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del plugin oficial de Facephi para Cordova. Se recomienda mantener siempre tu integración actualizada a la última versión estable, especial

### Última versión

**Versión:** 2.12.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* SDK nativa 2.12.0.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.11.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* SDK nativa 2.11.0.
* SelphID (MBSDR): nuevo parámetro de configuración `encodedDataFocusEnabled` y nuevos campos de resultado `encodedDataImages` y `tokenEncodedDataImages` para la lectura de códigos de barras. Uso opcional y retrocompatible.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.10.x\
**Fecha:** 08/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Sin cambios en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.9.x\
**Fecha:** 06/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+

***

**Versión:** 2.8.x\
**Fecha:** 05/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Fix memory leak en iOS. Se agrega el parámetro de configuración enableLocation en el sdk Core.

***

**Versión:** 2.7.x\
**Fecha:** 04/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Se elimina en parámetro enableSecurityMode del componente CORE. Ahora el mismo pasa a ser siempre true.

***

**Versión:** 2.6.x\
**Fecha:** 02/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+

***

**Versión:** 2.5.x\
**Fecha:** 12/2025

**Novedades:**

* API Android Version: 36
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+

***

**Versión:** 2.4.x\
**Fecha:** 11/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 2.1.21

***

**Versión:** 2.3.x\
**Fecha:** 10/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 1.9.x

***

**Versión:** 2.2.x\
**Fecha:** 09/2025

**Novedades:**

* API Android Version: 34
* Android Gradle Plugin(AGP) 8.3.2
* Kotlin 1.9.x

***

### Notas adicionales

Para reportar problemas o dudas, contacta con nuestro Soporte Técnico.


# Componentes

Plugins disponibles para el framework Cordova.

Componente principal - Core

{% content-ref url="/pages/jd5Fo3lsaQ6YbQY5cpn8" %}
[Componente principal](/sdks/sdk-mobile/framework-plugins/cordova/componentes/componente-principal)
{% endcontent-ref %}

Componente de captura facial - Selphi

{% content-ref url="/pages/PhC6AXlD6sgrDDQfNUNq" %}
[Captura facial - Selphi](/sdks/sdk-mobile/framework-plugins/cordova/componentes/captura-facial)
{% endcontent-ref %}

Componente de captura de documento - SelphID

{% content-ref url="/pages/nfAf5OFpiDq03x4Jt8h3" %}
[Captura de documentos - SelphID](/sdks/sdk-mobile/framework-plugins/cordova/componentes/captura-de-documentos)
{% endcontent-ref %}


# Componente principal

Es el componente mas importante del sdk, ya que contiene las librerías necesarias para que funcione todo de manera correcta.

La instalación del **Core** **Plugin** es obligatoria, independientemente de los productos que se requieran utilizar y del caso de uso que se haya definido. Contiene funcionalidades básicas para el funcionamiento de la SDK, además de otras funcionalidades transversales y necesarias para los plugins auxiliares.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cordova:

```swift
cordova plugin add @facephi/sdk-core-cordova@<versión>
```

### Android - Gradle:

```kotlin
api "com.facephi.androidsdk:sdk:$version"
api "com.facephi.androidsdk:core:$version"
implementation "com.facephi.androidsdk:tracking_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKMainComponent', '~> $version'
s.dependency 'FPHISDKTrackingComponent', '~> $version'
s.dependency 'FPHISDKLicensingComponent', '~> $version'
s.dependency 'FPHISDKTokenizeComponent', '~> $version'
s.dependency 'FPHISDKStatusComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>launchInitSession</td><td>Controlador principal del componente, que se encarga de validar las licencias entre otras cosas.</td></tr><tr><td>launchInitOperation</td><td>Método que se encarga de generar una nueva operación. El id de la misma se recupera en el objeto de resultado, parámetro data.</td></tr><tr><td>launchGetExtraData</td><td>El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el <em>Servicio de Validaciones de Facephi</em> (Backend).</td></tr><tr><td>launchCloseSession</td><td>Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización.</td></tr></tbody></table>

### launchInitSession <a href="#id-2-inicializacion-de-la-sesion" id="id-2-inicializacion-de-la-sesion"></a>

Antes de poder utilizar cualquier componente, se deberá inicializar la sesión de la SDK. Esta inicialización se debe hacer lo más pronto posible, preferentemente al inicio de la aplicación. Al mismo tiempo, una vez terminadas todas las operaciones con la SDK Mobile, deberá cerrarse igualmente la sesión.

Se puede inicializar el componente actual de dos formas, dependiendo de cómo desees inyectar la licencia.

El nuevo método de licenciamiento permite gestionar las licencias de forma transparente para el integrador. La licencia se puede inyectar de dos maneras:

* a. Obteniendo la licencia a través de un servicio mediante una URL y API-KEY
* b. Inyectando la licencia directamente como String

En ambos casos, el resultado se devolverá por medio de una *Promise*, la cual contiene un objeto de la clase **CoreResult**.

```javascript
exports.launchInitSession = function (cfg) {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [{
                config: cfg
            }];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkCore', 'launchInitSession', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitSessionConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitSessionConfiguration {
    license?: string;
    licenseUrl?: string;
    licenseApiKey?: string;
    enableTracking?: boolean;
    enableFlow?: boolean;
    enableSecurityMode?: boolean;
    internalOptions?: Record<string, string>;
    locale?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ZiEkZXjLq8M6NL0zUogw" %}
[Init Session Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-session-configuracion)
{% endcontent-ref %}

***

### launchInitOperation <a href="#id-3-inicializacion-de-la-operacion" id="id-3-inicializacion-de-la-operacion"></a>

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método *launchInitOperation*

```javascript
exports.launchInitOperation = function (cfg) {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [{
                config: cfg
            }];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkCore', 'launchInitOperation', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitOperationConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitOperationConfiguration {
    type: SdkOperationType;
    steps?: string[];
    customerId: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/TDD3HgSYFGVXXpt1Tp9O" %}
[Init Operation Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-operation-configuracion)
{% endcontent-ref %}

***

### launchCloseSession <a href="#id-6-cierre-de-sesion" id="id-6-cierre-de-sesion"></a>

Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización. Para ello, se ejecuta el siguiente fragmento de código:

```javascript
exports.launchCloseSession = function (cfg) {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [{
                config: cfg
            }];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkCore', 'launchCloseSession', config);
    });
};
```

***

### launchGetExtraData <a href="#id-7-metodo-extradata" id="id-7-metodo-extradata"></a>

El método *getExtraData* permite generar los identificadores necesarios para una operación que deba continuar en el *Servicio de Validaciones de Facephi* (Backend). Esta situación suele darse en casos en los que, una vez obtenida la información necesaria en la aplicación del cliente, se deba enviar esa información a un determinado servicio para su posterior validación o análisis. En caso de que deban trackearse los resultados de esos procesos en la Plataforma, ésta deberá ser capaz de unificar la primera parte del proceso realizada en cliente con la última realizada en el servicio, ya que al final forman parte de la misma operación.

```javascript
exports.launchGetExtraData = function () {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkCore', 'launchGetExtraData', config);
    });
};
```

## Lanzamiento de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El proceso de IDV permite lanzar un flujo configurado en la plataforma a partir de su ID (flowID). Para ello se necesitará invocar dos métodos: **launchInitFlow + launchStartFlow**.

### launchInitFlow

En éste método se seteará la configuración necesaria. El ID del flujo configurado en la plataforma (flowID) y el ID del cliente (customerID). Véase código:

```dart
await facephi.plugins.sdkcore.launchInitFlow({
     "customerId": "cordova@facephi.com",
     "flow": "f40c098c-a878-4976-aef1-xxxxxxx"
})
```

Para configurar el controlador de flujos, se creará un listado de los controladores de los componentes que van a participar en el proceso, lo cual permite inicializarlos correctamente. El orden en el que se definan no es importante, será el propio flujo el que indique el orden en el que se ejecutarán. Por ejemplo:

* **setSelphiFlow**: Captura facial
* **setSelphidFlow**: Captura de documentos

Código para el lanzamiento:

```javascript
/* Los resultados se escuchan implementando un listener */
setTimeout(function()
{
    if (typeof facephi.plugins.sdkcore !== "undefined")
    {
        facephi.plugins.sdkcore.startListeningTrackingEvents(
            (event) => {
                console.log('📡 startListeningTrackingEvents recibido:', event);
            },
            (err) => {
                console.error('❌ Error:', err);
            }
        );
        facephi.plugins.sdkcore.startListeningFlowEvents(
            (event) => {
                console.log('📡 startListeningFlowEvents recibido:', event);
            },
            (err) => {
                console.error('❌ Error:', err);
            }
        );
    }
}, 2000);

await facephi.plugins.sdkcore.launchInitFlow({
     "customerId": "cordova@facephi.com",
     "flow": "f40c098c-a878-4976-aef1-xxxxxxx"
 })
.then(
    async (result) =>
    {
        if (parseInt(result.finishStatus) == SdkMobileFinishStatus.Ok)
        {
            console.log("launchInitFlow result", result);
            await facephi.plugins.sdkselphid.setSelphidFlow()
            .then(
                (result) => { console.log("setSelphidFlow result", result); },
                (err) => console.log(err),
            );
            await facephi.plugins.sdkselphi.setSelphiFlow()
            .then(
                (result) => { console.log("setSelphiFlow result", result); },
                (err) => console.log(err),
            );
            await facephi.plugins.sdkselphi.setSignatureSelphiFlow()
            .then(
                (result) => { console.log("setSignatureSelphiFlow result", result); },
                (err) => console.log(err),
            );
            
            /* Al final de agregar los flujos, se lanza el launchStartFlow(Siempre que los métodos anteriores no fallen) */
            await facephi.plugins.sdkcore.launchStartFlow()
            .then(
                (result) => { console.log("launchStartFlow result", result); },
                (err) => console.log(err),
            );
        }
    },
    (err) => console.log(err),
);
```

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento de ***TODOS*** los métodos devolverá la información en formato **CoreResult**. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

<pre class="language-typescript"><code class="lang-typescript"><strong>export interface CoreResult {
</strong>    finishStatus: number;
    finishStatusDescription?: string;
    errorType: string;
    errorMessage?: string;
    data?: string;
}
</code></pre>

{% content-ref url="/pages/OfulgTvj6HOIQTMcT4M1" %}
[Core Resultado](/sdks/sdk-mobile/framework-plugins/extras/core/core-resultado)
{% endcontent-ref %}


# Captura de documentos - SelphID

Versión 2.3.X

La captura de documentos se realiza con el ***SelphID Plugin***.

Este componente se encarga de realizar capturas de documentos de identidad y del análisis de los datos obtenidos. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la parte frontal y trasera del documento.
* Extracción de la información contenida en el documento.
* Obtención de las imágenes del dorso y reverso del documento, así como otras imagénes incluidas en el documento: cara del usuario, firma del usuario,...
* Alto nivel de configuración: diferentes países, idiomas, tipos de documentos...

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cordova:

```swift
cordova plugin add @facephi/sdk-selphid-cordova@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

### iOS - Cocoapods:

```swift
pod 'FPHISDKSelphIDComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>launchSelphID</td><td>Controlador principal de captura de documentos</td></tr></tbody></table>

## Método launchSelphID <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```javascript
exports.launchSelphID = function (cfg) {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [{ config_id: cfg }];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkSelphid', 'launchSelphID', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphIDConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface SelphIDConfiguration 
{
    wizardMode?: boolean;
    documentSide: SelphIDDocumentSide;
    resourcesPath: string;
    debug?: boolean;
    showResultAfterCapture?: boolean;
    showTutorial?: boolean;
    tutorialOnly?: boolean;
    scanMode?: SelphIDScanMode;
    specificData?: string;
    fullscreen?: number;
    tokenImageQuality?: number;
    documentType?: SelphIDDocumentType;
    timeout?: SelphIDTimeout;
    tokenPrevCaptureData?: string;
    generateRawImages?: boolean;
    imageQuality?: number;
    compressFormat?: SelphIDCompressFormat;
    documentModels?: string;
    params?: any;
    showDiagnostic?: boolean;
    cameraId?: number;
    translationsContent?: string;
    viewsContent?: string;
    showPreviousTip?: boolean;
    vibrationEnabled?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/4rojYcN122t2mIdLaHZi" %}
[SelphID Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SelphIDResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface SelphIDResult 
{
    finishStatus: number;
    finishStatusDescription: string;
    errorType: string;
    errorMessage?: string;
    frontDocumentImage?: string;
    backDocumentImage?: string;
    faceImage?: string;
    signatureImage?: string;
    fingerprintImage?: string;
    documentData?: string;
    tokenFrontDocument?: string;
    tokenBackDocument?: string;
    tokenFaceImage?: string;
    tokenOCR?: string;
    documentCaptured?: string;
    captureProgress: number;
    matchingSidesScore: number;
    rawFrontDocument?: string;
    rawBackDocument?: string;
    tokenRawFrontDocument?: string;
    tokenRawBackDocument?: string;
    lastActionBeforeCapture?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/p4OH5L15yiLpD3JANudF" %}
[Selphid Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/fXdp5x6tOufH4uProkFy" %}
[Selphid - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-personalizacion-del-componente)
{% endcontent-ref %}


# Captura facial - Selphi

Versión: 2.3.X

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***Selphi Plugin***.

Este componente se encarga de realizar la captura de un selfie del usuario y de la posterior extracción de las características faciales más importantes. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la cara del usuario.
* Generación de las plantillas con las características faciales y de la imagen del usuario.

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cordova:

```swift
cordova plugin add @facephi/sdk-selphi-cordova@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphi_component:$version"
```

### iOS - Cocoapods:

```swift
pod 'FPHISDKSelphiComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>launchSelphi</td><td>Controlador principal de reconocimiento facial</td></tr></tbody></table>

## Método launchSelphi <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```javascript
exports.launchSelphi = function (cfg) {
    return new Promise((resolve, reject) => {
        var config = [];
        try {
            config = [{
                config: cfg
            }];
        } catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkSelphi', 'launchSelphi', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphiFaceConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface SelphiFaceConfiguration {
    resourcesPath: string;
    debug?: boolean;
    cropPercent?: boolean;
    stabilizationMode?: boolean;
    templateRawOptimized?: boolean;
    compressFormat?: SelphiCompressFormat;
    jpgQuality?: number;
    logImages?: boolean;
    livenessMode?: SelphiFaceLivenessMode;
    enableGenerateTemplateRaw?: boolean;
    showDiagnostic?: boolean;
    showTutorial?: boolean;
    showResultAfterCapture?: boolean;
    fullscreen?: boolean;
    qrMode?: boolean;
    translationsContent?: string;
    viewsContent?: string;
    cameraId?: number;
    params?: any;
    cameraFlashEnabled?: boolean;
    showPreviousTip?: boolean;
    extractionDuration?: SelphiExtractionDuration;
    cameraPreferred?: SelphiCamera;
    vibrationEnabled?: boolean;
    moveSuccessfulAttempts?: number;
    moveFailedAttempts?: number;   
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ltQAYDdQ0KvZtWp7uHMI" %}
[Selphi Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SelphiFaceResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

<pre class="language-typescript"><code class="lang-typescript">export interface SelphiFaceResult {
<strong>    finishStatus: number;
</strong>    finishStatusDescription: string;
    errorType: string;
    errorMessage?: string;
    template?: string;
    templateRaw?: string;
    eyeGlassesScore?: number;
    templateScore?: number;
    qrData?: string;
    images?: [string];
    bestImage?: string;
    bestImageCropped?: string;
    livenessDiagnostic?: string;
    iad?: string;
}
</code></pre>

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/BVDbdVCUJa9mGeT2ESeb" %}
[Selphi Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/KVR0glzjnbcizfLJUNI9" %}
[Selphi - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de NFC

Este componente se encarga de realizar la lectura del NFC de los documentos de identidad y pasaportes.

Sus principales procesos son:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cordova:

```swift
cordova plugin add @facephi/sdk-nfc-cordova@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:nfc_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKNFCComponent', '~> $version'
```

## Método launchNfc <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector NFC:

```dart
exports.launchNfc = function (cfg)
{
    return new Promise((resolve, reject) => {
        config = [];
        try {
            config = [{"config": cfg}];
        }
        catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkNfc', 'nfc', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***NfcConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface NfcConfiguration {
  docNumber: string;
  birthDate: string;
  expirationDate: string;
  extractionTimeout?: number;
  docType?: NfcDocumentType;
  showTutorial?: boolean;
  vibrationEnabled?: boolean;
  skipPACE?: boolean;
  debug?: boolean;
  showDiagnostic?: boolean;
  showPreviousTip?: boolean;
  extractFacialImage?: boolean;
  extractSignatureImage?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/qn36dDEGYFnB6gV1HxH7" %}
[Nfc Configuración](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-configuracion)
{% endcontent-ref %}

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***NfcResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface NfcResult {
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  nfcDocumentInformation?: any;
  nfcPersonalInformation?: any;
  nfcValidations?: any;
  nfcRawData?: any;
  nfcSecurityData?: any;
  facialImage?: string;
  fingerprintImage?: string;
  signatureImage?: string;
  tokenOCR?: string;
  tokenFacialImage?: string;
  tokenSignatureImage?: string;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/siUXPgKaUBtUufZJsrhb" %}
[Nfc Resultado](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-resultado)
{% endcontent-ref %}


# Captura de Huellas - Phingers

Éste plugin se encarga de realizar la captura de las huellas de los dedos (fingerprints) del usuario y la posterior extracción de las plantillas de las huellas posteriores.

Sus principales funcionalidades son las siguientes:

* Dos modos de funcionamiento: extracción de los cuatro dedos de la mano (excepto el pulgar), o extracción únicamente del pulgar.
* Gestión interna de cámara.
* Gestión de permisos.
* Detección de vivacidad incorporada.
* Asistente en los procesos de captura de las huellas.
* Generación de las plantillas con las características de las huellas, imágenes y puntuaciones.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Cordova:

```swift
cordova plugin add @facephi/sdk-phingers-cordova@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:phingers_tf_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKPhingersTFComponent', '~> $version'
```

## Método launchPhingers <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector de huellas:

<pre class="language-dart"><code class="lang-dart"><strong>exports.launchPhingers = function (cfg)
</strong>{
    return new Promise((resolve, reject) => {
        config = [];
        try {
            config = [{ "config" : cfg }];
        }
        catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkPhingers', 'phingers', config);
    });
};
</code></pre>

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***PhingersConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
 export interface PhingersConfiguration 
 {
  fingersFilter?: FingersFilter;
  reticleOrientation: ReticleOrientation;
  fingerSelectorHandOrientation?: PhingerSelectorHandOrientation;
  fingerSelectorOptions?: string[];
  showEllipses?: boolean;
  useLiveness?: boolean;
  showTutorial?: boolean;
  extractionTimeout?: number;
  vibration?: boolean;
  showDiagnostic?: boolean;
  threshold?: number;
  showPreviousTip?: boolean;
  showPreviousFingerSelector?: boolean;
}
```

{% content-ref url="/pages/YiYCyE3r02oYVzLIs2X9" %}
[Phingers Configuración](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***PhingersResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface PhingersResult 
{
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  fingers?: any;
  slapImages?: any;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/E1gYBTErWEYKApmDqqFF" %}
[Phingers Resultado](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-resultado)
{% endcontent-ref %}


# Videoidentificación - VideoID

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

## Dependencias

### Cordova:

```swift
cordova plugin add @facephi/sdk-videoid-cordova@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:videoid_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKVideoIDomponent', '~> $version'
```

## Método startVideoIdComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del Componente:

```js
exports.launchVideoId = function (cfg)
{
    return new Promise((resolve, reject) => {
        config = [];
        try {
            config = [{ "config": cfg }];
        }
        catch (e) {
            console.log(e);
        }

        exec(resolve, reject, 'SdkVideoId', 'videoId', config);
    });
};
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***VideoIdConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface VideoIdConfiguration {
  mode?: VideoMode;
  showTutorial?: boolean;
  autoFaceDetection?: boolean;
  url?: string;
  apiKey?: string;
  tenantId?: string;
  timeoutServerConnection?: number;
  sectionTime?: number;
  vibrationEnabled?: boolean;
  timeoutFaceDetection?: number;
  ocrValidations?: string[];
  countryFilter?: string[];
  documentFilter?: string[];
  sectionTimeout?: number;
  cameraPreferred?: CameraPreferred;
  maxRetries?: number;
  speechText?: string;
  debug?: boolean;
}
```

{% content-ref url="/pages/j2wTykQlqC8THAglzP3Z" %}
[Video Id Configuración](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***VideoIdResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface VideoIdResult {
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  faceImage?: string;
  faceImageTokenized?: string;
  documentFaceImageTokenized?: string;
  matchingSidesScore?: number;
  speechText?: string;
  documentType?: string;
  personalData?: any;
  frontDocumentData?: any;
  backDocumentData?: any;
  ocrMap?: any;
  ocrDiagnostic?: any;
}

```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/1nJjjGavGWsAq6dpXyWL" %}
[Video Id Resultado](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-resultado)
{% endcontent-ref %}


# Flutter

Integra las soluciones biométricas de Facephi en tus aplicaciones híbridas basadas en Flutter, de forma rápida y compatible con iOS y Android.

### ¿Por qué usar el plugin Flutter?

* Integración rápida para iOS y Android.
* Compatible con aplicaciones Flutter modernas.
* Acceso a los flujos biométricos de Facephi sin gestionar código nativo.
* Ejemplos claros y documentación adaptada a desarrolladores Flutter.

***

### Índice de contenidos

* [Instalación](/sdks/sdk-mobile/framework-plugins/flutter/instalacion)\
  Cómo instalar y configurar el plugin en tu proyecto Flutter.
* [Ejemplos de uso](/sdks/sdk-mobile/framework-plugins/flutter/ejemplos-de-uso)\
  Casos prácticos para realizar procesos de verificación de identidad.
* [Changelog](/sdks/sdk-mobile/framework-plugins/flutter/changelog)\
  Historial de versiones y actualizaciones importantes.
* [Componentes/módulos](/sdks/sdk-mobile/framework-plugins/flutter/componentes)

  Más información acerca de los productos incluidos en la SDK.

***

Antes de comenzar, asegúrate de cumplir los Requisitos mínimos de SDK Mobile.

¿Listo para integrar Facephi en tu app híbrida? Comienza por la Guía de instalación.


# Instalación

Sigue estos pasos para integrar el plugin oficial de Facephi en tu aplicación Flutter.

### Requisitos previos

Antes de integrar el plugin de Facephi para Flutter, verifica que cumples con:

* Flutter CLI versión 3.x o superior.
* Proyecto configurado para Android (AGP 8.9.x y Kotlin 2.2.x) y/o iOS (13+).
* Tener configurados los permisos de cámara y conexión a internet.
* Acceso a tus credenciales desde el Portal de Administración.

### Paso 1: Añadir la dependencia

En tu archivo `pubspec.yaml`:

```yaml
dependencies:
  fphi_sdkmobile_<pluginName>:
    hosted:
      name: fphi_sdkmobile_<pluginName>
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

Reemplaza `<versión>` por la última versión disponible que puedes consultar en el Changelog, y `<pluginName>` con el nombre del componente a instalar.

Ejecutar por consola la url de descarga del plugin de Facephi:

```
dart pub token add "https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi"
```

Una vez ejecutado el comando, la misma consola pedirá ingresar el token(no base64) provisto por Facephi.\
Finalmente para corroborar la correcta instalación del plugin, ejecutar el siguiente comando:

```bash
flutter pub get
```

***

### Paso 2: Configuración adicional

## Guía de Instalación nativa Android:

{% content-ref url="/pages/tc6Zady978xIFiZBoWnZ" %}
[Android](/sdks/sdk-mobile/framework-plugins/extras/android)
{% endcontent-ref %}

***

## Guía de Instalación nativa iOS:

{% content-ref url="/pages/Fwjszqg04wLRrI05uyVW" %}
[iOS](/sdks/sdk-mobile/framework-plugins/extras/ios)
{% endcontent-ref %}

***

### Próximos pasos

* Revisa los *Ejemplos de uso* para implementar flujos de verificación.
* Consulta el *Changelog* para conocer las últimas versiones y cambios.
* Profundiza en la funcionalidad de la SDK en la sección *Componentes*/módulos.
* Si tienes dudas, contacta con el Soporte Técnico.


# Ejemplos de uso

Aquí encontrarás ejemplos prácticos para integrar y utilizar el plugin oficial de Facephi en tus aplicaciones Flutter, compatibles con iOS y Android.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

{% embed url="<https://github.com/facephi/sdk-mobile-flutter-samples>" %}

***

### Recomendaciones clave

* Realiza siempre las pruebas iniciales en entorno `sandbox`.
* Asegúrate de que los permisos de cámara e internet estén configurados en cada plataforma.
* Valida los resultados en backend, no solo en cliente.
* Consulta el Changelog tras cada actualización.

Para dudas adicionales, contacta con el Soporte Técnico.


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del plugin oficial de Facephi para Flutter. Se recomienda mantener tu integración siempre actualizada a la última versión estable, especial

### Última versión

**Versión:** 2.12.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Flutter mínimo 3.38.5+.
* SDK nativa 2.12.0.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.11.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Flutter mínimo 3.38.5+.
* SDK nativa 2.11.0.
* SelphID (MBSDR): nuevo parámetro de configuración `encodedDataFocusEnabled` y nuevos campos de resultado `encodedDataImages` y `tokenEncodedDataImages` para la lectura de códigos de barras. Uso opcional y retrocompatible.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.10.x\
**Fecha:** 08/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Flutter mínimo 3.38.5+.
* Sin cambios en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.9.x\
**Fecha:** 06/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Flutter mínimo 3.38.5+.

***

**Versión:** 2.8.x\
**Fecha:** 05/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Fix memory leak en iOS. Se agrega el parámetro de configuración enableLocation en el sdk Core.

***

**Versión:** 2.7.x\
**Fecha:** 04/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Se elimina en parámetro enableSecurityMode del componente CORE. Ahora el mismo pasa a ser siempre true.

***

**Versión:** 2.6.x\
**Fecha:** 02/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+

***

**Versión:** 2.5.x\
**Fecha:** 01/12/2025

**Novedades:**

* Upgrade gradle AGP mínimo 8.9.x.
* Upgrade kotlin mínimo 2.2.x

***

**Versión:** 2.4.x\
**Fecha:** 01/11/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 2.1.21

***

**Versión:** 2.3.x\
**Fecha:** 10/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 1.9.x

***

**Versión:** 2.2.x\
**Fecha:** 09/2025

**Novedades:**

* API Android Version: 34
* Android Gradle Plugin(AGP) 8.3.2
* Kotlin 1.9.x

***

### ℹ️ Notas adicionales

✅ Las actualizaciones son retrocompatibles salvo que se indique lo contrario.\
✅ Realiza siempre pruebas completas en entorno `sandbox` tras cada actualización.\
✅ Consulta las Buenas Prácticas de integración antes de desplegar en producción.

Para reportar problemas o solicitar soporte, contacta con nuestro Soporte Técnico.


# Componentes

Plugins disponibles para el lenguaje Flutter.

Componente principal - Core

{% content-ref url="/pages/j62EGwNgKKW01V8l7hcX" %}
[Componente principal](/sdks/sdk-mobile/framework-plugins/flutter/componentes/componente-principal)
{% endcontent-ref %}

Componente de captura facial - Selphi

{% content-ref url="/pages/vI0QOIi3Dvy1EdS3fIEe" %}
[Captura facial - Selphi](/sdks/sdk-mobile/framework-plugins/flutter/componentes/captura-facial)
{% endcontent-ref %}

Componente de captura de documento - SelphID

{% content-ref url="/pages/WwLAXbXXrRECxWOLzeU5" %}
[Captura de documentos - SelphID](/sdks/sdk-mobile/framework-plugins/flutter/componentes/captura-de-documentos)
{% endcontent-ref %}


# Componente principal

Es el componente mas importante del sdk, ya que contiene las librerías necesarias para que funcione todo de manera correcta.

La instalación del **Core** **Plugin** es obligatoria, independientemente de los productos que se requieran utilizar y del caso de uso que se haya definido. Contiene funcionalidades básicas para el funcionamiento de la SDK, además de otras funcionalidades transversales y necesarias para los plugins auxiliares.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

<pre class="language-swift"><code class="lang-swift">dependencies:
  fphi_sdkmobile_core:
<strong>    hosted:
</strong>      name: fphi_sdkmobile_core
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^&#x3C;versión>
</code></pre>

### Android - Gradle:

```kotlin
api "com.facephi.androidsdk:sdk:$version"
api "com.facephi.androidsdk:core:$version"
implementation "com.facephi.androidsdk:tracking_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKMainComponent', '~> $version'
s.dependency 'FPHISDKTrackingComponent', '~> $version'
s.dependency 'FPHISDKLicensingComponent', '~> $version'
s.dependency 'FPHISDKTokenizeComponent', '~> $version'
s.dependency 'FPHISDKStatusComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>initSession</td><td>Controlador principal del componente, que se encarga de validar las licencias entre otras cosas.</td></tr><tr><td>initOperation</td><td>Método que se encarga de generar una nueva operación. El id de la misma se recupera en el objeto de resultado, parámetro data.</td></tr><tr><td>getExtraData</td><td>El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el <em>Servicio de Validaciones de Facephi</em> (Backend).</td></tr><tr><td>closeSession</td><td>Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización.</td></tr></tbody></table>

### initSession <a href="#id-2-inicializacion-de-la-sesion" id="id-2-inicializacion-de-la-sesion"></a>

Antes de poder utilizar cualquier componente, se deberá inicializar la sesión de la SDK. Esta inicialización se debe hacer lo más pronto posible, preferentemente al inicio de la aplicación. Al mismo tiempo, una vez terminadas todas las operaciones con la SDK Mobile, deberá cerrarse igualmente la sesión.

Se puede inicializar el componente actual de dos formas, dependiendo de cómo desees inyectar la licencia.

El nuevo método de licenciamiento permite gestionar las licencias de forma transparente para el integrador. La licencia se puede inyectar de dos maneras:

* Obteniendo la licencia a través de un servicio mediante una URL y API-KEY
* Inyectando la licencia directamente como String

En ambos casos, el resultado se devolverá por medio de una Promise, la cual contiene un objeto de la clase **CoreResult**.

```dart
@override
Future<Map> initSession({ required CoreConfigurationInitSession widgetConfigurationJSON }) async {
  final Map res = await methodChannel.invokeMethod('initSession', {"widgetConfigurationJSON": widgetConfigurationJSON.toJson()});
  return res;
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***CoreConfigurationInitSession*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class CoreConfigurationInitSession
{
  String mLicenseUrl;
  String mLicenseApiKey;
  String mLicense;
  String? mLocale;
  bool? mEnableTracking;
  bool? mEnableDebugMode;
  dynamic mInternalOptions
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ZiEkZXjLq8M6NL0zUogw" %}
[Init Session Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-session-configuracion)
{% endcontent-ref %}

***

### initOperation <a href="#id-3-inicializacion-de-la-operacion" id="id-3-inicializacion-de-la-operacion"></a>

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método initOperation

```dart
@override
Future<Map> initOperation({ required TrackingConfiguration widgetConfigurationJSON }) async {
  final Map res = await methodChannel.invokeMethod('initOperation', {"widgetConfigurationJSON": widgetConfigurationJSON.toJson()});
  return res;
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***TrackingConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class TrackingConfiguration
{
  TrackingOperationType mType;
  String mCustomerId;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/TDD3HgSYFGVXXpt1Tp9O" %}
[Init Operation Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-operation-configuracion)
{% endcontent-ref %}

***

### closeSession <a href="#id-6-cierre-de-sesion" id="id-6-cierre-de-sesion"></a>

Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización. Para ello, se ejecuta el siguiente fragmento de código:

```dart
@override
Future<Map> closeSession() async {
  final Map res = await methodChannel.invokeMethod('closeSession', {});
  return res;
}
```

***

### getExtraData <a href="#id-7-metodo-extradata" id="id-7-metodo-extradata"></a>

El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el *Servicio de Validaciones de Facephi* (Backend). Esta situación suele darse en casos en los que, una vez obtenida la información necesaria en la aplicación del cliente, se deba enviar esa información a un determinado servicio para su posterior validación o análisis. En caso de que deban trackearse los resultados de esos procesos en la Plataforma, ésta deberá ser capaz de unificar la primera parte del proceso realizada en cliente con la última realizada en el servicio, ya que al final forman parte de la misma operación.

```dart
@override
Future<Map> getExtraData() async {
  final Map res = await methodChannel.invokeMethod('getExtraData', {});
  return res;
}
```

## Lanzamiento de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El proceso de IDV lanza un flujo configurado en la plataforma a partir de su ID (flowID). Para ello se necesitará invocar dos métodos: **initFlow + startFlow**.

### initFlow

En éste método se seteará la configuración necesaria. El ID del flujo configurado en la plataforma (flowID) y el ID del cliente (customerID). Véase código:

```dart
await FphiSdkmobileCore().initFlow(widgetConfigurationJSON: FlowConfiguration(
    mCustomerId: customerId,
    mFlow: "f40c098c-a878-4976-aef1-2af6bbf55148"
));
```

Para configurar el controlador de flujos, se creará un listado de los controladores de los componentes que van a participar en el proceso, lo cual permite inicializarlos correctamente. El orden en el que se definan no es importante, será el propio flujo el que indique el orden en el que se ejecutarán. Por ejemplo:

* **setSelphiFlow**: Captura facial
* **setSelphidFlow**: Captura de documentos

Código para el lanzamiento:

<pre class="language-dart"><code class="lang-dart">// Si initFlow retorna STATUS_OK. Llamo a los flujos, invocando uno a uno los controladores
CoreWidget().initFlow().then((r) async
{
  r.map((r) async
  {
    if (r.finishStatus == SdkFinishStatus.STATUS_OK).
    {
      /* Se llamarán tantos métodos de seteos del flow's como flujos se usen */
      /* En el ejemplo un flow típico de onboarding */
      await SelphiFaceWidget().setSelphiFlow().then((value) {
        if (kDebugMode) {
          print(value);
        }
      });
      await SelphIDWidget().setSelphidFlow().then((value) {
        if (kDebugMode) {
          print(value);
        }
      });
      
      /* Al final de agregar los flujos, se lanza el startFlow(Siempre que los métodos anteriores no fallen) */
      await CoreWidget().startFlow().then((value)
      {
        if (kDebugMode) {
          print(value);
        }
      }).onError((error, stackTrace) {
        if (kDebugMode) {
          print(error);
        }
      });
    }
  });
}).onError((error, stackTrace) {
  if (kDebugMode) {
    print(error);
  }
});

/* Los resultados se escuchan implementando un BasicMessage, con el key 'core.flow' */
const channel = BasicMessageChannel&#x3C;dynamic>('core.flow', StringCodec());
channel.setMessageHandler((message) async
{
  if (jsonDecode(message!)['flow'] == "SELPHID")
  {
    if (kDebugMode) {
      print(SelphIDResult.fromMap(jsonDecode(message)));
    }
  }
  else if (jsonDecode(message!)['flow'] == "SELPHI")
  {
    if (kDebugMode) {
      print(SelphiFaceResult.fromMap(jsonDecode(message)));
    }
  }
  else
  {
    if (kDebugMode) {
      print(jsonDecode(message));
    }
  }
  return '';
<strong>});
</strong></code></pre>

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento de ***TODOS*** los métodos devolverá la información en formato CoreResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class CoreResult {
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final String? data;
}
```

{% content-ref url="/pages/OfulgTvj6HOIQTMcT4M1" %}
[Core Resultado](/sdks/sdk-mobile/framework-plugins/extras/core/core-resultado)
{% endcontent-ref %}


# Captura facial - Selphi

La captura facial se realiza con el Selphi Component.

La captura facial se realiza con el ***Selphi Component***.

Este componente se encarga de realizar la captura de un selfie del usuario y de la posterior extracción de las características faciales más importantes. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la cara del usuario.
* Generación de las plantillas con las características faciales y de la imagen del usuario.

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

```swift
dependencies:
  fphi_sdkmobile_selphi:
    hosted:
      name: fphi_sdkmobile_selphi
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphi_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKSelphiComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>startSelphiFaceWidget</td><td>Controlador principal de reconocimiento facial</td></tr></tbody></table>

## Método startSelphiFaceWidget <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```kotlin
@override
Future<Map> startSelphiFaceWidget({
  required String resourcesPath,
  required SelphiFaceConfiguration widgetConfigurationJSON
}) async {
  final Map result = await methodChannel.invokeMethod('selphi',
      {"resourcesPath": resourcesPath, "widgetConfigurationJSON": widgetConfigurationJSON.toJson()}
  );
  return result;
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphiFaceConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class SelphiFaceConfiguration {
  bool? mDebug;
  bool? mFullscreen;
  bool? mLogImages;
  bool? mStabilizationMode;
  bool? mTemplateRawOptimized;
  bool? mQRMode;
  bool? mShowResultAfterCapture;
  bool? mShowDiagnostic;
  bool? mShowTutorial;
  bool? mShowPreviousTip;
  bool? mVibrationEnabled;
  bool mEnableGenerateTemplateRaw;
  double mCropPercent;
  double mJPGQuality;
  String? mTranslationsContent;
  String? mViewsContent;
  String? mVideoFilename;
  int? mCameraId;
  int? mMoveSuccessfulAttempts;
  int? mMoveFailedAttempts;
  dynamic mParams;
  SelphiFaceLivenessMode? mLivenessMode;
  SelphiCompressFormat mCompressFormat;
  SelphiFaceExtractionDuration? mExtractionDuration;
  SelphiCamera mCameraPreferred;   
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ltQAYDdQ0KvZtWp7uHMI" %}
[Selphi Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SelphiFaceResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class SelphiFaceResult {
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final String? templateRaw;
  final String? qrData;
  final String? bestImage;
  final String? bestImageCropped;
  final String? bestImageTemplateRaw;
  final String? livenessDiagnostic;
  final dynamic images;
}
```

{% content-ref url="/pages/BVDbdVCUJa9mGeT2ESeb" %}
[Selphi Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/KVR0glzjnbcizfLJUNI9" %}
[Selphi - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de documentos - SelphID

La captura de documentos se realiza con el SelphID Component.

La captura de documentos se realiza con el ***SelphID Component***.

Este componente se encarga de realizar capturas de documentos de identidad y del análisis de los datos obtenidos. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la parte frontal y trasera del documento.
* Extracción de la información contenida en el documento.
* Obtención de las imágenes del dorso y reverso del documento, así como otras imagénes incluidas en el documento: cara del usuario, firma del usuario,...
* Alto nivel de configuración: diferentes países, idiomas, tipos de documentos...

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

```yaml
dependencies:
  fphi_sdkmobile_selphid:
    hosted:
      name: fphi_sdkmobile_selphid
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

### iOS - Cocoapods:

```swift
pod 'FPHISDKSelphIDComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>startSelphIDWidget</td><td>Controlador principal de captura de documentos</td></tr></tbody></table>

## Método startSelphIDWidget <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```dart
@override
Future<Map> startSelphIDWidget({required String resourcesPath, required SelphIDConfiguration widgetConfigurationJSON}) async
{
  final Map result = await methodChannel.invokeMethod('selphid', {"resourcesPath": resourcesPath, "widgetConfigurationJSON": widgetConfigurationJSON.toJson()});
  return result;
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphIDConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class SelphIDConfiguration{
  bool? mWizardMode;
  bool? mDebug;
  bool? mShowResultAfterCapture;
  bool? mShowTutorial;
  bool? mTutorialOnly;
  bool? mFullscreen;
  bool mGenerateRawImages;
  bool? mShowDiagnostic;
  bool? mShowPreviousTip;
  bool? mVibrationEnabled;
  double mJPGQuality;
  double? mTokenImageQuality;
  String? mSpecificData;
  String? mTranslationsContent;
  String? mViewsContent;
  String? mDocumentModels;
  String? mVideoFilename;
  String? mTokenPreviousCaptureData;
  int? mCameraId;
  dynamic mParams;
  SelphIDScanMode? mScanMode;
  SelphIDDocumentSide? mDocumentSide;
  SelphIDDocumentType? mDocumentType;
  SelphIDTimeout? mTimeout;
  SelphIDCompressFormat mCompressFormat;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/4rojYcN122t2mIdLaHZi" %}
[SelphID Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***SelphIDResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class SelphIDResult
{
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final String frontDocumentImage;
  final String backDocumentImage;
  final String rawBackDocument;
  final String rawFrontDocument;
  final String fingerprintImage;
  final String faceImage;
  final String signatureImage;
  final String tokenRawBackDocument;
  final String tokenRawFrontDocument;
  final String tokenFrontDocument;
  final String tokenBackDocument;
  final String tokenFaceImage;
  final String documentData;
  final String tokenOCR;
  final String documentCaptured;
  final double matchingSidesScore;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/p4OH5L15yiLpD3JANudF" %}
[Selphid Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/fXdp5x6tOufH4uProkFy" %}
[Selphid - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de NFC

Este componente se encarga de realizar la lectura del NFC de los documentos de identidad y pasaportes.

Sus principales procesos son:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

```swift
dependencies:
  fphi_sdkmobile_nfc:
    hosted:
      name: fphi_sdkmobile_nfc
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:nfc_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKNFCComponent', '~> $version'
```

## Método startNfcComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector NFC:

```dart
Future<Map> startNfcComponent({
  required NfcConfiguration widgetConfigurationJSON,
}) {
  return FphiSdkmobileNfcPlatform.instance.startNfcComponent(
      widgetConfigurationJSON: widgetConfigurationJSON
  );
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***NfcConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class NfcConfiguration
{
  NfcDocumentType mDocType;
  String mDocNumber;
  String mBirthDate;
  String mExpirationDate;
  int? mExtractionTimeout;
  bool? mShowDiagnostic;
  bool? mShowTutorial;
  bool? mShowPreviousTip;
  bool? mVibrationEnabled;
  bool? mDebug;
  bool? mSkipPACE;
  bool? mExtractFacialImage;
  bool? mExtractSignatureImage;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/qn36dDEGYFnB6gV1HxH7" %}
[Nfc Configuración](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-configuracion)
{% endcontent-ref %}

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***NfcResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class NfcResult
{
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final int timeoutStatus;
  final String facialImage;
  final String fingerprintImage;
  final String signatureImage;
  final dynamic nfcDocumentInformation;
  final dynamic nfcRawData;
  final dynamic nfcSecurityData;
  final dynamic nfcValidations;
  final dynamic nfcPersonalInformation;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/siUXPgKaUBtUufZJsrhb" %}
[Nfc Resultado](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-resultado)
{% endcontent-ref %}


# Captura de Huellas - Phingers

Éste plugin se encarga de realizar la captura de las huellas de los dedos (fingerprints) del usuario y la posterior extracción de las plantillas de las huellas posteriores.

Sus principales funcionalidades son las siguientes:

* Dos modos de funcionamiento: extracción de los cuatro dedos de la mano (excepto el pulgar), o extracción únicamente del pulgar.
* Gestión interna de cámara.
* Gestión de permisos.
* Detección de vivacidad incorporada.
* Asistente en los procesos de captura de las huellas.
* Generación de las plantillas con las características de las huellas, imágenes y puntuaciones.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

```swift
dependencies:
  fphi_sdkmobile_phingers:
    hosted:
      name: fphi_sdkmobile_phingers
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:phingers_tf_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKPhingersTFComponent', '~> $version'
```

## Método startPhingersComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector de huellas:

```dart
Future<Map> startPhingersComponent(
  { required PhingersConfiguration widgetConfigurationJSON }
)
{
  return FphiSdkmobilePhingersPlatform.instance.startPhingersComponent(widgetConfigurationJSON: widgetConfigurationJSON);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***PhingersConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class PhingersConfiguration
{
  PhingersReticleOrientation mReticleOrientation;
  FingersFilter mFingersFilter;
  bool mShowEllipses;
  bool mUseLiveness;
  bool mShowTutorial;
  bool mVibration;
  int mExtractionTimeout;
  bool? mShowDiagnostic;
  double? mThreshold;
  bool? mShowPreviousTip;
}
```

{% content-ref url="/pages/YiYCyE3r02oYVzLIs2X9" %}
[Phingers Configuración](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***PhingersResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class PhingersResult
{
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final dynamic fingers;
  final dynamic slapImages;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/E1gYBTErWEYKApmDqqFF" %}
[Phingers Resultado](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-resultado)
{% endcontent-ref %}


# Videoidentificación - VideoID

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

* Gestión interna de cámaras, micro y permisos.
* Conexión con los servicios.
* Lectura del OCR y captura del documento.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Flutter:

```swift
dependencies:
  fphi_sdkmobile_videoid:
    hosted:
      name: fphi_sdkmobile_videoid
      url: https://facephicorp.jfrog.io/artifactory/api/pub/pub-pro-fphi/
    version: ^<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:videoid_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKVideoIDomponent', '~> $version'
```

## Método startVideoIdComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del Componente:

```dart
Future<Map> startVideoIdComponent({required VideoIdConfiguration widgetConfigurationJSON})
{
  return FphiSdkmobileVideoidPlatform.instance.startVideoIdComponent(
      widgetConfigurationJSON: widgetConfigurationJSON
  );
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***VideoIdConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```dart
class VideoIdConfiguration
{
  PreferredCamera mPreferredCamera;
  VideoMode mMode;
  String? mUrl;
  String? mApiKey;
  String? mTenantId;
  String? mSpeechText;
  List<String>? mDocumentFilter;
  List<String>? mCountryFilter;
  bool mShowTutorial;
  bool? mShowDiagnostic;
  bool? mAutoFaceDetection;
  bool? mDebug;
  bool? mVibrationEnabled;
  int mSectionTime;
  int? mSectionTimeout;
  int? mTimeoutServerConnection;
  int? mTimeoutFaceDetection;
  int? mMaxRetries;
}
```

{% content-ref url="/pages/j2wTykQlqC8THAglzP3Z" %}
[Video Id Configuración](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***VideoIdResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
class VideoIdResult
{
  final SdkFinishStatus finishStatus;
  final String finishStatusDescription;
  final String errorDiagnostic;
  final String? errorMessage;
  final dynamic ocrMap;
  final String? faceImage;
  final String? faceImageTokenized;
  final double? matchingSidesScore;
  final String? speechText;
  final String? documentType;
  final dynamic personalData;
  final dynamic frontDocumentData;
  final dynamic backDocumentData;
  final dynamic ocrDiagnostic;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/1nJjjGavGWsAq6dpXyWL" %}
[Video Id Resultado](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-resultado)
{% endcontent-ref %}


# React Native

Integra las soluciones biométricas de Facephi en tus aplicaciones híbridas basadas en React Native, de forma rápida y compatible con iOS y Android.

Este plugin simplifica el uso de nuestros SDKs nativos, permitiendo implementar flujos de verificación biométrica desde código JavaScript/TypeScript, sin necesidad de tocar código nativo.

***

### ¿Por qué usar el plugin React Native?

* Integración rápida en proyectos React Native modernos.
* Acceso a los flujos biométricos de Facephi sin gestionar SDKs nativos directamente.
* Ejemplos y documentación adaptados a la comunidad React Native.

***

### Índice de contenidos

* [Instalación](/sdks/sdk-mobile/framework-plugins/react-native/instalacion)\
  Cómo instalar y configurar el plugin en tu proyecto React Native.
* [Ejemplos de uso](/sdks/sdk-mobile/framework-plugins/react-native/ejemplos-de-uso)\
  Casos prácticos para realizar procesos de verificación de identidad.
* [Changelog](/sdks/sdk-mobile/framework-plugins/react-native/changelog)\
  Historial de versiones y actualizaciones importantes.
* [Componentes/módulos](/sdks/sdk-mobile/framework-plugins/react-native/componentes)

  Más información acerca de los productos incluidos en la SDK.

***

Antes de comenzar, asegúrate de cumplir los Requisitos mínimos de SDK Mobile.

¿Listo para integrar Facephi en tu app híbrida? Comienza por la Guía de instalación.


# Instalación

Sigue estos pasos para integrar el plugin oficial de Facephi en tus aplicaciones React Native.

### Requisitos previos

Antes de integrar el plugin de Facephi para React Native, verifica que cumples con:

* React Native CLI versión 0.79.0 o superior.
* Proyecto configurado para Android (AGP 8.9.x y Kotlin 2.2.x) y/o iOS (13+).
* Tener configurados los permisos de cámara y conexión a internet.
* Acceso a tus credenciales desde el Portal de Administración.

***

### Paso 1: Instalar el plugin

Ejecuta:

```bash
npm install @facephi/sdk-<pluginName>-react-native@<versión>
```

o

```bash
yarn add @facephi/sdk-<pluginName>-react-native@<versión>
```

Reemplaza `<versión>` por la última versión disponible que puedes consultar en el Changelog, y `<pluginName>` con el nombre del componente a instalar.

Este comando descarga e instala el plugin oficial de Facephi compatible con Android e iOS. Si no se agrega el @\<version> React Native busca en los repositorios de Facephi la última versión disponible.

***

### Paso 2: Configuración adicional

## Guía de Instalación nativa Android:

{% content-ref url="/pages/tc6Zady978xIFiZBoWnZ" %}
[Android](/sdks/sdk-mobile/framework-plugins/extras/android)
{% endcontent-ref %}

***

## Guía de Instalación nativa iOS:

{% content-ref url="/pages/Fwjszqg04wLRrI05uyVW" %}
[iOS](/sdks/sdk-mobile/framework-plugins/extras/ios)
{% endcontent-ref %}

***

### Próximos pasos

* Revisa los *Ejemplos de uso*.
* Consulta el *Changelog*.
* Si tienes dudas, contacta con el Soporte Técnico.


# Ejemplos de uso

Aquí encontrarás ejemplos prácticos de cómo utilizar el plugin oficial de Facephi en tus aplicaciones React Native, compatibles con Android e iOS.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

{% embed url="<https://github.com/facephi/sdk-mobile-react-native-samples>" %}

***

### Recomendaciones de integración

* Realiza siempre las pruebas iniciales en entorno `sandbox`.
* Configura los permisos de cámara e internet para Android e iOS correctamente.
* Consulta el *Changelog* tras cada actualización.

Para dudas adicionales, contacta con el Soporte Técnico.


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del plugin oficial de Facephi para React Native.

Recomendamos mantener siempre tu integración actualizada a la última versión estable, especialmente si actualizas React Native o los entornos de Android/iOS.

***

### Última versión

**Versión:** 2.12.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80
* SDK nativa 2.12.0.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.11.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80
* SDK nativa 2.11.0.
* SelphID (MBSDR): nuevo parámetro de configuración `encodedDataFocusEnabled` y nuevos campos de resultado `encodedDataImages` y `tokenEncodedDataImages` para la lectura de códigos de barras. Uso opcional y retrocompatible.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.10.x\
**Fecha:** 08/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80
* Sin cambios en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.8.x\
**Fecha:** 06/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80

***

**Versión:** 2.8.x\
**Fecha:** 05/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80
* Fix memory leak en iOS. Se agrega el parámetro de configuración enableLocation en el sdk Core.

***

**Versión:** 2.7.x\
**Fecha:** 04/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80
* Se elimina en parámetro enableSecurityMode del componente CORE. Ahora el mismo pasa a ser siempre true.

***

**Versión:** 2.6.x\
**Fecha:** 02/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* React Native versión ≥ 0.80

***

**Versión:** 2.5.x\
**Fecha:** 12/2025

**Novedades:**

* Upgrade gradle AGP mínimo 8.9.x.
* API Android Version: 35
* Upgrade kotlin mínimo 2.2.x
* React Native versión ≥ 0.80

***

**Versión:** 2.4.x\
**Fecha:** 11/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 2.1.21
* React Native versión ≥ 0.80

***

**Versión:** 2.3.x\
**Fecha:** 10/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 1.9.x
* React Native versión ≥ 0.79

***

**Versión:** 2.2.x\
**Fecha:** 09/2025

**Novedades:**

* API Android Version: 34
* Android Gradle Plugin(AGP) 8.3.2
* Kotlin 1.9.x
* React Native versión ≥ 0.78

***

### Notas adicionales

* Las actualizaciones son retrocompatibles salvo que se indique lo contrario.
* Realiza siempre pruebas completas en entorno `sandbox` tras cada actualización.
* Consulta las Buenas Prácticas de integración antes de desplegar en producción.

Para reportar problemas o dudas, contacta con nuestro Soporte Técnico.


# Componentes

Plugins disponibles para el lenguaje React Native.

Componente principal - Core

{% content-ref url="/pages/QpLtZDPzqfvvIubT2V7K" %}
[Componente principal](/sdks/sdk-mobile/framework-plugins/react-native/componentes/componente-principal)
{% endcontent-ref %}

Componente de captura de documento - SelphID

{% content-ref url="/pages/WUNMw3GDruYEKggh0T9p" %}
[Captura de documentos - SelphID](/sdks/sdk-mobile/framework-plugins/capacitor/componentes/captura-de-documentos)
{% endcontent-ref %}

Componente de captura facial - Selphi

{% content-ref url="/pages/J6SfrEhrKGz9LCLEwZv6" %}
[Captura facial - Selphi](/sdks/sdk-mobile/framework-plugins/react-native/componentes/captura-facial)
{% endcontent-ref %}


# Componente principal

Es el componente mas importante del sdk, ya que contiene las librerías necesarias para que funcione todo de manera correcta.

La instalación del **Core Plugin** es obligatoria, independientemente de los productos que se requieran utilizar y del caso de uso que se haya definido. Contiene funcionalidades básicas para el funcionamiento de la SDK, además de otras funcionalidades transversales y necesarias para los plugins auxiliares.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### React Native:

```bash
npm i @facephi/sdk-core-react-native@<versión>
```

### Android - Gradle:

```kotlin
api "com.facephi.androidsdk:sdk:$version"
api "com.facephi.androidsdk:core:$version"
implementation "com.facephi.androidsdk:tracking_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKMainComponent', '~> $version'
s.dependency 'FPHISDKTrackingComponent', '~> $version'
s.dependency 'FPHISDKLicensingComponent', '~> $version'
s.dependency 'FPHISDKTokenizeComponent', '~> $version'
s.dependency 'FPHISDKStatusComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>initSession</td><td>Controlador principal del componente, que se encarga de validar las licencias entre otras cosas.</td></tr><tr><td>initOperation</td><td>Método que se encarga de generar una nueva operación. El id de la misma se recupera en el objeto de resultado, parámetro data.</td></tr><tr><td>getExtraData</td><td>El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el <em>Servicio de Validaciones de Facephi</em> (Backend).</td></tr><tr><td>closeSession</td><td>Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización.</td></tr></tbody></table>

### initSession <a href="#id-2-inicializacion-de-la-sesion" id="id-2-inicializacion-de-la-sesion"></a>

Antes de poder utilizar cualquier componente, se deberá inicializar la sesión de la SDK. Esta inicialización se debe hacer lo más pronto posible, preferentemente al inicio de la aplicación. Al mismo tiempo, una vez terminadas todas las operaciones con la SDK Mobile, deberá cerrarse igualmente la sesión.

Se puede inicializar el componente actual de dos formas, dependiendo de cómo desees inyectar la licencia.

El nuevo método de licenciamiento permite gestionar las licencias de forma transparente para el integrador. La licencia se puede inyectar de dos maneras:

* a. Obteniendo la licencia a través de un servicio mediante una URL y API-KEY
* b. Inyectando la licencia directamente como String

En ambos casos, el resultado se devolverá por medio de una Promise, la cual contiene un objeto de la clase **CoreResult**.

```javascript
export function initSession(config: InitSessionConfiguration): Promise<CoreResult> {
  return SdkCore.initSession(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitSessionConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitSessionConfiguration {
    license?: string;
    licenseUrl?: string;
    licenseApiKey?: string;
    enableTracking?: boolean;
    internalOptions?: Record<String, String>;
    enableDebugMode?: boolean;
    locale?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ZiEkZXjLq8M6NL0zUogw" %}
[Init Session Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-session-configuracion)
{% endcontent-ref %}

***

### initOperation <a href="#id-3-inicializacion-de-la-operacion" id="id-3-inicializacion-de-la-operacion"></a>

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método launchInitOperation

```javascript
export function initOperation(config: InitOperationConfiguration): Promise<CoreResult> {
  return SdkCore.initOperation(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitOperationConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitOperationConfiguration {
    type: SdkOperationType;
    customerId: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/TDD3HgSYFGVXXpt1Tp9O" %}
[Init Operation Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-operation-configuracion)
{% endcontent-ref %}

***

### closeSession <a href="#id-6-cierre-de-sesion" id="id-6-cierre-de-sesion"></a>

Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización. Para ello, se ejecuta el siguiente fragmento de código:

```javascript
export function closeSession(): Promise<CoreResult> {
  return SdkCore.closeSession();
}
```

***

### getExtraData <a href="#id-7-metodo-extradata" id="id-7-metodo-extradata"></a>

El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el *Servicio de Validaciones de Facephi* (Backend). Esta situación suele darse en casos en los que, una vez obtenida la información necesaria en la aplicación del cliente, se deba enviar esa información a un determinado servicio para su posterior validación o análisis. En caso de que deban trackearse los resultados de esos procesos en la Plataforma, ésta deberá ser capaz de unificar la primera parte del proceso realizada en cliente con la última realizada en el servicio, ya que al final forman parte de la misma operación.

```javascript
export function getExtraData(): Promise<CoreResult> {
  return SdkCore.getExtraData();
}
```

## Lanzamiento de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El proceso de IDV lanza un flujo configurado en la plataforma a partir de su ID (flowID). Para ello se necesitará invocar dos métodos: **initFlow + startFlow**.

### launchInitFlow

En éste método se seteará la configuración necesaria. El ID del flujo configurado en la plataforma (flowID) y el ID del cliente (customerID). Véase código:

```dart
export function initFlow(config: FlowConfiguration): Promise<CoreResult> {
  return SdkCore.initFlow(config);
}
```

Para configurar el controlador de flujos, se creará un listado de los controladores de los componentes que van a participar en el proceso, lo cual permite inicializarlos correctamente. El orden en el que se definan no es importante, será el propio flujo el que indique el orden en el que se ejecutarán. Por ejemplo:

* **setSelphiFlow**: Captura facial
* **setSelphidFlow**: Captura de documentos

Código para el lanzamiento:

```javascript
/* Los resultados se escuchan implementando un addListener, con el key 'core.flow' */
let flowListener = flowEmitter.addListener(
  "core.flow",
  (res: any) => console.log("FLOW_LISTENER", res)
);

const getFlowConfiguration = () => 
{
    const sdkConfiguration: FlowConfiguration = {
      flow: "f40c098c-a878-4976-aef1-xxxxxxx",
      customerId: CUSTOMER_ID,
    };
    return sdkConfiguration;
};
    
await initFlow(getFlowConfiguration())
.then(async (result: CoreResult) => 
{
  console.log("initFlow result", result);
  if (result.errorType == SdkErrorType.NoError) 
  {
    await setSelphiFlow().then((result: SelphiResult) => 
    {
      console.log("setSelphiFlow", result);
    });
    await setSelphidFlow().then((result: SelphidResult) => 
    {
      console.log("setSelphidFlow", result);
    });

    await startFlow()
    .then((result: CoreResult) => 
    {
      console.log("startFlow result", result);
    })
    .finally(()=> 
    {
      console.log("End startFlow...");
    });
  }
})
.finally(()=> {
  console.log("End launchFlow...");
});
```

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento de ***TODOS*** los métodos devolverá la información en formato CoreResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
export interface CoreResult {
    finishStatus: number;
    finishStatusDescription?: string;
    errorType: string;
    errorMessage?: string;
    data?: string;
}
```

{% content-ref url="/pages/OfulgTvj6HOIQTMcT4M1" %}
[Core Resultado](/sdks/sdk-mobile/framework-plugins/extras/core/core-resultado)
{% endcontent-ref %}


# Captura facial - Selphi

Versión 2.3.X.

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***Selphi Plugin***.

Este componente se encarga de realizar la captura de un selfie del usuario y de la posterior extracción de las características faciales más importantes. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la cara del usuario.
* Generación de las plantillas con las características faciales y de la imagen del usuario.

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### React Native:

```bash
npm install @facephi/sdk-selphi-react-native@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphi_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKSelphiComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>selphi</td><td>Controlador principal de reconocimiento facial</td></tr></tbody></table>

## Método selphi <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```typescript
export function selphi(config: SelphiConfiguration): Promise<SelphiResult> {
  return SdkSelphi.selphi(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphiConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface SelphiConfiguration {
  debug?: boolean;
  fullscreen?: boolean;
  cropPercent?: number;
  stabilizationMode?: boolean;
  templateRawOptimized?: boolean;
  resourcesPath?: string;
  enableGenerateTemplateRaw?: boolean;
  livenessMode?: SdkLivenessMode;
  showResultAfterCapture?: boolean;
  cameraFlashEnabled?: boolean;
  translationsContent?: string;
  viewsContent?: string;
  showTutorial?: boolean;
  cameraId?: number;
  videoFilename?: string;
  params?: any;
  qrMode?: boolean;
  showDiagnostic?: boolean;
  logImages?: boolean;
  compressFormat?: SdkCompressFormat;
  jpgQuality?: number;
  showPreviousTip?: boolean;
  vibrationEnabled?: boolean;
  extractionDuration?: SdkExtractionDuration;
  cameraPreferred?: SelphiCamera;
  moveSuccessfulAttempts?: number;
  moveFailedAttempts?: number;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ltQAYDdQ0KvZtWp7uHMI" %}
[Selphi Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SelphiResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface SelphiResult {
  finishStatus?: number;
  errorType?: string;
  finishStatusDescription?: string;
  errorMessage?: string;
  bestImage?: string;
  bestImageCropped?: string;
  bestImageTemplateRaw?: string;
  qrData?: string;
  templateRaw?: string;
  images?: string[];
  livenessDiagnostic?: string;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/BVDbdVCUJa9mGeT2ESeb" %}
[Selphi Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/KVR0glzjnbcizfLJUNI9" %}
[Selphi - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de documentos - SelphID

La captura de documentos se realiza con el ***SelphID Plugin***.

Este componente se encarga de realizar capturas de documentos de identidad y del análisis de los datos obtenidos. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la parte frontal y trasera del documento.
* Extracción de la información contenida en el documento.
* Obtención de las imágenes del dorso y reverso del documento, así como otras imagénes incluidas en el documento: cara del usuario, firma del usuario,...
* Alto nivel de configuración: diferentes países, idiomas, tipos de documentos...

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### React:

```swift
npm install @facephi/sdk-selphid-react-native@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

### iOS - Cocoapods:

```swift
pod 'FPHISDKSelphIDComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>launchSelphID</td><td>Controlador principal de captura de documentos</td></tr></tbody></table>

## Método selphid <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```javascript
export function selphid(config: SelphidConfiguration): Promise<SelphidResult> {
  return SdkSelphid.selphid(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphidConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
 export interface SelphidConfiguration {
  debug?: boolean;
  fullscreen?: boolean;
  tokenImageQuality?: number;
  timeout?: SdkTimeout;
  showResultAfterCapture?: boolean;
  showTutorial?: boolean;
  tutorialOnly?: boolean;
  scanMode?: SdkScanMode;
  specificData?: string;
  documentType?: SdkDocumentType;
  videoFilename?: string;
  documentModels?: string;
  generateRawImages?: boolean;
  translationsContent?: string;
  viewsContent?: string;
  cameraId?: number;
  params?: any;
  resourcesPath?: string;
  tokenPrevCaptureData?: string;
  wizardMode?: boolean;
  documentSide?: SdkDocumentSide;
  showDiagnostic?: boolean;
  compressFormat?: SdkCompressFormat;
  jpgQuality?: number;
  showPreviousTip?: boolean;
  vibrationEnabled?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/4rojYcN122t2mIdLaHZi" %}
[SelphID Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***SelphidResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface SelphidResult 
{
    finishStatus: number;
    finishStatusDescription: string;
    errorType: string;
    errorMessage?: string;
    frontDocumentImage?: string;
    backDocumentImage?: string;
    faceImage?: string;
    signatureImage?: string;
    fingerprintImage?: string;
    documentData?: string;
    tokenFrontDocument?: string;
    tokenBackDocument?: string;
    tokenFaceImage?: string;
    tokenOCR?: string;
    documentCaptured?: string;
    captureProgress: number;
    matchingSidesScore: number;
    rawFrontDocument?: string;
    rawBackDocument?: string;
    tokenRawFrontDocument?: string;
    tokenRawBackDocument?: string;
    lastActionBeforeCapture?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/p4OH5L15yiLpD3JANudF" %}
[Selphid Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/fXdp5x6tOufH4uProkFy" %}
[Selphid - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de NFC

Este componente se encarga de realizar la lectura del NFC de los documentos de identidad y pasaportes.

Sus principales procesos son:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### React:

```swift
npm install @facephi/sdk-nfc-react-native@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:nfc_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKNFCComponent', '~> $version'
```

## Método nfc <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector NFC:

```dart
export function nfc(config: NfcConfiguration): Promise<NfcResult> {
  return SdkNfc.nfc(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***NfcConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface NfcConfiguration {
  docNumber: string;
  birthDate: string;
  expirationDate: string;
  extractionTimeout?: number;
  docType?: NfcDocumentType;
  showTutorial?: boolean;
  vibrationEnabled?: boolean;
  skipPACE?: boolean;
  debug?: boolean;
  showDiagnostic?: boolean;
  showPreviousTip?: boolean;
  extractFacialImage?: boolean;
  extractSignatureImage?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/qn36dDEGYFnB6gV1HxH7" %}
[Nfc Configuración](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-configuracion)
{% endcontent-ref %}

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***NfcResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface NfcResult {
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  nfcDocumentInformation?: any;
  nfcPersonalInformation?: any;
  nfcValidations?: any;
  nfcRawData?: any;
  nfcSecurityData?: any;
  facialImage?: string;
  fingerprintImage?: string;
  signatureImage?: string;
  tokenOCR?: string;
  tokenFacialImage?: string;
  tokenSignatureImage?: string;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/siUXPgKaUBtUufZJsrhb" %}
[Nfc Resultado](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-resultado)
{% endcontent-ref %}


# Captura de Huellas - Phingers

Éste plugin se encarga de realizar la captura de las huellas de los dedos (fingerprints) del usuario y la posterior extracción de las plantillas de las huellas posteriores.

Sus principales funcionalidades son las siguientes:

* Dos modos de funcionamiento: extracción de los cuatro dedos de la mano (excepto el pulgar), o extracción únicamente del pulgar.
* Gestión interna de cámara.
* Gestión de permisos.
* Detección de vivacidad incorporada.
* Asistente en los procesos de captura de las huellas.
* Generación de las plantillas con las características de las huellas, imágenes y puntuaciones.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### React Native:

```swift
npm install @facephi/sdk-phingers-react-native@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:phingers_tf_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKPhingersTFComponent', '~> $version'
```

## Método phingers <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector de huellas:

```dart
export function phingers(config: PhingersConfiguration): Promise<PhingersResult> {
  return SdkPhingers.phingers(config);
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***PhingersConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
 export interface PhingersConfiguration 
 {
  fingersFilter?: FingersFilter;
  reticleOrientation: ReticleOrientation;
  fingerSelectorHandOrientation?: PhingerSelectorHandOrientation;
  fingerSelectorOptions?: string[];
  showEllipses?: boolean;
  useLiveness?: boolean;
  showTutorial?: boolean;
  extractionTimeout?: number;
  vibration?: boolean;
  showDiagnostic?: boolean;
  threshold?: number;
  showPreviousTip?: boolean;
  showPreviousFingerSelector?: boolean;
}
```

{% content-ref url="/pages/YiYCyE3r02oYVzLIs2X9" %}
[Phingers Configuración](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***PhingersResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface PhingersResult 
{
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  fingers?: any;
  slapImages?: any;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/E1gYBTErWEYKApmDqqFF" %}
[Phingers Resultado](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-resultado)
{% endcontent-ref %}


# Videoidentificación - VideoID

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

## Dependencias

### React Native:

```swift
npm install @facephi/sdk-videoid-react-native@<versión>
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:videoid_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKVideoIDomponent', '~> $version'
```

## Método startVideoIdComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del Componente:

```dart
Future<Map> startVideoIdComponent({required VideoIdConfiguration widgetConfigurationJSON})
{
  return FphiSdkmobileVideoidPlatform.instance.startVideoIdComponent(
      widgetConfigurationJSON: widgetConfigurationJSON
  );
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***VideoIdConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface VideoIdConfiguration {
  mode?: VideoMode;
  showTutorial?: boolean;
  autoFaceDetection?: boolean;
  url?: string;
  apiKey?: string;
  tenantId?: string;
  timeoutServerConnection?: number;
  sectionTime?: number;
  vibrationEnabled?: boolean;
  timeoutFaceDetection?: number;
  ocrValidations?: string[];
  countryFilter?: string[];
  documentFilter?: string[];
  sectionTimeout?: number;
  cameraPreferred?: CameraPreferred;
  maxRetries?: number;
  speechText?: string;
  debug?: boolean;
}
```

{% content-ref url="/pages/uQTITr1yAOYjJFzojInZ" %}
[Video Id](/sdks/sdk-mobile/framework-plugins/extras/video-id)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***VideoIdResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface VideoIdResult {
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  faceImage?: string;
  faceImageTokenized?: string;
  documentFaceImageTokenized?: string;
  matchingSidesScore?: number;
  speechText?: string;
  documentType?: string;
  personalData?: any;
  frontDocumentData?: any;
  backDocumentData?: any;
  ocrMap?: any;
  ocrDiagnostic?: any;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/1nJjjGavGWsAq6dpXyWL" %}
[Video Id Resultado](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-resultado)
{% endcontent-ref %}


# Capacitor

Integra las soluciones biométricas de Facephi en tus aplicaciones híbridas basadas en Capacitor, de forma rápida y compatible con iOS y Android.

Este plugin simplifica el uso de nuestros SDKs nativos y permite implementar flujos de verificación biométrica desde aplicaciones basadas en Ionic, Angular, React, Vue o cualquier framework compatible con Capacitor.

***

* Integración rápida en proyectos multiplataforma.
* Acceso a los flujos biométricos de Facephi desde JavaScript.
* Evita la complejidad de gestionar SDKs nativos directamente.
* Ideal para aplicaciones basadas en Ionic o similares.

***

### Índice de contenidos

* [Instalación](/sdks/sdk-mobile/framework-plugins/capacitor/instalacion)\
  Cómo instalar y configurar el plugin en tu proyecto Capacitor.
* [Ejemplos de uso](/sdks/sdk-mobile/framework-plugins/capacitor/ejemplos-de-uso)\
  Casos prácticos para realizar procesos de verificación de identidad.
* [Changelog](/sdks/sdk-mobile/framework-plugins/capacitor/changelog)\
  Historial de versiones y actualizaciones importantes.
* [Componentes/módulos](/sdks/sdk-mobile/framework-plugins/capacitor/componentes)

  Más información acerca de los productos incluidos en la SDK.

***

Antes de comenzar, asegúrate de cumplir los Requisitos mínimos de SDK Mobile.

¿Listo para integrar Facephi en tu app híbrida? Comienza por la Guía de instalación.


# Instalación

Sigue estos pasos para integrar el plugin oficial de Facephi en tu aplicación basada en Capacitor.

### Requisitos previos

Antes de integrar el plugin de Facephi para Capacitor, verifica que cumples con:

* Capacitor CLI versión 6 o superior.
* Proyecto configurado para Android (AGP 8.9.x y Kotlin 2.2.x) y/o iOS (13+).
* Tener configurados los permisos de cámara y conexión a internet.
* Acceso a tus credenciales desde el Portal de Administración.

***

### Paso 1: Instalar el plugin

Ejecuta:

```bash
npm install @facephi/sdk-<pluginName>-capacitor@<versión>
npm run build
npx cap sync
```

Reemplaza `<versión>` por la última versión disponible que puedes consultar en el Changelog, y `<pluginName>` con el nombre del componente a instalar.

Este comando descarga e instala el plugin oficial de Facephi compatible con Android e iOS. Si no se agrega el @\<versión> Capacitor busca en los repositorios de Facephi la última versión disponible.

***

### Paso 2: Configuración adicional

## Guía de Instalación nativa Android:

{% content-ref url="/pages/tc6Zady978xIFiZBoWnZ" %}
[Android](/sdks/sdk-mobile/framework-plugins/extras/android)
{% endcontent-ref %}

***

## Guía de Instalación nativa iOS:

{% content-ref url="/pages/Fwjszqg04wLRrI05uyVW" %}
[iOS](/sdks/sdk-mobile/framework-plugins/extras/ios)
{% endcontent-ref %}

***

### Próximos pasos

* Revisa los *Ejemplos de uso*.
* Consulta el *Changelog*.
* Si tienes dudas, contacta con el Soporte Técnico.


# Ejemplos de uso

A continuación, te mostramos ejemplos prácticos de cómo utilizar el plugin oficial de Facephi en tus aplicaciones basadas en Capacitor, compatibles con Android e iOS.

Las aplicaciones de ejemplo se pueden encontrar en el repositorio de GitHub:

{% embed url="<https://github.com/facephi/sdk-mobile-capacitor-samples>" %}

***

### Recomendaciones clave

* Realiza siempre las pruebas iniciales en entorno `sandbox`.
* Asegúrate de que los permisos de cámara e internet estén configurados en cada plataforma.
* Consulta el *Changelog* tras cada actualización.

Para dudas adicionales, contacta con el Soporte Técnico.


# Changelog

Aquí encontrarás el historial de versiones y actualizaciones del plugin oficial de Facephi para Capacitor.

Se recomienda mantener siempre tu integración actualizada a la última versión estable, especialmente al actualizar Capacitor o los entornos Android/iOS.

***

### Última versión

**Versión:** 2.12.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0
* SDK nativa 2.12.0.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.11.x\
**Fecha:** 09/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0
* SDK nativa 2.11.0.
* SelphID (MBSDR): nuevo parámetro de configuración `encodedDataFocusEnabled` y nuevos campos de resultado `encodedDataImages` y `tokenEncodedDataImages` para la lectura de códigos de barras. Uso opcional y retrocompatible.
* Resto de componentes: sin cambios de API en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.10.x\
**Fecha:** 08/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0
* Sin cambios en capa híbrida. Véase cambios en nativos
* [iOS Changelog.](/sdks/sdk-mobile/ios-sdk/changelog#ultima-version)
* [Android Changelog.](/sdks/sdk-mobile/android-sdk/changelog#ultima-version)

***

**Versión:** 2.8.x\
**Fecha:** 06/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0

***

**Versión:** 2.8.x\
**Fecha:** 05/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0
* Fix memory leak en iOS. Se agrega el parámetro de configuración enableLocation en el sdk Core.

***

**Versión:** 2.7.x\
**Fecha:** 04/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0
* Se elimina en parámetro enableSecurityMode del componente CORE. Ahora el mismo pasa a ser siempre true.

***

**Versión:** 2.6.x\
**Fecha:** 02/2026

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.9+.
* Kotlin mínimo 2.2+
* Capacitor versión ≥ 5.0

***

**Versión:** 2.5.x\
**Fecha:** 12/2025

**Novedades:**

* Upgrade gradle AGP mínimo 8.9.x.
* API Android Version: 35
* Upgrade kotlin mínimo 2.2.x
* Capacitor versión ≥ 5.0

***

**Versión:** 2.4.x\
**Fecha:** 11/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 2.1.21
* Capacitor versión ≥ 5.0

***

**Versión:** 2.3.x\
**Fecha:** 10/2025

**Novedades:**

* API Android Version: 35
* Android Gradle Plugin(AGP) mínimo 8.6
* Kotlin 1.9.x
* Capacitor versión ≥ 5.0

***

**Versión:** 2.2.x\
**Fecha:** 09/2025

**Novedades:**

* API Android Version: 34
* Android Gradle Plugin(AGP) 8.3.2
* Kotlin 1.9.x
* Capacitor versión ≥ 5.0

***

### Notas adicionales

* Las actualizaciones son retrocompatibles salvo que se indique lo contrario.
* Realiza siempre pruebas completas en entorno `sandbox` tras cada actualización.
* Consulta las Buenas Prácticas de integración antes de desplegar en producción.

Para reportar problemas o solicitar soporte, contacta con nuestro Soporte Técnico.


# Componentes

Plugins disponibles para el lenguaje Capacitor.

Componente principal - Core

{% content-ref url="/pages/qn2nyQbWwHq04qy1aXbe" %}
[Componente principal](/sdks/sdk-mobile/framework-plugins/capacitor/componentes/componente-principal)
{% endcontent-ref %}

Componente de captura facial - Selphi

{% content-ref url="/pages/NDWocHEU0SpxtaLbzKaz" %}
[Captura facial - Selphi](/sdks/sdk-mobile/framework-plugins/capacitor/componentes/captura-facial)
{% endcontent-ref %}

Componente de captura de documento - SelphID

{% content-ref url="/pages/WUNMw3GDruYEKggh0T9p" %}
[Captura de documentos - SelphID](/sdks/sdk-mobile/framework-plugins/capacitor/componentes/captura-de-documentos)
{% endcontent-ref %}


# Componente principal

Es el componente mas importante del sdk, ya que contiene las librerías necesarias para que funcione todo de manera correcta.

La instalación del **Core** **Plugin** es obligatoria, independientemente de los productos que se requieran utilizar y del caso de uso que se haya definido. Contiene funcionalidades básicas para el funcionamiento de la SDK, además de otras funcionalidades transversales y necesarias para los plugins auxiliares.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Capacitor:

```bash
npm i @facephi/sdk-core-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
api "com.facephi.androidsdk:sdk:$version"
api "com.facephi.androidsdk:core:$version"
implementation "com.facephi.androidsdk:tracking_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKMainComponent', '~> $version'
s.dependency 'FPHISDKTrackingComponent', '~> $version'
s.dependency 'FPHISDKLicensingComponent', '~> $version'
s.dependency 'FPHISDKTokenizeComponent', '~> $version'
s.dependency 'FPHISDKStatusComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>initSession</td><td>Controlador principal del componente, que se encarga de validar las licencias entre otras cosas.</td></tr><tr><td>initOperation</td><td>Método que se encarga de generar una nueva operación. El id de la misma se recupera en el objeto de resultado, parámetro data.</td></tr><tr><td>getExtraData</td><td>El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el <em>Servicio de Validaciones de Facephi</em> (Backend).</td></tr><tr><td>closeSession</td><td>Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización.</td></tr></tbody></table>

### initSession <a href="#id-2-inicializacion-de-la-sesion" id="id-2-inicializacion-de-la-sesion"></a>

Antes de poder utilizar cualquier componente, se deberá inicializar la sesión de la SDK. Esta inicialización se debe hacer lo más pronto posible, preferentemente al inicio de la aplicación. Al mismo tiempo, una vez terminadas todas las operaciones con la SDK Mobile, deberá cerrarse igualmente la sesión.

Se puede inicializar el componente actual de dos formas, dependiendo de cómo desees inyectar la licencia.

El nuevo método de licenciamiento permite gestionar las licencias de forma transparente para el integrador. La licencia se puede inyectar de dos maneras:

* a. Obteniendo la licencia a través de un servicio mediante una URL y API-KEY
* b. Inyectando la licencia directamente como String

En ambos casos, el resultado se devolverá por medio de una Promise, la cual contiene un objeto de la clase **CoreResult**.

```javascript
initSession(configuration: InitSessionConfiguration): Promise<CoreResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitSessionConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitSessionConfiguration {
    license?: string;
    licenseUrl?: string;
    licenseApiKey?: string;
    enableTracking?: boolean;
    internalOptions?: Record<String, String>;
    enableDebugMode?: boolean;
    locale?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ZiEkZXjLq8M6NL0zUogw" %}
[Init Session Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-session-configuracion)
{% endcontent-ref %}

***

### initOperation <a href="#id-3-inicializacion-de-la-operacion" id="id-3-inicializacion-de-la-operacion"></a>

Al iniciar un proceso o flujo, **siempre** se deberá realizar la llamada al método launchInitOperation

```javascript
initOperation(configuration: InitOperationConfiguration): Promise<CoreResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***InitOperationConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface InitOperationConfiguration {
    type: SdkOperationType;
    steps?: string[];
    customerId: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/TDD3HgSYFGVXXpt1Tp9O" %}
[Init Operation Configuración](/sdks/sdk-mobile/framework-plugins/extras/core/init-operation-configuracion)
{% endcontent-ref %}

***

### closeSession <a href="#id-6-cierre-de-sesion" id="id-6-cierre-de-sesion"></a>

Antes de que la aplicación se vaya a destruir, se deberá cerrar la sesión de la SDK para así avisar a la plataforma de su finalización. Para ello, se ejecuta el siguiente fragmento de código:

```javascript
closeSession(): Promise<CoreResult>;
```

***

### launchGetExtraData <a href="#id-7-metodo-extradata" id="id-7-metodo-extradata"></a>

El método getExtraData permite generar los identificadores necesarios para una operación que deba continuar en el *Servicio de Validaciones de Facephi* (Backend). Esta situación suele darse en casos en los que, una vez obtenida la información necesaria en la aplicación del cliente, se deba enviar esa información a un determinado servicio para su posterior validación o análisis. En caso de que deban trackearse los resultados de esos procesos en la Plataforma, ésta deberá ser capaz de unificar la primera parte del proceso realizada en cliente con la última realizada en el servicio, ya que al final forman parte de la misma operación.

```javascript
getExtraData(): Promise<CoreResult>;
```

## Lanzamiento de IDV <a href="#lanzamiento-de-idv" id="lanzamiento-de-idv"></a>

El proceso de IDV lanza un flujo configurado en la plataforma a partir de su ID (flowID). Para ello se necesitará invocar dos métodos: **initFlow + startFlow**.

### launchInitFlow

En éste método se seteará la configuración necesaria. El ID del flujo configurado en la plataforma (flowID) y el ID del cliente (customerID). Véase código:

```dart
initFlow = async (): Promise<CoreResult> => 
{
  const widgetConfig: InitFlowConfiguration = {
    flow: "f40c098c-a878-4976-aef1-xxxxxxx",
    customerId: CUSTOMER_ID
  };
  return SdkCore.initFlow(widgetConfig);
};
```

```typescript
startFlow = async (): Promise<CoreResult> => 
{
  console.log('Launching startFlow...');
  return SdkCore.startFlow();
};
```

Para configurar el controlador de flujos, se creará un listado de los controladores de los componentes que van a participar en el proceso, lo cual permite inicializarlos correctamente. El orden en el que se definan no es importante, será el propio flujo el que indique el orden en el que se ejecutarán. Por ejemplo:

* **setSelphiFlow**: Captura facial
* **setSelphidFlow**: Captura de documentos

Código para el lanzamiento:

```javascript
/* Los resultados se escuchan implementando un addListener, con el key 'core.flow' */
listener: any = SdkCore.addListener('core.flow', (response: any) => 
{
  console.log("core.flow:", response);
});

await this.coreService.initFlow().then(async (result: CoreResult) => 
{
  if (result.finishStatus == SdkFinishStatus.Ok)
  {
    await this.selphiFaceService.setSelphiFlow()
      .then((res: SelphiFaceResult) => console.log("setSelphiFlow res", res))
      .catch((err) => console.log("setSelphiFlow err", err));
      
    await this.selphidService.setSelphidFlow()
      .then((res: SelphIDResult) => console.log("setSelphidFlow res", res))
      .catch((err) => console.log("setSelphidFlow err", err));


    await this.coreService.startFlow()
      .then((res: CoreResult) => console.log("startFlow res", res))
      .catch((err) => console.log("startFlow err", err));
  }
}, 
(err: any) => console.log(err));
```

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento de ***TODOS*** los métodos devolverá la información en formato CoreResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```dart
export interface CoreResult {
    finishStatus: number;
    finishStatusDescription?: string;
    errorType: string;
    errorMessage?: string;
    data?: string;
}
```

{% content-ref url="/pages/OfulgTvj6HOIQTMcT4M1" %}
[Core Resultado](/sdks/sdk-mobile/framework-plugins/extras/core/core-resultado)
{% endcontent-ref %}


# Captura facial - Selphi

Versión 2.3.X

## Introducción <a href="#id-1-introduccion" id="id-1-introduccion"></a>

La captura facial se realiza con el ***Selphi Plugin***.

Este componente se encarga de realizar la captura de un selfie del usuario y de la posterior extracción de las características faciales más importantes. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la cara del usuario.
* Generación de las plantillas con las características faciales y de la imagen del usuario.

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Capacitor:

```bash
npm install @facephi/sdk-selphi-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphi_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKSelphiComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>startExtraction</td><td>Controlador principal de reconocimiento facial</td></tr></tbody></table>

## Método startExtraction <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```typescript
startExtraction(configuration: SelphiFaceConfiguration): Promise<SelphiFaceResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphiFaceConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface SelphiFaceConfiguration {
  debug?: boolean;
  fullscreen?: boolean;
  cropPercent?: number;
  stabilizationMode?: boolean;
  templateRawOptimized?: boolean;
  resourcesPath?: string;
  enableGenerateTemplateRaw?: boolean;
  livenessMode?: SdkLivenessMode;
  showResultAfterCapture?: boolean;
  cameraFlashEnabled?: boolean;
  translationsContent?: string;
  viewsContent?: string;
  showTutorial?: boolean;
  cameraId?: number;
  videoFilename?: string;
  params?: any;
  qrMode?: boolean;
  showDiagnostic?: boolean;
  logImages?: boolean;
  compressFormat?: SdkCompressFormat;
  jpgQuality?: number;
  showPreviousTip?: boolean;
  vibrationEnabled?: boolean;
  extractionDuration?: SdkExtractionDuration;
  cameraPreferred?: SelphiCamera;
  moveSuccessfulAttempts?: number;
  moveFailedAttempts?: number;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/ltQAYDdQ0KvZtWp7uHMI" %}
[Selphi Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato SelphiFaceResult. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface SelphiFaceResult {
  finishStatus?: number;
  errorType?: string;
  finishStatusDescription?: string;
  errorMessage?: string;
  bestImage?: string;
  bestImageCropped?: string;
  bestImageTemplateRaw?: string;
  qrData?: string;
  templateRaw?: string;
  images?: string[];
  livenessDiagnostic?: string;
}
```

{% content-ref url="/pages/BVDbdVCUJa9mGeT2ESeb" %}
[Selphi Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/KVR0glzjnbcizfLJUNI9" %}
[Selphi - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphi/selphi-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de documentos - SelphID

La captura de documentos se realiza con el ***SelphID Plugin***.

Este componente se encarga de realizar capturas de documentos de identidad y del análisis de los datos obtenidos. Sus principales procesos son:

* Gestión interna de cámaras y permisos.
* Asistente en los procesos de captura de la parte frontal y trasera del documento.
* Extracción de la información contenida en el documento.
* Obtención de las imágenes del dorso y reverso del documento, así como otras imagénes incluidas en el documento: cara del usuario, firma del usuario,...
* Alto nivel de configuración: diferentes países, idiomas, tipos de documentos...

***

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Capacitor:

```bash
npm install @facephi/sdk-selphid-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

### iOS - Cocoapods:

```swift
pod 'FPHISDKSelphIDComponent', '~> $version'
```

## Métodos disponibles

Este componente contiene varios métodos que ejecutan diferentes funcionalidades:

<table data-header-hidden><thead><tr><th width="233.64453125"></th><th></th></tr></thead><tbody><tr><td><strong>Método</strong></td><td><strong>Descripción</strong></td></tr><tr><td>launchSelphID</td><td>Controlador principal de captura de documentos</td></tr></tbody></table>

## Método startCapture <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento de la captura facial:

```javascript
startCapture(configuration: SelphIDConfiguration): Promise<SelphIDResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***SelphIDConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface SelphIDConfiguration 
{
    wizardMode?: boolean;
    documentSide: SelphIDDocumentSide;
    resourcesPath: string;
    debug?: boolean;
    showResultAfterCapture?: boolean;
    showTutorial?: boolean;
    tutorialOnly?: boolean;
    scanMode?: SelphIDScanMode;
    specificData?: string;
    fullscreen?: number;
    tokenImageQuality?: number;
    documentType?: SelphIDDocumentType;
    timeout?: SelphIDTimeout;
    tokenPrevCaptureData?: string;
    generateRawImages?: boolean;
    imageQuality?: number;
    compressFormat?: SelphIDCompressFormat;
    documentModels?: string;
    params?: any;
    showDiagnostic?: boolean;
    cameraId?: number;
    translationsContent?: string;
    viewsContent?: string;
    showPreviousTip?: boolean;
    vibrationEnabled?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/4rojYcN122t2mIdLaHZi" %}
[SelphID Configuración](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-configuracion)
{% endcontent-ref %}

***

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***SelphIDResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface SelphIDResult 
{
    finishStatus: number;
    finishStatusDescription: string;
    errorType: string;
    errorMessage?: string;
    frontDocumentImage?: string;
    backDocumentImage?: string;
    faceImage?: string;
    signatureImage?: string;
    fingerprintImage?: string;
    documentData?: string;
    tokenFrontDocument?: string;
    tokenBackDocument?: string;
    tokenFaceImage?: string;
    tokenOCR?: string;
    documentCaptured?: string;
    captureProgress: number;
    matchingSidesScore: number;
    rawFrontDocument?: string;
    rawBackDocument?: string;
    tokenRawFrontDocument?: string;
    tokenRawBackDocument?: string;
    lastActionBeforeCapture?: string;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/p4OH5L15yiLpD3JANudF" %}
[Selphid Resultado](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-resultado)
{% endcontent-ref %}

## Personalización del componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Además de los cambios que se pueden realizar a nivel de SDK (los cuales se explican en el documento de [Ajustes avanzados](#id-1-introduccion)), este componente en concreto permite su propia personalización.

{% content-ref url="/pages/fXdp5x6tOufH4uProkFy" %}
[Selphid - Personalización del Componente](/sdks/sdk-mobile/framework-plugins/extras/selphid/selphid-personalizacion-del-componente)
{% endcontent-ref %}


# Captura de NFC

Este componente se encarga de realizar la lectura del NFC de los documentos de identidad y pasaportes.

Sus principales procesos son:

* Gestión interna del sensor de NFC.
* Gestión de permisos.
* Análisis de documento.
* Análisis del progreso.
* Asistente en los procesos de lectura.
* Devolución de toda la información posible a leer
* Devolución de imágenes cuando estén disponible para su lectura

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Capacitor:

```bash
npm install @facephi/sdk-nfc-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:nfc_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKNFCComponent', '~> $version'
```

## Método startNfc <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector NFC:

```dart
startNfc(configuration: NfcConfiguration): Promise<NfcResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***NfcConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
class NfcConfiguration
{
  docNumber: string;
  birthDate: string;
  expirationDate: string;
  extractionTimeout?: number;
  docType?: NfcDocumentType;
  showTutorial?: boolean;
  vibrationEnabled?: boolean;
  skipPACE?: boolean;
  debug?: boolean;
  showDiagnostic?: boolean;
  showPreviousTip?: boolean;
  extractFacialImage?: boolean;
  extractSignatureImage?: boolean;
}
```

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/qn36dDEGYFnB6gV1HxH7" %}
[Nfc Configuración](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-configuracion)
{% endcontent-ref %}

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***NfcResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
class NfcResult
{
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  nfcDocumentInformation?: any;
  nfcPersonalInformation?: any;
  nfcValidations?: any;
  facialImage?: string;
  fingerprintImage?: string;
  signatureImage?: string;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/siUXPgKaUBtUufZJsrhb" %}
[Nfc Resultado](/sdks/sdk-mobile/framework-plugins/extras/nfc/nfc-resultado)
{% endcontent-ref %}


# Captura de Huellas - Phingers

Éste plugin se encarga de realizar la captura de las huellas de los dedos (fingerprints) del usuario y la posterior extracción de las plantillas de las huellas posteriores.

Sus principales funcionalidades son las siguientes:

* Dos modos de funcionamiento: extracción de los cuatro dedos de la mano (excepto el pulgar), o extracción únicamente del pulgar.
* Gestión interna de cámara.
* Gestión de permisos.
* Detección de vivacidad incorporada.
* Asistente en los procesos de captura de las huellas.
* Generación de las plantillas con las características de las huellas, imágenes y puntuaciones.

## Dependencias <a href="#id-2-dependencia" id="id-2-dependencia"></a>

### Capacitor:

```bash
npm install @facephi/sdk-phingers-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:phingers_tf_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKPhingersTFComponent', '~> $version'
```

## Método startPhingers <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del lector de huellas:

```dart
startPhingers(configuration: PhingersConfiguration): Promise<PhingersResult>;
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***PhingersConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface PhingersConfiguration 
{
  fingersFilter?: FingersFilter;
  reticleOrientation: ReticleOrientation;
  fingerSelectorHandOrientation?: PhingerSelectorHandOrientation;
  fingerSelectorOptions?: string[];
  showEllipses?: boolean;
  useLiveness?: boolean;
  showTutorial?: boolean;
  extractionTimeout?: number;
  vibration?: boolean;
  showDiagnostic?: boolean;
  threshold?: number;
  showPreviousTip?: boolean;
  showPreviousFingerSelector?: boolean;
}
```

{% content-ref url="/pages/YiYCyE3r02oYVzLIs2X9" %}
[Phingers Configuración](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***PhingersResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface PhingersResult 
{
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  fingers?: any;
  slapImages?: any;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/E1gYBTErWEYKApmDqqFF" %}
[Phingers Resultado](/sdks/sdk-mobile/framework-plugins/extras/phingers/phingers-resultado)
{% endcontent-ref %}


# Videoidentificación - VideoID

Este componente se encarga de realizar la grabación de un usuario identificándose, mostrando la cara y su documento de identidad.

## Dependencias

### Capacitor:

```bash
npm install @facephi/sdk-videoid-capacitor@<versión>
npm run build
npx cap sync
```

### Android - Gradle:

```kotlin
implementation "com.facephi.androidsdk:videoid_component:$version"
```

### iOS - Cocoapods:

```swift
s.dependency 'FPHISDKVideoIDomponent', '~> $version'
```

## Método startVideoIdComponent <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Una vez iniciado el SDK y creada una nueva operación se podrá lanzar el componente. Se podrá hacer uso de cualquiera de sus controladores para ejecutar su funcionalidad.

Lanzamiento del Componente:

```dart
Future<Map> startVideoIdComponent({required VideoIdConfiguration widgetConfigurationJSON})
{
  return FphiSdkmobileVideoidPlatform.instance.startVideoIdComponent(
      widgetConfigurationJSON: widgetConfigurationJSON
  );
}
```

## Configuración básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para lanzar el componente actual, se deberá crear un objeto ***VideoIdConfiguration*** que será la configuración del controlador del componente.

La configuración básica necesaria para es la siguiente:

```typescript
export interface VideoIdConfiguration {
  mode?: VideoMode;
  showTutorial?: boolean;
  autoFaceDetection?: boolean;
  url?: string;
  apiKey?: string;
  tenantId?: string;
  timeoutServerConnection?: number;
  sectionTime?: number;
  vibrationEnabled?: boolean;
  timeoutFaceDetection?: number;
  ocrValidations?: string[];
  countryFilter?: string[];
  documentFilter?: string[];
  sectionTimeout?: number;
  cameraPreferred?: CameraPreferred;
  maxRetries?: number;
  speechText?: string;
  debug?: boolean;
}
```

{% content-ref url="/pages/j2wTykQlqC8THAglzP3Z" %}
[Video Id Configuración](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-configuracion)
{% endcontent-ref %}

### Configuración avanzada del componente

A continuación se detallan todos los campos que forman parte de esta clase.

## Recepción del resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

El lanzamiento devolverá la información en formato ***VideoIdResult***. Pudiendo diferenciarse entre un lanzamiento correcto y uno incorrecto:

```typescript
export interface VideoIdResult {
  finishStatus: number;
  finishStatusDescription?: string;
  errorType: string;
  errorMessage?: string;
  faceImage?: string;
  faceImageTokenized?: string;
  documentFaceImageTokenized?: string;
  matchingSidesScore?: number;
  speechText?: string;
  documentType?: string;
  personalData?: any;
  frontDocumentData?: any;
  backDocumentData?: any;
  ocrMap?: any;
  ocrDiagnostic?: any;
}
```

A continuación se detallan todos los campos que forman parte de esta clase.

{% content-ref url="/pages/1nJjjGavGWsAq6dpXyWL" %}
[Video Id Resultado](/sdks/sdk-mobile/framework-plugins/extras/video-id/video-id-resultado)
{% endcontent-ref %}


# Extras

Documentación en común de los componentes con el resto de los híbridos.


# iOS

Guía de instalación nativa para híbridos.

Para ***iOS***, actualiza el archivo `Info.plist` con las claves necesarias a nivel aplicación cliente:

```xml
<key>NSCameraUsageDescription</key>
<string>Se requiere acceso a la cámara para la verificación biométrica.</string>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```

#### Añadir repositorio privado

Para tener acceso a nuestro repositorio privado, se requiere haber instalado previamente **Cocoapods** en la máquina.

Por cuestiones de seguridad y mantenimiento, los nuevos componentes de la ***SDKMobile*** se almacenan en unos repositorios privados que requieren de unas credenciales específicas para poder acceder a ellos. Esas credenciales deberá obtenerlas a través del equipo de soporte de Facephi. A continuación, se indica como preparar el entorno para consumir los componentes:

* Primero instalamos el comando que nos dará acceso a usar cocoapods con **Artifactory**.

```bash
sudo gem install cocoapods-art
```

En caso de utilizar un Mac con **chip M1**, pueden surgir errores durante la instalación es posible que surjan errores en el futuro, de ser así, se recomienda usar en cambio el siguiente comando:

```bash
sudo arch -arm64 gem install ffi; sudo arch -arm64 gem install cocoapods-art
```

En caso de tener problemas con la instalación, desinstalar completamente cocoapods y todas sus dependencias para hacer una instalación limpia.

* Necesitaremos añadir el repositorio a la lista del fichero **netrc**. Para ello, desde un Terminal, se ejecuta el siguiente comando:

```bash
$ nano ~/.netrc
```

Y copiamos el siguiente fragmento con los datos correspondientes al final del fichero:

```bash
machine facephicorp.jfrog.io
  login <USERNAME>
  password <TOKEN>
```

Es importante copiar de manera exacta el anterior fragmento de código. El indentado previo a las palabras login y password está formado por dos espacios.

* Finalmente se añadirá el repositorio que contiene dependencias privada:

```sh
pod repo-art add cocoa-pro-fphi 
"https://facephicorp.jfrog.io/artifactory/api/pods/cocoa-pro-fphi"
```

#### Dependencias requeridas para la integración

Para evitar conflictos y problemas de compatibilidad, en caso de querer instalar el componente en un proyecto que contenga una versión antigua de las librerías de Facephi (*Widgets*), éstos deberán eliminarse por completo antes de la instalación de los componentes de la ***SDKMobile***.

* Actualmente las librerías FacePhi se distribuyen remotamente a través de diferentes gestores de dependencias, en este caso, ***Cocoapods*****. Dependencias obligatorias** que deben ser instaladas previamente (añadiéndolas al *Podfile*):

```sh
plugin 'cocoapods-art', :sources => ['cocoa-pro-fphi’]
source 'https://cdn.cocoapods.org/'

target 'Example' do
... 
```

* Cuando se quiera actualizar dependencias, antes de ejecutar el ***pod install*** hay que usar el siguiente comando para actualizar el repositorio local:

```sh
pod repo-art update cocoa-pro-fphi --prune
```


# Android

Guía de instalación nativa para híbridos.

Asegúrate de declarar los permisos requeridos en tu `AndroidManifest.xml` en la aplicación del cliente:

```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
```

### Declaración de dependencias <a href="#id-2-lanzamiento-simplificado" id="id-2-lanzamiento-simplificado"></a>

#### Configurar el repositorio y la dependencia base <a href="#id-21-configurar-el-repositorio-y-la-dependencia-base" id="id-21-configurar-el-repositorio-y-la-dependencia-base"></a>

Por cuestiones de seguridad y mantenimiento, los nuevos componentes de la ***SDKMobile*** se almacenan en unos repositorios privados que requieren de unas credenciales específicas para poder acceder a ellos. Esas credenciales deberá obtenerlas a través del *equipo de soporte* de **Facephi**.

Una vez obtenidas las credenciales, se deberá incluir el siguiente fragmento de código en el fichero **settings.gradle**:

```kts
mavenCentral()
maven {
    Properties props = new Properties()
    def propsFile = new File('local.properties')
    if(propsFile.exists()){
        props.load(new FileInputStream(propsFile))
    }
    name="external"
    url = uri("https://facephicorp.jfrog.io/artifactory/maven-pro-fphi")
    credentials {
        username = props["artifactory.user"] ?: System.getenv("USERNAME_ARTIFACTORY")
        password = props["artifactory.token"] ?: System.getenv("TOKEN_ARTIFACTORY")
    }
}
```

Las credenciales se incluirán en el fichero *local.properties* con la siguiente estructura:

```bash
artifactory.user=YOUR_CREDENTIALS_USERNAME
artifactory.token=YOUR_CREDENTIALS_TOKEN
```

La otra alternativa es setear las variables del entorno y recuperarlas con el comando **System.getenv()** como se muestra en el código.




---

[Next Page](https://docs.facephi.com/llms-full.txt/1)

