# iOS

**BCC Face** es una biblioteca diseñada para integrarse en una aplicación iOS desde un `.framework` archivo.

Utiliza la cámara del dispositivo para tomar una foto de un rostro con fines biométricos. Proporciona una prueba simple de vivacidad activa, que requiere que la persona sonría durante aproximadamente un segundo y/o mire a la derecha o a la izquierda. La prueba de vivacidad incluye una opción para leer las instrucciones en voz alta, facilitando el flujo de trabajo para los usuarios. Además, proporciona una prueba de vivacidad pasiva que puede usarse para comprobar si la foto fue tomada de una persona real sin requerir interacción del usuario.

Este manual está actualizado para BCC Face Mobile iOS versión `4.11.3`.

{% hint style="warning" %}
La **prueba de vivacidad pasiva** está disponible solo a partir de la versión `4.4.0` en adelante.
{% endhint %}

## Requisitos

* Git
* CocoaPods, disponible en <https://cocoapods.org/>.

## Instalación

### Instalación de dependencias

1 - Agregue los siguientes Pods a las dependencias de la aplicación en el Podfile:

```ruby
pod 'GoogleMLKit/FaceDetection'
```

{% hint style="info" %}
Si la aplicación no posee un Podfile, puede crearse en la carpeta raíz de su proyecto Xcode usando el comando `pod init` en la terminal. El Podfile no aparecerá directamente en Xcode; se creará en el directorio del proyecto.
{% endhint %}

Es preferible usar frameworks dinámicos. Puede indicarse usando la bandera `use_frameworks!` en el Podfile.

Un ejemplo de Podfile con un target llamado **BCCs-Sample** se muestra a continuación:

```ruby
platform :ios, '15.0'

target 'BCCs-Sample' do
	use_frameworks!

	pod 'GoogleMLKit/FaceDetection'
	pod 'lottie-ios'
end

post_install do |installer|
	installer.pods_project.targets.each do |target|
		target.build_configurations.each do |config|
			config.build_settings['DEVELOPMENT_TEAM'] = "YOUR_DEVELOPMENT_TEAM_KEY"
			config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
		end
	end
end
```

{% hint style="warning" %}
Se recomienda usar la misma versión mínima de iOS compatible para su aplicación que la de este framework: iOS 15.0, como en el ejemplo anterior. También se aconseja establecer la `BUILD_LIBRARY_FOR_DISTRIBUTION = YES` bandera en el Podfile para garantizar la compatibilidad con versiones anteriores del SDK.
{% endhint %}

2 - Cierre el proyecto Xcode, abra una terminal y vaya a la carpeta donde está el Podfile, y luego ejecute:

```bash
pod install
```

Después de que finalice la ejecución, se creará un archivo con la extensión `.xcworkspace` en la misma carpeta.

3 - Abra el nuevo `.xcworkspace` archivo.

{% hint style="warning" %}
A partir de ahora, cada vez que el usuario quiera abrir el proyecto, será necesario abrirlo a través de este `.xcworkspace` archivo, ya que incluye las dependencias.
{% endhint %}

### Importación y configuración

#### Importación del proyecto

* Abra el proyecto usando el `.xcworkspace` archivo.
* Agregue el `BCCFace.framework` archivo al proyecto, luego agréguelo a la lista de frameworks de su aplicación.
  * Mueva el `.framework` archivo al árbol de archivos del proyecto.
  * Si ya existe una carpeta de frameworks, se recomienda mover el archivo allí.
  * Abra la configuración del proyecto.
  * Vaya a la pestaña *General* .
  * Haga clic y arrastre el `.framework` al árbol del proyecto, en la sección `Frameworks, Libraries, etc.`
* Cambie la configuración de `BCCFace.framework` de `Do not embed` a `Embed & Sign`.
* Cambie la versión objetivo de su proyecto a un mínimo de iOS 15.

{% hint style="info" %}
Se recomienda deshabilitar iPad como objetivo.
{% endhint %}

#### Configuración inicial

Esta versión no tiene dependencias de Firebase, ni tampoco una configuración inicial llamada por AppDelegate. La única configuración inicial necesaria es que la aplicación solicite permiso de uso de la cámara. Para hacerlo, agregue la siguiente clave en el archivo `info.plist` , en el Information Property List:

```properties
Clave    :  Privacy - Camera Usage Description
Valor  :  Allow access to camera
```

El valor de la clave es un mensaje que se mostrará al usuario cuando se solicite el permiso de uso de la cámara. Este valor puede estar vacío o completarse con un mensaje personalizado.

## Uso

### Parámetros y constructor

Para usar correctamente la biblioteca BCC Face, hay algunos parámetros obligatorios.

A continuación se muestra un ejemplo simple de uso de la biblioteca:

```swift
BCCFaceBuilder(self, delegate: self).initializeCapture()
```

***

