# iOS

**BCC Face** é uma biblioteca destinada a ser integrada em uma aplicação iOS a partir de um `.framework` arquivo.

Ele usa a câmera do dispositivo para tirar uma foto de um rosto para fins biométricos. Fornece um teste simples de vivacidade ativa, exigindo que a pessoa sorria por cerca de um segundo e/ou olhe para a direita ou esquerda. O teste de vivacidade inclui uma opção para falar as instruções, facilitando o fluxo de trabalho para os usuários. Além disso, fornece um teste de vivacidade passiva que pode ser usado para verificar se a foto foi tirada de uma pessoa real sem exigir interação do usuário.

Este manual é atualizado para a versão do BCC Face Mobile iOS `4.8.0`.

{% hint style="warning" %}
O **teste de vivacidade passiva** está disponível apenas a partir da versão `4.4.0` em diante.
{% endhint %}

## Requisitos

* Git
* CocoaPods, disponível em <https://cocoapods.org/>.

## Instalação

### Instalando Dependências

1 - Adicione os seguintes Pods às dependências da aplicação no Podfile:

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

{% hint style="info" %}
Se a aplicação não possuir um Podfile, ele pode ser criado na pasta raiz do seu projeto Xcode usando o comando `pod init` no terminal. O Podfile não aparecerá diretamente no Xcode; ele será criado no diretório do projeto.
{% endhint %}

É preferível usar frameworks dinâmicos. Isso pode ser indicado usando a flag `use_frameworks!` no Podfile.

Um exemplo de Podfile com um target chamado **BCCs-Sample** é mostrado abaixo:

```ruby
platform :ios, '15.0'

target 'BCCs-Sample' do
	use_frameworks!

	pod 'GoogleMLKit/FaceDetection', '~> 6.0.0'
	pod 'lottie-ios', '~> 4.5.0'
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" %}
Na versão atual do BCC Face Mobile iOS (`4.8.0`), é necessário usar a versão `4.5.0` do **lottie-ios** da dependência, conforme especificado no exemplo acima, para garantir compatibilidade e evitar conflitos de versão.
{% endhint %}

{% hint style="warning" %}
Recomenda-se usar a mesma versão mínima do iOS suportada para sua aplicação como a deste framework: iOS 15.0, como no exemplo acima. Também é aconselhável definir a `BUILD_LIBRARY_FOR_DISTRIBUTION = YES` flag no Podfile para garantir compatibilidade com versões mais antigas do SDK.
{% endhint %}

2 - Feche o projeto Xcode, abra um terminal e vá para a pasta onde o Podfile está, e então execute:

```bash
pod install
```

Após a execução terminar, um arquivo com a `.xcworkspace` extensão será criado na mesma pasta.

3 - Abra o novo `.xcworkspace` arquivo.

{% hint style="warning" %}
A partir de agora, toda vez que o usuário quiser abrir o projeto, é necessário abri-lo através deste `.xcworkspace` arquivo, pois ele inclui as dependências.
{% endhint %}

### Importando e Configurando

#### Importando o Projeto

* Abra o projeto usando o `.xcworkspace` arquivo.
* Adicione o `BCCFace.framework` arquivo ao projeto, então adicione-o à lista de frameworks da sua aplicação.
  * Mova o `.framework` arquivo para a árvore de arquivos do projeto.

    > Se já houver uma pasta de frameworks, é recomendado mover o arquivo para lá.
  * Abra as configurações do projeto.
  * Vá para a *aba Geral* .
  * Clique e arraste o `.framework` para a árvore do projeto na seção `Frameworks, Libraries, etc.`
* Altere a `BCCFace.framework` configuração de `Do not embed` para `Embed & Sign`.
* Altere a versão alvo do seu projeto para um mínimo de iOS 15.

{% hint style="info" %}
É recomendado desabilitar iPad como target.
{% endhint %}

#### Configuração Inicial

Esta versão não possui dependências do Firebase, nem de uma configuração inicial chamada pelo AppDelegate. A única configuração inicial necessária é que a aplicação deve solicitar permissão de uso da câmera. Para isso, adicione a seguinte chave no `info.plist` arquivo, na Information Property List:

```properties
Chave :  Privacy - Camera Usage Description
Valor :  Permitir acesso à câmera
```

O valor da chave é uma mensagem a ser mostrada ao usuário quando solicitada a permissão de uso da câmera. Este valor pode ficar em branco ou ser preenchido com uma mensagem personalizada.

## Uso

### Parâmetros e Construtor

Para usar corretamente a biblioteca BCC Face, existem alguns parâmetros obrigatórios.

Um exemplo simples de uso da biblioteca é mostrado abaixo:

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

***

O `BCCFaceBuilder` o construtor da classe recebe os seguintes parâmetros:

* `hostVC: UIViewController` - View controller que chama a tela de captura.
* `delegate: BCCFaceDelegate` - Interface responsável por notificar eventos de captura (por exemplo, falha ou sucesso).

***

O `initializeCapture` o método também aceita um parâmetro opcional, como mostrado abaixo:

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

Se você quiser que a navegação ocorra através de um navigation controller, você deve fornecê-lo ao chamar o método.

***

O `BCCFaceBuilder` a classe é responsável por lidar com a configuração de uso para `BCCFace`. Os seguintes parâmetros são aceitos para configurar a captura biométrica e o comportamento do software:

* `buildSmileCheck(with smileProbability: ClosedRange<Float> = 0.5...1.0)` - Adiciona o sorriso para o teste de vivacidade e define o limiar de aceitação. Esse recurso é habilitado por padrão.
* `removeSmileCheck()` - Remove o sorriso do teste de vivacidade.
* `buildRotationCheck(_ rotationChecks: [HeadRotationCheck], headRotationAngle: ClosedRange<Float> = -6.0...6.0)` - Define uma lista de testes de vivacidade para rotação da cabeça e o ângulo máximo de rotação. Esse recurso é habilitado por padrão. As opções de rotação de cabeça são:

  ```swift
  enum class HeadRotationCheck {
  	case randomRotation
  	case leftRotation
  	case rightRotation
  }
  ```
* `removeHeadRotation()` - Remove a rotação de cabeça do teste de vivacidade.
* `addPassiveLiveness()` - Adiciona o teste de vivacidade passiva. Esse recurso é usado para verificar se a foto capturada é de uma pessoa real sem exigir qualquer interação do usuário. Para usar esse recurso, VOCÊ DEVE desabilitar os checagens de vivacidade ativas (`removeSmileCheck()` e `removeHeadRotation()`) que são adicionados por padrão.
* `buildSpeechSettings(_ speechSettings: SpeechSettings)` - Define os critérios para fala de acessibilidade, usando os seguintes parâmetros:

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

  * `volume` - O volume do áudio entre `0.0` e `1.0`.
  * `startsMuted` - Define se as instruções começam silenciadas ou não (`true` para mudo).
  * `pitch` - Define a entonação da voz para as instruções entre `0.5` (baixo) e `2.0` (alto).
  * `speed` - Define a velocidade da voz para as instruções. Este valor deve ser positivo.

  Os valores pré-definidos podem ser acessados através da variável estática:

  ```swift
  public static let defaultSpeechSettings = SpeechSettings(
  	volume: 1.0,
  	startsMuted: true,
  	pitch: 1.0,
  	speed: 0.5
  )
  ```
* `removeSpeech()` - Remove a fala de acessibilidade.
* `setReviewEnable(_ enable: Bool)` - Define se a tela de revisão da captura biométrica está habilitada ou desabilitada.
* `setInstructionEnable(_ enable: Bool)` - Define se a tela de instruções está habilitada ou desabilitada.
* `forceLanguage(_ language: BCCLanguages?)` - Força as instruções a serem mostradas em um único idioma. Se o idioma do dispositivo não for suportado, o inglês será usado. Os idiomas suportados são:

  ```swift
  public enum BCCLanguages: String {
  	case ptBR = "pt-BR"
  	case enUS = "en"
  	case esMX = "es"
  	case deviceLanguage = "deviceLanguage"
  }
  ```
* `removeLanguage()` - Remove o idioma forçado.

Para referência, aqui está uma lista completa de parâmetros e valores padrão:

```swift
var smileProbability: ClosedRange<Float> = 0.5...1.0
var headRotationAngle: ClosedRange<Float> = -6.0...6.0
var openEyesProbability: ClosedRange<Float> = 0.8...1.1
var livenessChecks: [LivenessChecks] = [.smileDetection, .headRotationRandom]
var speechSettings: SpeechSettings? = .defaultSpeechSettings
var language: BCCLanguages? = nil
var showPhotoReview: Bool = false
```

{% hint style="warning" %}
O teste de vivacidade ativo (usando sorriso e rotação aleatória da cabeça) está habilitado por padrão. Para usar apenas a checagem de vivacidade passiva, antes de adicioná-la, é necessário remover os métodos de vivacidade ativos do construtor:

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

{% endhint %}

Aqui está um trecho de código para inicializar uma captura usando apenas o teste de vivacidade passiva:

```swift
// Do ViewController desejado...