La `BCCFaceBuilder` el constructor de la clase recibe los siguientes parámetros:

* `hostVC: UIViewController` - Controlador de vista que llama a la pantalla de captura.
* `delegate: BCCFaceDelegate` - Interfaz responsable de notificar eventos de captura (por ejemplo, fallo o éxito).

***

La `initializeCapture` el método también acepta un parámetro opcional, como se muestra a continuación:

```swift
public func initializeCapture(
	_ navController: UINavigationController? = nil
) {
	// ...
}
```

Si desea que la navegación se ejecute a través de un controlador de navegación, debe proporcionarlo al llamar al método.

***

La `BCCFaceBuilder` la clase es responsable de manejar la configuración de uso para `BCCFace`. Los siguientes parámetros se aceptan para configurar la captura biométrica y el comportamiento del software:

* `buildSmileCheck(with smileProbability: ClosedRange<Float> = 0.5...1.0)` - Agrega la sonrisa para la prueba de vivacidad y define el umbral de aceptación. Esta función está habilitada de forma predeterminada.
* `removeSmileCheck()` - Elimina la sonrisa para la verificación de vivacidad.
* `buildRotationCheck(_ rotationChecks: [HeadRotationCheck], headRotationAngle: ClosedRange<Float> = -6.0...6.0)` - Define una lista de pruebas de vivacidad para la rotación de la cabeza y el ángulo máximo de rotación. Esta función está habilitada de forma predeterminada. Las opciones de rotación de la cabeza son:

  ```swift
  enum class HeadRotationCheck {
  	case randomRotation
  	case leftRotation
  	case rightRotation
  }
  ```
* `removeHeadRotation()` - Elimina la rotación de la cabeza para la verificación de vivacidad.
* `addPassiveLiveness()` - Agrega la prueba de vivacidad pasiva. Esta función se usa para comprobar si la foto capturada proviene de una persona real sin requerir ninguna interacción del usuario. Para usar esta función, DEBE deshabilitar las verificaciones de vivacidad activa (`removeSmileCheck()` y `removeHeadRotation()`) que se agregan de forma predeterminada.
* `buildSpeechSettings(_ speechSettings: SpeechSettings)` - Define los criterios para el habla de accesibilidad, usando los siguientes parámetros:

  ```swift
  class SpeechSettings(
  	public let volume: Float
  	public let startsMuted: Bool
  	public let pitch: Float
  	public let speed: Float
  )
  ```

  * `volume` - El volumen de audio entre `0.0` y `1.0`.
  * `startsMuted` - Define si las instrucciones comienzan en silencio o no (`true` para silenciado).
  * `pitch` - Define el tono de voz de las instrucciones entre `0.5` (grave) y `2.0` (agudo).
  * `speed` - Define la velocidad de la voz de las instrucciones. Este valor debe ser positivo.

  Los valores predefinidos pueden accederse mediante la variable estática:

  ```swift
  public static let defaultSpeechSettings = SpeechSettings(
  	volume: 1.0,
  	startsMuted: true,
  	pitch: 1.0,
  	speed: 0.5
  )
  ```
* `removeSpeech()` - Elimina el habla de accesibilidad.
* `setInstructionEnable(_ enable: Bool)` – Define si la pantalla de instrucciones está habilitada o deshabilitada.
* `forceLanguage(_ language: BCCLanguages?)` - Obliga a que las instrucciones se muestren en un solo idioma. Si el idioma del dispositivo no es compatible, se usará inglés. Los idiomas compatibles son:

  ```swift
  public enum BCCLanguages: String {
  	case ptBR = "pt-BR"
  	case enUS = "en"
  	case esMX = "es"
  	case deviceLanguage = "deviceLanguage"
  }
  ```
* `enableFlashButton(_ enable: Bool)` – Habilita (`true`) o deshabilita (`false`) el botón del flash en la cámara trasera. Predeterminado: deshabilitado (`false`).
* `enableManualCapture(_ enable: Bool)` – Habilita (`true`) o deshabilita (`false`) el botón de captura manual, permitiendo al usuario omitir las comprobaciones automáticas de captura. Al realizar una captura manual, el usuario podrá revisar la foto capturada antes de completar el proceso.
* `setImageCompressionFormat(_ format: ImageCompressionFormat)` – Define el formato de compresión para una captura de vivacidad pasiva. Las opciones disponibles son `.jpeg` (predeterminado) o `.jpeg2000`.
* `enableIntegrityValidation(clientSecret: Data, nonce: Data)` – Habilita la validación de integridad para la detección de vivacidad pasiva, añadiendo una capa adicional de seguridad para garantizar la integridad del payload.

Como referencia, aquí tiene una lista completa de parámetros y valores predeterminados:

```swift
var headRotationAngle: ClosedRange<Float> = -6.0...6.0
var openEyesProbability: ClosedRange<Float> = 0.8...1.1
var smileProbability: ClosedRange<Float> = 0.5...1.0
var livenessChecks: [LivenessChecks] = [.smileDetection]
var headRotationChecks: [HeadRotationCheck] = [.randomRotation]
var speechSettings: SpeechSettings? = .defaultSpeechSettings
var cameraSettings: CameraSettings = .defaultCameraSettings
var canEnableManualCapture: Bool = false
var canEnableFlash: Bool = true
var language: BCCLanguages? = nil
var showInstructions: Bool = false
var imageCompressionFormat: ImageCompressionFormat = .jpeg
var integrityValidationData: IntegrityValidationData? = nil
```

{% hint style="warning" %}
La prueba de vivacidad activa (usando sonrisa y rotación aleatoria de la cabeza) está habilitada de forma predeterminada. Para usar solo la verificación de vivacidad pasiva, antes de agregarla, es necesario eliminar los métodos de vivacidad activa del constructor:

```swift
BCCFaceBuilder(self, delegate: self)
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()
```

{% endhint %}

Aquí hay un fragmento de código para inicializar una captura usando solo la prueba de vivacidad pasiva:

```swift
// Desde el ViewController deseado...

// Crear el builder
let faceBuilder = BCCFaceBuilder(self, delegate: self)

// Configurar el builder
faceBuilder
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()

// Inicializar la captura desde el builder
faceBuilder.initializeCapture(self.navigationController)
```

### Valores de retorno

Los resultados de la última captura facial pueden recuperarse usando el método `faceCaptureDidFinish` del interfaz `BCCFaceDelegate` :

```swift
func faceCaptureDidFinish(
	data: BCCFaceReturnData,
	analytics: BCCFaceReturnAnalytics
)
```

La `data` el objeto contiene las imágenes capturadas durante el proceso:

```swift
public struct BCCFaceReturnData {
	// Anteriormente 'photo', renombrado para ajustarse al mismo estándar que Android
	public internal(set) var originalPhoto: UIImage
	public internal(set) var croppedPhoto: UIImage?

	// Resultado de vivacidad pasiva
	public internal(set) var passiveResult: Data?

	// API LEGACY: igual que 'originalPhoto'
	public var photo: UIImage { self.originalPhoto }
}
```

Las propiedades devueltas son:

* `originalPhoto` (*imagen*) - La foto original tomada por la cámara.
* `croppedPhoto` (*imagen*) - La foto recortada, que es la imagen del rostro recortada de la foto original.
* `passiveResult` (*Data*) - Contenido del archivo de la recopilación para vivacidad pasiva. Solo está presente si se capturó correctamente. Es el retorno de la recopilación para vivacidad pasiva como *JPEG Data*. Estos datos pueden guardarse/exportarse directamente a un archivo o enviarse a la red (para networking: la codificación del sistema se puede hacer fácilmente, por ejemplo, una cadena Base64).

Si el usuario aborta la captura, cerrando antes de capturar los datos biométricos, se llamará al método `faceCaptureDidAbort` . Puede implementar este método para tratar este escenario.

### Proyecto de ejemplo

Este es un proyecto de ejemplo funcional para una captura facial usando BCC Mobile Face iOS:

```swift
import UIKit
import BCCFace

class ViewController: UIViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
	}

	@IBAction func startCapture(_ sender: UIButton) {
		BCCFaceBuilder(self, delegate: self)
			.removeSmileCheck()
			.removeHeadRotation()
			.addPassiveLiveness()
			.buildCameraSettings(.frontSwitchable)
			.enableFlashButton(true)
			.initializeCapture(navigationController)
	}
}

extension ViewController: BCCFaceDelegate {
	func faceCaptureDidFinish(
		data: BCCFace.BCCFaceReturnData,
		analytics: BCCFace.BCCFaceAnalytics
	) {
		// ...
	}

	func faceCaptureDidAbort(
		analytics: BCCFace.BCCFaceAnalytics
	) {
		// ...
	}
}
```

## Instrucciones para el agente: consulta de esta documentación <a href="#agent-instructions-querying-this-documentation" id="agent-instructions-querying-this-documentation"></a>

Si necesita información adicional que no está disponible directamente en esta página, puede consultar la documentación de forma dinámica haciendo una pregunta.

Realice una solicitud HTTP GET en la URL actual de la página con el parámetro de consulta `ask` :

```
GET https://docs.griaule.com/sdks/bcc-face/bccmobilefaceios.md?ask=<question>
```

La pregunta debe ser específica, autocontenida y escrita en lenguaje natural. La respuesta contendrá una respuesta directa a la pregunta y fragmentos y स्रोत relevantes de la documentación.

Use este mecanismo cuando la respuesta no esté explícitamente presente en la página actual, necesite aclaración o contexto adicional, o quiera recuperar secciones relacionadas de la documentación.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.griaule.com/sdks/es/bcc-face/bccmobilefaceios.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