// Crie o builder
let faceBuilder = BCCFaceBuilder(self, delegate: self)

// Configure o builder
faceBuilder
	.removeSmileCheck()
	.removeHeadRotation()
	.addPassiveLiveness()

// Inicialize a captura a partir do builder
faceBuilder.initializeCapture(self.navigationController)
```

### Valores de Retorno

Os resultados da última captura facial podem ser recuperados usando o `faceCaptureDidFinish` método do `BCCFaceDelegate` interface:

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

O `data` o objeto contém as imagens capturadas durante o processo:

```swift
public struct BCCFaceReturnData {
	// Anteriormente 'photo', renomeado para estar em conformidade com o mesmo padrão do Android
	public internal(set) var originalPhoto: UIImage
	public internal(set) var croppedPhoto: UIImage?

	// Resultado de Vivacidade Passiva
	public internal(set) var passiveResult: Data?

	// API LEGADA: mesmo que 'originalPhoto'
	public var photo: UIImage { self.originalPhoto }
}
```

As propriedades retornadas são:

* `originalPhoto` (*imagem*) - A foto original tirada pela câmera.
* `croppedPhoto` (*imagem*) - A foto recortada, que é a imagem do rosto recortada da foto original.
* `passiveResult` (*Data*) - Conteúdo do arquivo da coleção para vivacidade passiva. Está presente apenas se capturado com sucesso. É o retorno da coleta para vivacidade passiva como *JPEG Data*. Esses dados podem ser salvos/exportados diretamente para um arquivo ou enviados pela rede (para envio na rede: a codificação do sistema pode ser feita facilmente, por exemplo, string Base64).

Se o usuário abortar a captura, fechando antes de capturar os biométricos, o método `faceCaptureDidAbort` será chamado. Você pode implementar este método para tratar esse cenário.

### Projeto de Exemplo

Este é um projeto de exemplo funcional para captura facial usando o 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
	) {
		// ...
	}
}
```
