> For the complete documentation index, see [llms.txt](https://docs.caf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.caf.io/caf-sdk/caf-sdk-pt-br/ios/getting-started-with-the-sdk-5.md).

# Introdução legada ao SDK

{% hint style="warning" %}
A versão 7.0.0 traz uma forma opcional e mais rápida de inicializar o SDK com menos linhas de código. Além dessa atualização de código, lançamos uma página de documentação totalmente nova e mais fácil de ler. Para adotar essa nova configuração, [confira o guia atualizado.](/caf-sdk/caf-sdk-pt-br/ios/getting-started-with-the-sdk.md)
{% endhint %}

## Sobre o CafSDK

Esta documentação técnica cobre a **implementação do CafSDK para iOS**, detalhando a configuração, inicialização, execução dos fluxos de captura e personalizações avançadas.

Atualmente, o CafSDK integra dois módulos principais: **Face Liveness (FL)** e **Document Detector (DD)**, executados sequencialmente com uma interface de configuração unificada.

### O que é Face Liveness

É o módulo que valida a autenticidade de um rosto capturado por um aplicativo de fotos, garantindo que a imagem corresponda a uma pessoa real.

**Características técnicas:**

* Configuração de URL para autenticação (`authBaseUrl`) e verificação de liveness (`livenessBaseUrl`).
* Flags para habilitar captura de tela e modo de depuração.
* Suporte a múltiplos provedores de autenticação.

### O que é Document Detector

É o módulo que permite a captura e o processamento de documentos (por exemplo, carteira de identidade, cartão de CPF, passaporte etc.).

**Características técnicas:**

* Configuração de um fluxo passo a passo definido por `CafDocumentDetectorStep` para captura de documentos.
* Parâmetros operacionais, como timeout, flags de captura manual e outras configurações.
* Possibilidade de usar a câmera para validações de enquadramento ou envio de arquivo de documento.

***

## Comece a usar o SDK

**Adicione a dependência**

O CafSDK oferece integração por meio de **Swift Package Manager (SPM) e CocoaPods**, oferecendo flexibilidade para escolher o gerenciador de dependências que melhor se adapta ao seu projeto. Este guia explica as etapas necessárias para adicionar o CafSDK ao seu projeto iOS e traz detalhes sobre os módulos disponíveis.

### Requisitos para adicionar

Para usar os módulos do CafSDK no iOS, certifique-se de que seu projeto atenda aos requisitos mínimos:

| Requisito                         | Versão |
| --------------------------------- | ------ |
| **Destino de implantação do iOS** | 15.0+  |
| **Xcode**                         | 26.0+  |
| **Swift**                         | 6.3+   |

> **Observação**: configure o Info.plist do seu projeto com as permissões necessárias para acesso à câmera e à rede.

* **Token mobile da CAF**: válido [mobileToken da CAF](https://github.com/combateafraude/public-docs/blob/docs-sdks/sdk_integration_documentation.md)

### **Etapas para adicionar**

**Via Swift Package Manager (SPM)**

**Etapa 1 - Adicione a dependência**

Abra o arquivo `Package.swift` do seu projeto e adicione a seguinte dependência. Isso informa ao Swift Package Manager onde localizar o repositório do CafSDK:

```swift
dependencies: [
    .package(url: "https://github.com/combateafraude/caf-ios-sdk.git", from: "6.4.2")
]
```

**Etapa 2 - Inclua os produtos desejados**

Depois de adicionar a dependência, inclua os produtos necessários no target da sua aplicação. Isso permite integrar o SDK completo ou selecionar apenas módulos específicos, de acordo com suas necessidades:

```swift
.target(
    name: "YourApp",
    dependencies: [
        .product(name: "CafSDK", package: "caf-ios-sdk"),            // SDK completo
        .product(name: "DocumentDetector", package: "caf-ios-sdk"),    // Somente DocumentDetector
        .product(name: "CafFaceLiveness", package: "caf-ios-sdk"),       // Somente CafFaceLiveness
        .product(name: "IproovProvider", package: "caf-ios-sdk"),        // Provedor iProov opcional
        .product(name: "FaceTec2DProvider", package: "caf-ios-sdk"),     // Provedor FaceTec 2D opcional
        .product(name: "FortfaceProvider", package: "caf-ios-sdk")       // Provedor Fortface opcional (PayFace)
    ]
)
```

**Informações adicionais**

* **Modularidade:** integre apenas os módulos necessários para manter seu projeto leve.
* **Compatibilidade:** o SDK é compatível com iOS 15.0+ e foi desenvolvido com Swift 5.10+.
* **Gerenciamento de versão:** Verifique sempre o repositório oficial para obter a versão mais recente.

### Via CocoaPods

**Etapa 1 - Atualize seu Podfile**

Para integrar o CafSDK usando CocoaPods, abra o Podfile do seu projeto e adicione as seguintes linhas. Isso instruirá o CocoaPods a baixar os artefatos necessários do repositório oficial:

```bash
# SDK completo
pod 'CafSDKiOS'

# Somente DocumentDetector
pod 'CafSDKiOS/DocumentDetector'

# Somente CafFaceLiveness
pod 'CafSDKiOS/CafFaceLiveness'

# Provedor iProov opcional
pod 'CafSDKiOS/IproovProvider'

# Provedor FaceTec 2D opcional
pod 'CafSDKiOS/FaceTec2DProvider'

# Provedor Fortface opcional (PayFace)
pod 'CafSDKiOS/FortfaceProvider'

```

**Etapa 2 - Instale as dependências**

Depois de atualizar seu Podfile, abra um terminal no diretório raiz do seu projeto e execute:

```bash
pod install
```

Este comando baixa e integra todos os módulos específicos ao seu projeto.

**Informações adicionais**

* **Integração seletiva:** escolha apenas os módulos necessários para seu projeto, otimizando o desempenho.
* **Gerenciamento automático de dependências:** O CocoaPods gerencia automaticamente a resolução de versões e conflitos de dependência.
* **Documentação e suporte:** para instruções mais detalhadas ou solução de problemas, consulte a documentação do CafSDK.

***

## Como inicializar o SDK

Este guia explica como inicializar o CafSDK no iOS. Ele aborda os requisitos, permissões, configuração global, configuração específica de módulos e inicialização do builder.

### Permissões

Para que os módulos do SDK funcionem corretamente, você deve declarar as seguintes permissões no seu **Info.plist**:

**Para Face Liveness:**

* **Descrição de uso da câmera (**`NSCameraUsageDescription`**):** explica por que o aplicativo precisa de acesso à câmera para detecção facial.
* **Acesso à rede:** nenhuma permissão explícita é necessária, mas certifique-se de que seu aplicativo suporte conexões seguras (HTTPS/WSS).

**Para Document Detector:**

* **Descrição de uso da câmera (**`NSCameraUsageDescription`**):** necessária para capturar imagens de documentos.
* **Descrição de uso da biblioteca de fotos (**`NSPhotoLibraryUsageDescription`**):** necessária se seu aplicativo suportar o envio de imagens da biblioteca (opcional).

### Configuração de segurança

A partir da versão 6.0.0, o CafSDK inclui recursos de proteção em tempo de execução do aplicativo (RASP). A partir da versão 6.4.2, a aplicação dessas verificações é controlada exclusivamente pela `securityEnabled` propriedade em `CafSDKConfiguration`.

* **Propriedade:** `securityEnabled`
* **Tipo:** `Bool`
* **Padrão:** `false`

Quando definido como `true`, o SDK executará uma validação de segurança rigorosa durante a inicialização e a execução. Se uma violação de segurança for detectada, o SDK lançará uma `securityException` e encerrará o fluxo.

**Exemplo de código:**

```swift
let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.faceLiveness, .documentDetector],
    securityEnabled: true
)
```

> **Observação:** Recomendamos fortemente habilitar essa flag em builds de produção para garantir a integridade do processo de captura.

> **Migração de `CAFEnforceSecurity`:** A `CAFEnforceSecurity` `Info.plist` flag foi removida na versão 6.4.2 e não é mais lida pelo SDK. Defina `securityEnabled` ativado `CafSDKConfiguration` em vez disso.

***

### **Configurações**

O processo de inicialização é dividido em duas partes: configuração global e configuração específica de módulos.

**Configuração global**

Crie um `CafSDKConfiguration` objeto, que serve como o contêiner central para todas as configurações. Essa configuração define a ordem de execução dos módulos e a identidade visual (por meio de uma configuração de cores).

**Exemplo de código:**

```swift
let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.faceLiveness, .documentDetector] // Obrigatório
)
```

**Configuração específica do módulo**

Após as configurações globais, configure cada módulo individualmente para ajustar os parâmetros operacionais, de segurança e visuais.

**Configuração do Document Detector**

Configure o módulo Document Detector especificando o fluxo de captura e opções como captura manual e confirmações em pop-up.

**Exemplo de código:**

```swift
sdkConfig.setDocumentDetectorConfig(CafDocumentDetectorConfig(
    flow: [CafDocumentDetectorStep(stepType: .cnhFull)] // Necessário para o fluxo do detector de documentos
))
```

Consulte: [DocumentDetector](#custom-settings-document-detector)

**Configuração do Face Liveness**

Configure o módulo Face Liveness para validar que o rosto capturado pertence a uma pessoa viva. Defina opções para indicadores de carregamento, endpoints e certificados de segurança.

**Exemplo de código:**

```swift
sdkConfig.setFaceLivenessConfig(CafFaceLivenessConfig())
```

Consulte: [FaceLiveness](#custom-settings-face-liveness)

***

## Inicialização do builder

A inicialização do builder é a etapa em que o fluxo de captura do CafSDK é configurado para execução. Use `CafSdkProvider.Builder` para fornecer os parâmetros necessários, incluindo um token mobile, ID da pessoa, ambiente e o callback unificado para tratar eventos.

**Exemplo de código:**

```swift
// Crie a configuração do SDK com os módulos desejados e as configurações personalizadas
var sdkConfig = CafSDKConfiguration(
        presentationOrder: [.faceLiveness, .documentDetector]
    ).setDocumentDetectorConfig(CafDocumentDetectorConfig(flow: [CafDocumentDetectorStep(stepType: .cnhFront)])) // Exemplo de documento obrigatório
        .setFaceLivenessConfig(CafFaceLivenessConfig())

// Construa o SDK com os parâmetros necessários e um callback para eventos
let builder = CafSDKProvider.Builder(
    self,
    mobileToken: "yourToken",
    personId: "personId",
    environment: .prod,
    configuration: sdkConfig,
    callback: { [weak self] event in
        self?.handleUnifiedEvent(event)
    }
)
let sdk = builder.build()

// Inicie a sessão do SDK
sdk.start()

// Exemplo de manipulador de evento unificado
private func handleUnifiedEvent(_ event: CafUnifiedEvent) {
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        switch event {
        case .loading:
            print("🔄 Carregando...")
        case .loaded:
            print("🔄 Carregado")
        case .success(let responses):
            responses.forEach { response in
                print("Módulo: \(response.moduleName) Resposta assinada: \(response.signedResponse)")
            }
        case .failure(let jwtResponse, let type, let description):
            print("Falha: \(type) - \(description ?? \"Sem descrição\")")
            if let jwt = jwtResponse {
                print("Resposta JWT: \(jwt)")
            }
        case .error(let type, let desc):
            print("Erro: \(type) \(desc)")
        case .cancelled:
            print("⚠️ Cancelado")
        case .log(let level, let message):
            print("[\(level)] \(message)")
        }
    }
}
```

**Detalhes do processo**

* **Configuração global:** define o fluxo geral e a aparência usando `presentationOrder` e `CafColorConfiguration`.
* **Configuração específica do módulo:** personaliza os módulos Document Detector e Face Liveness com configurações individuais (por exemplo, fluxo de captura, indicador de carregamento, endpoints da API).
* **Inicialização com o Builder:** o padrão builder reúne todos os parâmetros necessários (token mobile, ID da pessoa, ambiente, configuração e callback) para criar e iniciar o SDK.

Seguindo estas etapas, seu projeto iOS será configurado corretamente para usar o CafSDK, garantindo uma integração robusta e eficiente dos módulos de detecção de documentos e verificação facial.

### Pré-carregamento da sessão (opcional)

A `loadSession()` o método permite pré-carregar a sessão do usuário antes de iniciar o fluxo do SDK. Isso melhora o tempo de abertura do SDK de Face Liveness ao preparar a sessão e os recursos relacionados com antecedência, resultando em uma inicialização mais rápida quando `start()` for chamado.

**Quando usar:**

* Quando você quiser otimizar a experiência do usuário reduzindo o tempo inicial de carregamento
* Quando você tiver a oportunidade de pré-carregar a sessão antes que o usuário realmente precise iniciar o fluxo
* Particularmente útil para a inicialização do módulo Face Liveness

**Exemplo de código:**

```swift
let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.faceLiveness, .documentDetector]
).setFaceLivenessConfig(CafFaceLivenessConfig())

let builder = CafSDKProvider.Builder(
    self,
    mobileToken: "mobile-token",
    personId: "person-id",
    environment: .prod,
    configuration: sdkConfig
) { [weak self] event in
    self?.handleUnifiedEvent(event)
}

let sdk = builder.build()

// Pré-carregue a sessão (opcional)
sdk.loadSession()

// Mais tarde, quando estiver pronto para iniciar o fluxo
sdk.start()
```

**Notas importantes:**

* Este método é opcional e deve ser chamado após `build()` mas antes de `start()`
* Pré-carregar a sessão ajuda a reduzir o tempo inicial de carregamento quando `start()` for eventualmente chamado
* O callback unificado receberá `.loading` e `.loaded` eventos durante o pré-carregamento, que podem ser usados para atualizar a interface
* Isso é particularmente benéfico para a inicialização do módulo Face Liveness

***

## Concluindo uma sessão

Uma sessão completa no CafSDK abrange todo o fluxo, da inicialização à conclusão — seja essa conclusão uma validação bem-sucedida, um erro ou um cancelamento pelo usuário.

**Tratamento de eventos da sessão**

O callback do builder retorna um conjunto de eventos definido pela `CafUnifiedEvent` enumeração. Esses eventos incluem:

* `Carregando`: Indica uma solicitação de carregamento do SDK
* `Carregado`: Indica a conclusão da solicitação de carregamento do SDK
* `Success(responses: [CafUnifiedResponse])`: Resultados finais (quando `waitForAllServices=true`)
* `Failure(response: String?, type: CafFailureType, description: String?)`: Falhas específicas do módulo
* `Error(type: CafErrorType, description: String)`: Erros críticos de execução
* `Cancelled`: Cancelamento iniciado pelo usuário
* `Log(level: CafLogLevel, message: String)`: Informações de depuração

### Detalhamento dos tipos de erro

### Tipos de falha (CafFailureType)

| Caso do enum      | Valor bruto           | Condição de acionamento                                              | GPA |  LA |
| ----------------- | --------------------- | -------------------------------------------------------------------- | :-: | :-: |
| `desconhecido`    | "desconhecido"        | Falha genérica                                                       |  ✅  |  ❌  |
| `tooMuchMovement` | "too\_much\_movement" | Movimento excessivo da cabeça                                        |  ✅  |  ❌  |
| `tooBright`       | "too\_bright"         | Superiluminação                                                      |  ✅  |  ❌  |
| `tooDark`         | "too\_dark"           | Condições de pouca luz                                               |  ✅  |  ❌  |
| `misalignedFace`  | "misaligned\_face"    | Falha no alinhamento do rosto                                        |  ✅  |  ❌  |
| `eyesClosed`      | "eyes\_closed"        | Olhos fechados durante a captura                                     |  ✅  |  ✅  |
| `faceTooFar`      | "face\_too\_far"      | Rosto muito distante                                                 |  ✅  |  ❌  |
| `faceTooClose`    | "face\_too\_close"    | Rosto muito próximo                                                  |  ✅  |  ❌  |
| `sunglasses`      | "sunglasses"          | Óculos que obscurecem os olhos                                       |  ✅  |  ❌  |
| `obscuredFace`    | "obscured\_face"      | Obstrução parcial do rosto                                           |  ✅  |  ✅  |
| `multipleFaces`   | "multiple\_faces"     | Múltiplos rostos detectados                                          |  ✅  |  ✅  |
| `óculos`          | "óculos"              | Óculos gerais detectados que precisam ser removidos                  |  ⚠️ |  ✅  |
| `faceNotFound`    | "face\_not\_found"    | Nenhum rosto detectado na moldura oval                               |  ⚠️ |  ✅  |
| `framesBlurry`    | "frames\_blurry"      | As imagens estão borradas demais para processamento                  |  ⚠️ |  ✅  |
| `lightingIssues`  | "lighting\_issues"    | Problemas gerais de iluminação ou reflexo                            |  ⚠️ |  ✅  |
| `motionIssue`     | "motion\_issue"       | Problemas de captura relacionados a movimento                        |  ⚠️ |  ✅  |
| `backgroundIssue` | "background\_issue"   | Fundo problemático (muito movimentado ou com pouco contraste)        |  ⚠️ |  ✅  |
| `deviceIssue`     | "device\_issue"       | Falha relacionada ao hardware ou à câmera                            |  ⚠️ |  ✅  |
| `deviceRestart`   | "device\_restart"     | Recomendação para reiniciar o dispositivo                            |  ⚠️ |  ✅  |
| `systemError`     | "system\_error"       | Erro interno do sistema                                              |  ⚠️ |  ✅  |
| `rejected`        | "rejected"            | Transação ou verificação rejeitada                                   |  ⚠️ |  ✅  |
| `timeout`         | "timeout"             | A sessão atingiu o tempo limite                                      |  ⚠️ |  ✅  |
| `userNotFound`    | "user\_not\_found"    | O usuário não pôde ser identificado ou não foi encontrado no sistema |  ⚠️ |  ✅  |
| `processingFault` | "processing\_fault"   | Erro interno de processamento no lado do servidor                    |  ⚠️ |  ✅  |

```swift
case .failure(let jwtResponse, let type, let desc):
    switch type {
    case .eyesClosed:
        showAlert("Mantenha os olhos abertos")
    case .multipleFaces:
        showAlert("Apenas um rosto é permitido")
    // Lidar com outros casos
    }
```

***

### Tipos de Erro (CafErrorType)

| Caso do enum                    | Condição de acionamento                              |
| ------------------------------- | ---------------------------------------------------- |
| `unsupportedDevice`             | Especificações de dispositivo não suportadas         |
| `cameraPermission`              | Acesso à câmera negado                               |
| `networkException`              | Problemas de conectividade de rede                   |
| `serverException`               | Falha no processamento do backend                    |
| `tokenException`                | Token inválido/expirado                              |
| `captureAlreadyActiveException` | Sessão iProov simultânea                             |
| `faceAuthentication`            | Erro de autenticação facial                          |
| `unexpectedErrorException`      | Erro crítico irrecuperável                           |
| `userTimeoutException`          | Tempo limite de captura excedido                     |
| `imageNotFoundException`        | Dados da imagem ausentes                             |
| `tooManyRequestsException`      | Limite de taxa da API excedido                       |
| `unknownException`              | Erro não classificado                                |
| `libraryException`              | Erro de baixo nível do framework                     |
| `permissionException`           | Permissões do sistema ausentes                       |
| `invalidResponseException`      | Resposta inválida recebida                           |
| `securityException`             | Violação de segurança em tempo de execução detectada |

```swift
case .error(let type, let desc):
    switch type {
    case .cameraPermission:
        requestCameraAccess()
    case .networkException:
        showRetryButton()
    case .invalidResponseException:
        showAlert("Resposta inválida recebida do servidor")
    // Lidar com outros erros
    }
```

### Importante

Uma sessão é considerada concluída quando todos os módulos do fluxo de captura terminarem sua operação com sucesso ou quando o processo for interrompido por um erro ou por cancelamento do usuário. Em uma sessão concluída:

**Execução completa**

Cada módulo que termina com sucesso envia um evento `Sucesso` , incluindo:

* `moduleName`: identifica o módulo (por exemplo, "documentDetector" ou "faceLiveness") que concluiu a operação.
* `signedResponse`: Um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.

**Fluxo interrompido**

Se ocorrer um erro ou o usuário cancelar o processo:

* `Erro`: um `CafUnifiedEvent.Error` evento é disparado com uma mensagem de erro descritiva, permitindo que você faça a recuperação ou notifique o usuário.
* `Cancelled`: um `CafUnifiedEvent.Cancelled` evento é ativado, o que permite limpar recursos ou exibir uma mensagem de cancelamento.

**Exemplo de Tratamento de Eventos**

Confira um exemplo de como tratar esses eventos no callback unificado para iOS:

```swift
func handleUnifiedEvent(_ event: CafUnifiedEvent) {
    switch event {
    case .loading:
        // Exibir um indicador de carregamento
        break
    case .loaded:
        // Atualizar a interface para mostrar que os módulos estão prontos
        break
    case .success(let responses):
        // Processar todas as respostas bem-sucedidas
        responses.forEach { response in
            print("Módulo: \(response.moduleName) Resultado: \(response.signedResponse)")
        }
    case .failure(let response, let type, let description):
        // Lidar com falhas específicas do SDK com diagnósticos detalhados
        print("Falha: \(type) - \(description)")
        if let response = response {
            print("Resposta JWT: \(response)")
        }
    case .error(let type, let desc):
        print("Erro: \(type) \(desc)")
    case .cancelled:
        // Tratar o cancelamento de forma graciosa
        break
    case .log(let level, let message):
        // Registrar mensagens internas para fins de depuração
        print("[\(level)] \(message)")
    }
}
```

**Resumo**

* **Sessão concluída:** uma sessão é considerada concluída quando todos os módulos configurados terminam suas tarefas com sucesso, ou quando ocorre um erro/cancelamento.
* **Gerenciamento centralizado:** O callback unificado garante que, independentemente do resultado, seu aplicativo será notificado e poderá tomar a ação adequada.

Essa abordagem garante uma integração robusta com o CafSDK, lidando de forma eficiente com cada estado do fluxo de captura, do início ao fim.

***

### Fluxo avançado

Esta seção explica como personalizar e ajustar o fluxo de captura do CafSDK para atender a requisitos de negócios específicos e melhorar a experiência do usuário no iOS.

**Ordem de execução dos módulos**

A ordem em que os módulos são executados é definida pelo `presentationOrder` campo do `CafSDKConfiguration` objeto. Essa sequência é crucial, pois impacta diretamente a lógica do fluxo. Por exemplo, se o processo exigir que o documento seja capturado antes da validação facial, a ordem deve refletir essa prioridade.

**Exemplo de código:**

```swift
let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.documentDetector, .faceLiveness],
    colorConfig: CafColorConfiguration(
        primaryColor: "#FF0000",
        secondaryColor: "#FFFFFF",
        contentColor: "#FF0000",
        backgroundColor: "#FFFFFF",
        mediumColor: "#00FF00",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"
    ), // Opcional
    waitForAllServices: true, // Opcional
    enableTransitionScreens: true // Opcional
)
```

### Modo Escuro / Modo Claro

O suporte ao Modo Escuro está habilitado por padrão no SDK para garantir uma experiência consistente do usuário entre os temas do sistema. No entanto, se você quiser aplicar um esquema de cores personalizado, primeiro deve verificar se o dispositivo está usando atualmente o Modo Escuro ou o Modo Claro e configurar o `CafColorConfiguration` de acordo.

Use o estilo de interface do sistema para determinar o modo atual e, em seguida, ajuste a configuração de cores para corresponder à aparência desejada.

```swift
let userInterfaceStyle = UITraitCollection.current.userInterfaceStyle

let colorConfig: CafColorConfiguration

if userInterfaceStyle == .dark {
    colorConfig = CafColorConfiguration(
        primaryColor: "#FFFFFF",
        secondaryColor: "#222222",
        contentColor: "#FFFFFF",
        backgroundColor: "#000000",
        mediumColor: "#555555",
        dialogBackgroundColor: "#1C1C1E",
        dialogBorderColor: "#E5E5E7"
    )
} else {
    colorConfig = CafColorConfiguration(
        primaryColor: "#FF0000",
        secondaryColor: "#FFFFFF",
        contentColor: "#FF0000",
        backgroundColor: "#FFFFFF",
        mediumColor: "#00FF00",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"
    )
}

let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.documentDetector, .faceLiveness],
    colorConfig: colorConfig
)
```

### Configuração específica do módulo

Personalize módulos individuais usando os métodos `setDocumentDetectorConfig` e `setFaceLivenessConfig` Esses métodos permitem ajustar parâmetros essenciais, como:

* **Tempo limite de captura**: define o tempo máximo para captura manual.
* **Tempo limite da solicitação**: define o tempo máximo de espera por uma resposta do serviço.
* **Flags de depuração**: ativam ou desativam modos de depuração para identificar problemas durante o desenvolvimento.
* **Layout e outras configurações**: ajustam parâmetros visuais e operacionais específicos de cada módulo.

**Personalização visual**

Com o `CafColorConfiguration` objeto, você pode alinhar a identidade visual do fluxo de captura com o design do seu aplicativo. Isso garante que os elementos visuais (botões, fundos e indicadores) estejam consistentes com a identidade da sua marca.

#### Registro e monitoramento de logs

O callback unificado implementa diferentes níveis de log (**DEBUG, USAGE, INFO**), permitindo o monitoramento detalhado de cada etapa do fluxo. Esses logs são essenciais para integração com ferramentas de monitoramento, ajuste de desempenho e detecção de problemas em tempo real.

**Exemplo no callback:**

```swift
callback = { event in
    switch event {
    case .log(let level, let message):
        // Registrar mensagens para monitoramento detalhado do fluxo
        print("[LOG] \(level): \(message)")
    default:
        break
    }
}
```

**Exemplo de encadeamento de configuração:**

```swift
var sdkConfig = CafSDKConfiguration(
    presentationOrder: [.faceLiveness, .documentDetector],
    colorConfig: CafColorConfiguration(
        primaryColor: "#FF0000",
        secondaryColor: "#FFFFFF",
        contentColor: "#FF0000",
        backgroundColor: "#FFFFFF",
        mediumColor: "#00FF00",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"
    ),
    waitForAllServices: true, // Opcional
    enableTransitionScreens: true // Opcional
)
.setDocumentDetectorConfig(CafDocumentDetectorConfig(
    flow: [CafDocumentDetectorStep(stepType: .cnhFull)]
))
.setFaceLivenessConfig(CafFaceLivenessConfig())
```

Consulte: [DocumentDetector](#custom-settings-document-detector) e [FaceLiveness](#custom-settings-face-liveness)

\* Ao encadear essas chamadas de configuração, você pode controlar com precisão o comportamento e a aparência de cada módulo no fluxo unificado.

***

## Configurações personalizadas - Face Liveness

O módulo Face Liveness no CafSDK oferece medidas robustas para garantir que o rosto do usuário seja real e pertença a uma pessoa viva. Ele oferece suporte a vários provedores, como iProov, FaceTec2D e Fortface (PayFace), permitindo que você escolha ou combine soluções com base em seus requisitos.

Para opções detalhadas de personalização, veja: Configurações de Face Liveness.

**Para configurar o Face Liveness**

O principal objeto de configuração é `CafFaceLivenessConfig`, que inclui:

* **Configuração de instruções:** instruções e etapas personalizáveis (via `CafInstructionsConfiguration`) que orientam o usuário.
* **Indicador de carregamento:** uma flag (`loadingEnabled`) para exibir um indicador de carregamento durante o processamento.
* **URLs de endpoint (opcional):** `authBaseUrl` (HTTPS) e `livenessBaseUrl` (WSS) para comunicação com a API ao usar um proxy reverso.
* **Certificados (opcional):** uma lista de hashes Base64 codificados em SHA-256 SPKI para comunicação segura via WSS, necessária apenas ao usar um proxy reverso.
* **customLocalization (opcional):**: Este método permite especificar um nome de recurso de localização personalizado para o módulo iProov. Quando um nome é fornecido, o SDK carregará o arquivo de localização correspondente em vez do pacote de recursos padrão. Para mais detalhes sobre o formato dos arquivos de localização e a integração, consulte a [documentação de Localização do iProov](https://github.com/iProov/ios/wiki/Localization).
* **executeFaceAuth:** define se a autenticação facial será executada.
* **maxRetryAttempts:** define o número máximo de tentativas de repetição para a validação de Face Liveness. Use `-1` (padrão) para tentativas ilimitadas, `0` para nenhuma tentativa, ou qualquer `N` positivo para permitir até `N` tentativas.
* **flCustomizations (opcional):** personalizações genéricas para o fluxo de Face Liveness. Inclui suporte para textos da interface do PayFace (Fortface) e fonte via `CafFLPayFaceCustomization`.
* **payFaceDebugMode:** ativa o modo de depuração para o provedor PayFace quando `true`.

**Exemplo de configuração:**

```swift
sdkConfig.setFaceLivenessConfig(CafFaceLivenessConfig(
    instructionsConfig: CafInstructionsConfiguration(
        enabled: true,
        captureTitle: "Escaneie seu rosto",
        captureDescriptionText: "Siga estas etapas:",
        captureSteps: ["Segure o telefone com firmeza", "Garanta uma boa iluminação"],
        captureButtonTitle: "Iniciar escaneamento",
        captureHeaderImage: UIImage(named: "scan_icon")
    ),
    loadingEnabled: true,
    reverseProxyConfig: CafReverseProxyConfig(
        authBaseUrl: "https://my.proxy.io/v1/faces/",
        livenessBaseUrl: "wss://my.proxy.io/ws/",
        certificates: ["4d69f16113bed7d62ca56feb68d32a0fcb7293d3960="]
    ), // Opcional, usado apenas com proxy reverso
    customLocalization: "your-customs-strings-file-name",
    executeFaceAuth: false,
    maxRetryAttempts: -1, // Opcional, o padrão é -1 (ilimitado). Use 0 para nenhuma tentativa
    payFaceDebugMode: true, // Opcional, ativa o modo de depuração para o provedor PayFace
    // Personalização opcional do PayFace (Fortface)
    flCustomizations: [
        CafFLPayFaceCustomization(
            cameraMessageFont: "HelveticaNeue-Bold",
            startMessage: "Centralize seu rosto e fique parado",
            facePositionedMessage: "Perfeito! Mantenha seu rosto centralizado"
        )
    ]
))
```

### Como funciona

Quando `faceLivenessConfig` está definido em seu `CafSDKConfiguration`, o módulo Face Liveness será executado automaticamente quando sua posição na ordem de apresentação for alcançada. Após uma execução bem-sucedida, um `CafUnifiedEvent.Success` evento é disparado, contendo:

* `moduleName`: o identificador do módulo (por exemplo, "faceLiveness").
* `signedResponse`: Um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.

Esses resultados podem então ser processados no seu callback unificado para atualizar a interface ou prosseguir com o fluxo do aplicativo.

***

## Configurações personalizadas

**Resumo da configuração do SDK**

O SDK é configurado por meio de `CafSDKConfiguration`, que inclui configurações para:

* Personalização da interface do usuário (cores, instruções e imagens).
* Endpoints de proxy reverso e certificados de segurança (opcional).
* Parâmetros opcionais como `personId`.

**Configuração de Proxy Reverso**

### Para Face Liveness (opcional)

Use esta configuração somente se você estiver roteando solicitações de Face Liveness por meio de um proxy reverso.

**Requisitos:**

* **Protocolo:** `wss://` (WebSocket Secure).
* **Certificados:** Hashes SHA-256 codificados em Base64 do Subject Public Key Info (SPKI) do certificado.

**Configuração:**

Todas as configurações de proxy reverso para Face Liveness são definidas usando a `CafFaceLivenessConfig` estrutura.

1. **Defina a URL base**
   * Use a `livenessBaseUrl` propriedade para definir o endpoint WSS.
   * Exemplo: `"wss://my.proxy.io/ws/"`
2. **Defina os certificados**
   * Use a `certificates` propriedade para fornecer os hashes SPKI.
   * Exemplo: `["4d69f16113bed7d62ca56feb68d32a0fcb7293d3960="]`

**Exemplo de código:**

```swift
.setFaceLivenessConfig(CafFaceLivenessConfig(
    reverseProxyConfig: CafReverseProxyConfig(
        livenessBaseUrl: "wss://my.proxy.io/ws/",
        certificates: ["4d69f16113bed7d62ca56feb68d32a0fcb7293d3960=",
                   "50f71c5dda30741ee4be1ac378e12539b0d1d511f99=",
                   "9f85e26c1ae41f7ac97adc4099be7f2a40759510ab9="]
    ), // Opcional, usado apenas com proxy reverso
))
```

### Proxy reverso de autenticação (opcional)

Use esta configuração somente se você estiver roteando solicitações de autenticação por meio de um proxy reverso.

**Requisito:**

* **Protocolo:** `https://`

**Configuração:**

Todas as configurações de proxy reverso para autenticação são definidas usando a `CafFaceLivenessConfig` estrutura.

1. **Defina a URL Base**
   * Use a `authBaseUrl` propriedade para definir o endpoint HTTPS.
   * Exemplo: `"https://my.proxy.io/v1/faces/"`

**Exemplo de código:**

```swift
.setFaceLivenessConfig(CafFaceLivenessConfig(
    reverseProxyConfig: CafReverseProxyConfig(
            authBaseUrl: "https://my.proxy.io/v1/faces/",
        ), // Opcional, usado apenas com proxy reverso
))
```

***

## **Estruturas de Configuração**

### Liveness Facial Caf

Personalize a tela de instruções do Face Liveness.

| Propriedade          | Tipo                           | Descrição                                                                                                                                               | Padrão      |
| -------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| `loadingEnabled`     | `Bool`                         | Ativa/desativa a tela de carregamento.                                                                                                                  | `true`      |
| `authBaseUrl`        | `String`                       | URL HTTPS para solicitações de autenticação. Opcional. Necessário apenas para proxy reverso.                                                            | `""`        |
| `livenessBaseUrl`    | `String`                       | URL WSS para o WebSocket do FaceLiveness. Opcional. Necessário apenas para proxy reverso.                                                               | `""`        |
| `certificates`       | `[String]`                     | Hashes SPKI SHA-256 codificados em Base64. Opcional. Necessário apenas para WSS via proxy.                                                              | `[]`        |
| `instructionsConfig` | `CafInstructionsConfiguration` | Personaliza a tela de instruções (título, etapas, imagens).                                                                                             | Veja abaixo |
| `executeFaceAuth`    | Boolean                        | Define se a autenticação facial será executada.                                                                                                         |             |
| `maxRetryAttempts`   | Int                            | Define o número máximo de tentativas de repetição para a validação de liveness facial. Use `-1` (padrão) para tentativas ilimitadas e `0` para nenhuma. | -1          |
| `flCustomizations`   | `[CafFLCustomization]`         | Personalizações genéricas do Face Liveness (por exemplo, textos da interface e fonte do PayFace).                                                       | `[]`        |
| `payFaceDebugMode`   | `Bool`                         | Ativa o modo de depuração especificamente para o provedor PayFace (Fortface).                                                                           | `false`     |

### Instruções de configuração

Personalize a tela de instruções do Face Liveness.

| Propriedade              | Tipo        | Descrição                                         | Padrão |
| ------------------------ | ----------- | ------------------------------------------------- | ------ |
| `ativado`                | `Bool`      | Mostra/oculta a tela de instruções.               | `true` |
| `captureTitle`           | `String?`   | Título do cabeçalho da tela de captura.           | `nil`  |
| `captureDescriptionText` | `String?`   | Breve descrição da tela de captura.               | `nil`  |
| `captureSteps`           | `[String]?` | Lista ordenada de instruções para captura.        | `nil`  |
| `captureButtonTitle`     | `String?`   | Texto do botão de confirmação na tela de captura. | `nil`  |
| `captureHeaderImage`     | `UIImage?`  | Imagem exibida no topo da tela de captura.        | `nil`  |
| `uploadTitle`            | `String?`   | Título do cabeçalho da tela de upload.            | `nil`  |
| `uploadDescriptionText`  | `String?`   | Breve descrição da tela de upload.                | `nil`  |
| `uploadSteps`            | `[String]?` | Lista ordenada de instruções para upload.         | `nil`  |
| `uploadButtonTitle`      | `String?`   | Texto do botão de confirmação na tela de upload.  | `nil`  |
| `uploadHeaderImage`      | `UIImage?`  | Imagem exibida no topo da tela de upload.         | `nil`  |

### Configuração de cores Caf

Personalize a interface. Todos os elementos de UI dos módulos Face Liveness e Document Detector usarão estas cores.

| Propriedade             | Tipo     | Descrição                                             | Formato                                     |
| ----------------------- | -------- | ----------------------------------------------------- | ------------------------------------------- |
| `primaryColor`          | `String` | Botões principais, destaques.                         | Código hexadecimal (por exemplo, `#FF0000`) |
| `secondaryColor`        | `String` | Elementos secundários, bordas.                        | Código hexadecimal                          |
| `contentColor`          | `String` | Texto e ícones.                                       | Código hexadecimal                          |
| `backgroundColor`       | `String` | Fundo da tela.                                        | Código hexadecimal                          |
| `mediumColor`           | `String` | Elementos neutros (por exemplo, barras de progresso). | Código hexadecimal                          |
| `dialogBackgroundColor` | `String` | Cor de fundo de diálogos e pop-ups.                   | Código hexadecimal                          |
| `dialogBorderColor`     | `String` | Cor da borda de diálogos e pop-ups.                   | Código hexadecimal                          |

### Exemplo de código

#### Exemplo completo de código de configuração.

```swift
var facelivenessConfig = CafFaceLivenessConfig(
        instructionsConfig: CafInstructionsConfiguration(
            enabled: true,
            captureTitle: "Escaneie seu rosto",
            captureDescriptionText: "Siga estas etapas:",
            captureSteps: ["Segure o telefone com firmeza", "Garanta uma boa iluminação"],
            captureButtonTitle: "Iniciar escaneamento",
            captureHeaderImage: UIImage(named: "scan_icon")
        ), loadingEnabled: true,
        reverseProxyConfig: CafReverseProxyConfig(
            authBaseUrl: "https://my.proxy.io/v1/faces/",
            livenessBaseUrl: "wss://my.proxy.io/ws/",
            certificates: ["4d69f16113bed7d62ca56feb68d32a0fcb7293d3960="]
        ), // Opcional, usado apenas com proxy reverso
        executeFaceAuth: false,
        maxRetryAttempts: -1, // Opcional, o padrão é -1 (tentativas ilimitadas)
    )
```

***

## Mais informações

#### Requisitos do certificado

* Os certificados devem ser o hash SHA-256 codificado em base64 do Subject Public Key Info (SPKI) do certificado.

#### **Aplicação do protocolo**

* A URL do Face Liveness deve usar **wss\://** ao usar um proxy reverso.
* A URL de autenticação deve usar **https\://** ao usar um proxy reverso.

#### **Valores padrão**

* `loadingEnabled` é `true` por padrão.
* `instructionsConfig.enabled` é `true` por padrão.

## Resultados do SDK

### Casos de sucesso

Após a execução bem-sucedida, o `CafUnifiedEvent.success` evento conterá um array `[CafUnifiedResponse]` de respostas. Para Face Liveness:

```swift
case .success(let responses):
    if let faceResponse = responses.first(where: { $0.moduleName == "faceLiveness" }) {
        let signedResponse = faceResponse.signedResponse
        // Processar JWT
    }
```

#### Parâmetros de SignedResponse

Dentro do `signedResponse`, o parâmetro `isAlive` define a execução do liveness, onde `true` é aprovado e `false` é rejeitado.

| Evento       | Descrição                                                                              |
| ------------ | -------------------------------------------------------------------------------------- |
| `requestId`  | Identificador da solicitação.                                                          |
| `isAlive`    | Validação de uma pessoa viva, identifica se o usuário foi aprovado com sucesso ou não. |
| `token`      | Token da solicitação.                                                                  |
| `userId`     | Identificador do usuário fornecido para a solicitação.                                 |
| `imageUrl`   | Link temporário para a imagem, gerado pela nossa API.                                  |
| `personId`   | Identificador do usuário fornecido para o SDK.                                         |
| `sdkVersion` | Versão do SDK em uso.                                                                  |
| `iat`        | Expiração do token.                                                                    |

{% hint style="warning" %}
A **isAlive** o parâmetro é **MUITO IMPORTANTE**, pois ele determina se o processo de validação prossegue ou é interrompido. Quando `isAlive: true`, o usuário tem permissão para continuar sua jornada; por outro lado, se `isAlive: false`, o usuário é considerado inválido e o acesso às próximas etapas da jornada deve ser negado. Este parâmetro desempenha um papel fundamental na condução do fluxo das operações.
{% endhint %}

### Casos de erro

Consulte [Detalhamento dos tipos de erro](#error-types-breakdown)

#### Tipos de falha

O módulo Face Liveness fornece motivos detalhados de falha por meio do `CafUnifiedEvent.failure` caso. Esses tipos de falha ajudam a identificar problemas específicos durante a validação facial.

```swift
public enum CafFailureType: String, Encodable, CaseIterable {
    case unknown = "unknown"
    case tooMuchMovement = "too_much_movement"
    case tooBright = "too_bright"
    case tooDark = "too_dark"
    case misalignedFace = "misaligned_face"
    case eyesClosed = "eyes_closed"
    case faceTooFar = "face_too_far"
    case faceTooClose = "face_too_close"
    case sunglasses = "sunglasses"
    case eyewear = "eyewear"
    case obscuredFace = "obscured_face"
    case multipleFaces = "multiple_faces"
    case faceNotFound = "face_not_found"
    case framesBlurry = "frames_blurry"
    case lightingIssues = "lighting_issues"
    case motionIssue = "motion_issue"
    case backgroundIssue = "background_issue"
    case deviceIssue = "device_issue"
    case deviceRestart = "device_restart"
    case systemError = "system_error"
    case rejected = "rejected"
    case timeout = "timeout"
    case userNotFound = "user_not_found"
    case processingFault = "processing_fault"
}
```

Todos os motivos de falha são retornados exclusivamente em fluxos de validação de liveness GPA. Em fluxos LA (Liveness Assurance), qualquer falha retornará consistentemente o genérico `desconhecido` erro.

| FailureType       | Descrição                                                                                           | GPA | LA |
| ----------------- | --------------------------------------------------------------------------------------------------- | --- | -- |
| `desconhecido`    | Tente novamente                                                                                     | ✅   | ❌  |
| `tooMuchMovement` | Fique parado                                                                                        | ✅   | ❌  |
| `tooBright`       | Vá para um lugar mais escuro                                                                        | ✅   | ❌  |
| `tooDark`         | Vá para um lugar mais claro                                                                         | ✅   | ❌  |
| `misalignedFace`  | Mantenha seu rosto dentro do oval                                                                   | ✅   | ❌  |
| `faceTooFar`      | Aproxime seu rosto da tela                                                                          | ✅   | ❌  |
| `faceTooClose`    | Afaste seu rosto da tela                                                                            | ✅   | ❌  |
| `sunglasses`      | Remova os óculos de sol                                                                             | ✅   | ❌  |
| `systemError`     | Erro do sistema                                                                                     | ⚠️  | ✅  |
| `rejected`        | A transação não pôde ser concluída                                                                  | ⚠️  | ✅  |
| `faceNotFound`    | Posicione seu rosto no oval e tente ficar parado                                                    | ⚠️  | ✅  |
| `obscuredFace`    | Certifique-se de que todo o seu rosto esteja visível e remova qualquer acessório que possa cobri-lo | ✅   | ✅  |
| `timeout`         | Tempo limite do sistema                                                                             | ⚠️  | ✅  |
| `óculos`          | Remova seus óculos                                                                                  | ⚠️  | ✅  |
| `multipleFaces`   | Certifique-se de que apenas uma pessoa esteja visível                                               | ✅   | ✅  |
| `eyesClosed`      | Certifique-se de que seus olhos estejam abertos                                                     | ✅   | ✅  |
| `userNotFound`    | A transação não pôde ser concluída                                                                  | ⚠️  | ✅  |
| `lightingIssues`  | Certifique-se de que seu rosto esteja bem iluminado e sem reflexos                                  | ⚠️  | ✅  |
| `framesBlurry`    | Posicione seu rosto no oval e tente ficar parado                                                    | ⚠️  | ✅  |
| `deviceIssue`     | Tente um dispositivo diferente                                                                      | ⚠️  | ✅  |
| `motionIssue`     | Posicione seu rosto no oval e tente ficar parado                                                    | ⚠️  | ✅  |
| `backgroundIssue` | Vá para outro local com um fundo neutro                                                             | ⚠️  | ✅  |
| `deviceRestart`   | Reinicie seu dispositivo e tente novamente                                                          | ⚠️  | ✅  |
| `processingFault` | Tente novamente                                                                                     | ⚠️  | ✅  |

Legenda: ✅ = será retornado, ❌ = não será retornado, ⚠️ = pode ser retornado no futuro

***

## **Configurações personalizadas - Document Detector**

A **DocumentDetector** o módulo usa machine learning (via TensorFlow Lite) para detectar e validar documentos com segurança. Este módulo é altamente configurável, permitindo definir fluxos de documentos personalizados, telas de pré-visualização e configurações de captura manual.

### Configuração do Document Detector

O objeto principal de configuração para este módulo é o **CafDocumentDetectorConfig**, que oferece opções como:

* **Fluxo:** Uma matriz de `CafDocumentDetectorStep` objetos para determinar a ordem e o tipo das capturas de documentos.
* **Personalização do layout:** Defina a aparência da interface de captura usando a classe `DocumentDetectorLayout` As cores são herdadas principalmente da configuração global `CafColorConfiguration`.
* **Configurações de upload:** Controle o formato do arquivo, a compactação e o tamanho máximo do arquivo com `CafUploadSettings`.
* **Opções de captura manual:** Ative a captura manual, ajuste o tempo limite.
* **Personalização de strings e ativos da interface:** Use `ddCustomizations` para fornecer textos e imagens personalizados para telas específicas, como o pop-up de upload e a tela de pré-visualização.
* **Configurações de proxy e tempo limite:** Configure um proxy e ajuste o tempo limite da rede para uploads seguros de documentos (opcional).

#### Exemplo de código:

```swift
let documentConfig = CafDocumentDetectorConfig(
    flow: [/* Matriz de itens CafDocumentDetectorStep */], // Obrigatório
    layout: CafDocumentDetectorLayout(),
    uploadSettings: CafUploadSettings(enable: true),
    manualCaptureEnabled: true,
    manualCaptureTime: 45,
    requestTimeout: 60,
    showPopup: true,
    ddCustomizations: [
        CafPreviewCustomization(
            title: "A foto está nítida?",
            message: "Certifique-se de que todas as informações estejam legíveis.",
            okButton: "Sim, está boa!",
            tryAgainButton: "Tirar novamente"
        )
    ]
)
```

## Documentos disponíveis e personalização

**CafSDK** fornece um conjunto de documentos pré-configurados (por exemplo, `rgFront`, `cnhFront`, `passaporte`, etc.). Você pode personalizar esses documentos ou criar seus próprios fluxos ajustando as propriedades de cada `CafDocumentDetectorStep` e `CafDocument`.

### Como funciona

Quando `documentConfig` está definido em seu `CafSDKConfiguration`, o **Document Detector** módulo é executado automaticamente quando atinge sua posição designada no fluxo.

Após uma execução bem-sucedida, um `CafUnifiedEvent.Success` evento é disparado, contendo:

* **moduleName:** O identificador do módulo (por exemplo, `"documentDetector"`).
* **signedResponse:** Um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.

Esses resultados são então processados na sua resposta unificada da chamada, permitindo que você prossiga com o fluxo ou armazene as informações capturadas conforme necessário.

#### Exemplo de código:

```swift
sdkConfig.setDocumentDetectorConfig(CafDocumentDetectorConfig(
    flow: [CafDocumentDetectorStep(stepType: .rgFront)],
    manualCaptureEnabled: true,
    manualCaptureTime: 45,
    requestTimeout: 60,
    showPopup: true
))
```

Após a captura e o processamento do documento serem concluídos, o **Document Detector** módulo aciona um `CafUnifiedEvent.Success` evento, que inclui:

* **moduleName:** O identificador do módulo (por exemplo, `"documentDetector"`).
* **result:** Os dados do documento capturado.

***

## Configurações personalizadas - Document Detector

Para configurar o Caf Document Detector, use a `CafDocumentDetectorConfig` estrutura, que inclui:

* Etapas do fluxo de captura de documentos.
* Personalização do layout da interface do usuário (UI).
* Personalizações de strings e ativos da UI para telas específicas.
* Comportamento de upload.
* Configurações de proxy.

### Configuração principal

Propriedades de `CafDocumentDetectorConfig` .

| Propriedade                  | Tipo                           | Descrição                                                                                                                                                   | Padrão         |
| ---------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `flow`                       | `[CafDocumentDetectorStep]`    | Lista ordenada de etapas de captura de documentos.                                                                                                          | `[]`           |
| `layout`                     | `CafDocumentDetectorLayout`    | Personalização da UI (botões, fontes, sobreposições de feedback). As cores são tematizadas principalmente pela configuração global `CafColorConfiguration`. | Layout padrão  |
| `instructionsConfig`         | `CafInstructionsConfiguration` | Personaliza a tela de instruções (título, etapas, imagens).                                                                                                 | Veja abaixo    |
| `uploadSettings`             | `CafUploadSettings`            | Controla o comportamento de upload de documentos.                                                                                                           | `enable: true` |
| `manualCaptureEnabled`       | `Bool`                         | Ativa o botão de captura manual.                                                                                                                            | `true`         |
| `manualCaptureTime`          | `TimeInterval`                 | Tempo limite (segundos) para captura manual. Use `0` para desativar o temporizador de contagem regressiva.                                                  | `0`            |
| `requestTimeout`             | `TimeInterval`                 | Tempo limite da solicitação HTTP.                                                                                                                           | `60`           |
| `showPopup`                  | `Bool`                         | Mostra/oculta o pop-up inicial de instruções.                                                                                                               | `true`         |
| `proxySettings`              | `CafProxySettings?`            | Configuração de proxy reverso (host, porta, autenticação).                                                                                                  | `nil`          |
| `previewShow`                | `Bool`                         | Ativa a tela de pré-visualização após a captura.                                                                                                            | `false`        |
| `ddCustomizations`           | `[CafDDCustomization]?`        | Matriz de personalizações de strings e ativos da UI para telas do Document Detector (por exemplo, pop-up de upload, tela de pré-visualização).              | `nil`          |
| `enableMultiLanguage`        | `Bool`                         | Ativa a tradução automática das mensagens padrão.                                                                                                           | `true`         |
| `allowedPassportCountryList` | `[CafCountryCodes]?`           | Lista de permissões de países permitidos para passaporte (por exemplo, `.BR`, `.US`).                                                                       | `nil`          |
| `selectDocumentConfig`       | `CafSelectDocumentConfig?`     | Configura a tela de seleção de documentos (título/descrição) e os títulos/descrições por documento por meio de `customTitles`/`customDescriptions`          | `nil`          |
| `currentStepDoneDelay`       | `TimeInterval`                 | Atraso (em segundos) antes de prosseguir após concluir uma etapa de captura                                                                                 | `1.0`          |
| `maxRetryAttempts`           | `Int`                          | Número máximo de tentativas de repetição no fluxo de erro do servidor do DocumentCapture.                                                                   | `2`            |

### Personalização da tela de seleção de documento (`CafSelectDocumentConfig`)

Use `CafSelectDocumentConfig` para personalizar a tela de seleção de documentos. Você pode definir um título/descrição da tela e, opcionalmente, substituir os rótulos localizados padrão por tipo de documento.

| Propriedade          | Tipo                            | Descrição                                               |
| -------------------- | ------------------------------- | ------------------------------------------------------- |
| `screenTitle`        | `String?`                       | Título exibido no topo da tela de seleção.              |
| `description`        | `String?`                       | Subtítulo/descrição abaixo do título.                   |
| `customTitles`       | `[CafDocumentTypeKey: String]?` | Substitui o título padrão de cada tipo de documento.    |
| `customDescriptions` | `[CafDocumentTypeKey: String]?` | Substitui a descrição padrão de cada tipo de documento. |

**Sufixo lateral automático para documentos frente e verso**

Quando você fornece `customTitles` e o fluxo inclui etapas de frente/verso para um tipo de documento, o SDK adiciona automaticamente um sufixo lateral localizado aos rótulos das etapas no fluxo após a seleção. Documentos de etapa única que representam um documento aberto (por exemplo, `.rgFull` ou `.cnhFull`) recebem um sufixo "Aberto", enquanto outros documentos de etapa única (por exemplo, `passaporte`) não recebem sufixo.

Exemplo (frente e verso: RG):

```swift
let titles: [CafDocumentTypeKey: String] = [.rg: "RG (Título Base Personalizado)"]

var ddConfig = CafDocumentDetectorConfig(
    flow: [
        CafDocumentDetectorStep(stepType: .rgFront),
        CafDocumentDetectorStep(stepType: .rgBack)
    ],
    selectDocumentConfig: CafSelectDocumentConfig(
        customTitles: titles
    )
)

// Rótulos resultantes das etapas (localizados):
// "RG (Título Base Personalizado) - Frente"
// "RG (Título Base Personalizado) - Verso"
```

Exemplo (etapa única: Passaporte; sem sufixo):

```swift
let titles: [CafDocumentTypeKey: String] = [.passport: "Passaporte (Título Base Personalizado)"]

var ddConfig = CafDocumentDetectorConfig(
    flow: [CafDocumentDetectorStep(stepType: .passport)],
    selectDocumentConfig: CafSelectDocumentConfig(customTitles: titles)
)

// Rótulo resultante da etapa:
// "Passaporte (Título Base Personalizado)"
```

#### Exemplo de código

```swift
let titles: [CafDocumentTypeKey: String] = [
    .rg: "RG (Título Personalizado)",
    .cnh: "CNH (Título Personalizado)",
    .passport: "Passaporte (Título Personalizado)"
]

let descriptions: [CafDocumentTypeKey: String] = [
    .rgDigital: "RG Digital (Descrição Personalizada)",
    .any: "Outro (Descrição Personalizada)"
]

var ddConfig = CafDocumentDetectorConfig(
    flow: [
        CafDocumentDetectorStep(stepType: .rgFront),
        CafDocumentDetectorStep(stepType: .rgBack)
    ],
    selectDocumentConfig: CafSelectDocumentConfig(
        screenTitle: "Escolha um documento",
        description: "Selecione qual documento você deseja usar.",
        customTitles: titles,
        customDescriptions: descriptions
    )
)

sdkConfig.setDocumentDetectorConfig(ddConfig)
```

#### Chaves de tipo de documento (`CafDocumentTypeKey`)

Use estas chaves ao personalizar os rótulos:

* `rg`
* `rgDigital`
* `cnh`
* `cnhDigital`
* `crlv`
* `rne`
* `ctps`
* `passaporte`
* `any`

### Configuração da tela de instruções

O Document Detector também oferece suporte a uma tela de instruções usando `instructionsConfig: CafInstructionsConfiguration`, semelhante ao Face Liveness.

| Propriedade          | Tipo                           | Descrição                                                     | Padrão |
| -------------------- | ------------------------------ | ------------------------------------------------------------- | ------ |
| `instructionsConfig` | `CafInstructionsConfiguration` | Conteúdo da tela de instruções (veja as propriedades abaixo). |        |

`CafInstructionsConfiguration`:

| Propriedade              | Tipo        | Descrição                                         | Padrão |
| ------------------------ | ----------- | ------------------------------------------------- | ------ |
| `ativado`                | `Bool`      | Mostra/oculta a tela de instruções.               | `true` |
| `captureTitle`           | `String?`   | Título do cabeçalho da tela de captura.           | `nil`  |
| `captureDescriptionText` | `String?`   | Breve descrição da tela de captura.               | `nil`  |
| `captureSteps`           | `[String]?` | Lista ordenada de instruções para captura.        | `nil`  |
| `captureButtonTitle`     | `String?`   | Texto do botão de confirmação na tela de captura. | `nil`  |
| `captureHeaderImage`     | `UIImage?`  | Imagem exibida no topo da tela de captura.        | `nil`  |
| `uploadTitle`            | `String?`   | Título do cabeçalho da tela de upload.            | `nil`  |
| `uploadDescriptionText`  | `String?`   | Breve descrição da tela de upload.                | `nil`  |
| `uploadSteps`            | `[String]?` | Lista ordenada de instruções para upload.         | `nil`  |
| `uploadButtonTitle`      | `String?`   | Texto do botão de confirmação na tela de upload.  | `nil`  |
| `uploadHeaderImage`      | `UIImage?`  | Imagem exibida no topo da tela de upload.         | `nil`  |

Exemplo:

```swift
let ddConfig = CafDocumentDetectorConfig(
    flow: [
        CafDocumentDetectorStep(stepType: .rgFront),
        CafDocumentDetectorStep(stepType: .rgBack)
    ],
    instructionsConfig: CafInstructionsConfiguration(
        enabled: true,
        captureTitle: "Escaneie seu documento",
        captureDescriptionText: "Siga as etapas abaixo",
        captureSteps: ["Coloque o documento no enquadramento", "Evite reflexos"],
        captureButtonTitle: "Iniciar",
        captureHeaderImage: UIImage(named: "doc_instructions")
    )
)
```

### Personalização do layout

Propriedades de `CafDocumentDetectorLayout`. As cores desses elementos são influenciadas principalmente pela configuração global `CafColorConfiguration` definida em `CafSDKConfiguration`.

| Propriedade              | Tipo                        | Descrição                                                   | Padrão                |
| ------------------------ | --------------------------- | ----------------------------------------------------------- | --------------------- |
| `closeButtonImage`       | `UIImage?`                  | Imagem para o botão de fechar.                              | Padrão do sistema     |
| `closeButtonColor`       | `UIColor?`                  | Cor do botão de fechar.                                     | Global `primaryColor` |
| `closeButtonSize`        | `CGFloat?`                  | Tamanho (largura/altura) do botão de fechar.                | `44`                  |
| `closeButtonContentMode` | `UIView.ContentMode?`       | Modo de conteúdo da imagem do botão de fechar.              | `.scaleAspectFit`     |
| `feedbackColors`         | `CafDocumentFeedbackColors` | Cores para sobreposições de feedback (padrão/erro/sucesso). | Cores predefinidas    |
| `font`                   | `String?`                   | Nome da fonte personalizada (por exemplo, "Avenir-Bold").   | Fonte do sistema      |

#### Exemplo de código:

```swift
var layout = CafDocumentDetectorLayout()
layout.closeButtonImage = UIImage(named: "close_icon")
// layout.primaryColor não está mais disponível aqui; use a configuração global CafColorConfiguration
layout.font = "Helvetica-Bold"
layout.feedbackColors = CafDocumentFeedbackColors(
    defaultColor: .gray, 
    errorColor: .red, 
    successColor: .green
)
```

### Personalização de strings da interface e recursos (`CafDDCustomization`)

A `ddCustomizations` propriedade em `CafDocumentDetectorConfig` permite fornecer uma matriz de objetos que estejam em conformidade com `CafDDCustomization` para substituir textos e imagens padrão em telas específicas do Document Detector.

Se um objeto de personalização para uma tela específica não for fornecido, ou se uma propriedade específica dentro desse objeto estiver `nil`, o SDK usará suas strings e recursos localizados padrão.

#### `CafPreviewCustomization`

Personaliza a tela de pré-visualização do documento exibida após uma imagem do documento ser capturada (se `previewShow` é `true`).

| Propriedade      | Tipo      | Descrição                                                | Padrão (localizado)                                   |
| ---------------- | --------- | -------------------------------------------------------- | ----------------------------------------------------- |
| `title`          | `String?` | Texto do título na tela de pré-visualização.             | "A foto ficou boa?"                                   |
| `message`        | `String?` | Texto de subtítulo/mensagem na tela de pré-visualização. | "Verifique se todas as informações estão legíveis..." |
| `okButton`       | `String?` | Texto do botão de confirmação ("aceitar").               | "Sim, ficou boa!"                                     |
| `tryAgainButton` | `String?` | Texto do botão de tentar novamente ("tirar de novo").    | "Tirar de novo"                                       |

**Exemplo:**

```swift
let previewCustom = CafPreviewCustomization(
    title: "Confirmar qualidade da foto",
    message: "Garanta que todos os detalhes estejam nítidos e não haja reflexos.",
    okButton: "Confirmar",
    tryAgainButton: "Capturar novamente"
)
// Adicione à CafDocumentDetectorConfig:
// ddCustomizations: [previewCustom]
```

#### `CafDDUploadCustomization`

Personaliza o pop-up exibido quando o usuário escolhe enviar um arquivo de documento.

| Propriedade    | Tipo       | Descrição                                    | Padrão (localizado)      |
| -------------- | ---------- | -------------------------------------------- | ------------------------ |
| `image`        | `UIImage?` | Imagem exibida no topo do pop-up.            | Ilustração padrão do SDK |
| `title`        | `String?`  | Texto do título do pop-up de envio.          | "Enviar documento"       |
| `message`      | `String?`  | Texto da mensagem dentro do pop-up de envio. | "Selecione o arquivo..." |
| `uploadButton` | `String?`  | Texto do botão "Enviar".                     | "Enviar"                 |
| `cancelButton` | `String?`  | Texto do botão "Cancelar".                   | "Cancelar"               |

**Exemplo:**

```swift
let uploadCustom = CafDDUploadCustomization(
    title: "Selecione seu documento",
    message: "Por favor, escolha o arquivo de documento que você deseja enviar.",
    uploadButton: "Escolher arquivo",
    cancelButton: "Voltar"
)
// Adicione à CafDocumentDetectorConfig:
// ddCustomizations: [uploadCustom, previewCustom] // Pode ter várias personalizações
```

#### `CafUploadMessagesCustomization`

Personaliza as mensagens de qualidade no fluxo exibidas durante o agendamento do envio do documento.

| Propriedade           | Tipo            | Descrição                                                          | Padrão (localizado)                           |
| --------------------- | --------------- | ------------------------------------------------------------------ | --------------------------------------------- |
| `sending`             | `String?`       | Mensagem exibida quando o envio começa.                            | `"Enviando documento... Aguarde..."`          |
| `verifyingIntegrity`  | `String?`       | Mensagem exibida enquanto a integridade do documento é verificada. | `"Verificando a integridade do documento..."` |
| `processingData`      | `String?`       | Mensagem exibida enquanto os dados estão sendo processados.        | `"Processando os dados do documento..."`      |
| `almostDone`          | `String?`       | Mensagem exibida quando o envio está quase concluído.              | `"Quase lá... Finalizando o envio..."`        |
| `timeBetweenMessages` | `TimeInterval?` | Intervalo (em segundos) entre cada mensagem.                       | `15`                                          |

**Exemplo:**

```swift
let messagesCustom = CafUploadMessagesCustomization(
    sending: "Enviando documento...",
    verifyingIntegrity: "Verificando a integridade do documento...",
    processingData: "Processando os dados do documento...",
    almostDone: "Quase lá!",
    timeBetweenMessages: 20
)
// Adicione à CafDocumentDetectorConfig:
// ddCustomizations: [messagesCustom]
```

#### `CafFailedPhotoCustomization`

Personaliza a tela de falha exibida quando uma foto não consegue ser enviada.

| Propriedade      | Tipo      | Descrição                                 | Padrão |
| ---------------- | --------- | ----------------------------------------- | ------ |
| `title`          | `String?` | Texto do título exibido na tela de falha. |        |
| `description`    | `String?` | Texto de descrição explicando a falha.    |        |
| `continueButton` | `String?` | Texto do botão de tentar novamente.       |        |

**Exemplo:**

```swift
let failedPhotoCustom = CafFailedPhotoCustomization(
    title: "Foto não enviada!",
    description: "Não foi possível enviar a foto. Verifique sua conexão.",
    continueButton: "Tentar novamente"
)
// Adicione à CafDocumentDetectorConfig ou UploadValidationViewController:
// ddCustomizations: [failedPhotoCustom]
```

#### `CafMessageCustomization`

Personaliza várias mensagens no fluxo exibidas durante o processo de captura do documento (por exemplo, mensagens do sensor, feedback de IA).

| Propriedade                      | Descrição                                                       | Padrão (localizado)                |
| -------------------------------- | --------------------------------------------------------------- | ---------------------------------- |
| `waitMessage`                    | Exibida durante a inicialização do SDK.                         | "Aguarde"                          |
| `holdDocumentMessage`            | Exibida ao pedir ao usuário que mantenha o documento estável.   | "Segure o documento"               |
| `fitTheDocumentMessage`          | Recomenda alinhar o documento à máscara.                        | "Encaixe o documento na marcação"  |
| `verifyingQualityMessage`        | Exibida durante a verificação de qualidade.                     | "Verificando a qualidade…"         |
| `lowQualityDocumentMessage`      | Exibida em caso de falha na captura devido à qualidade.         | "Ops, tente novamente"             |
| `uploadingImageMessage`          | Exibida durante o envio da imagem.                              | "Enviando imagem..."               |
| `sensorLuminosityMessage`        | Aviso de pouca luminosidade.                                    | "Ambiente muito escuro"            |
| `manualCaptureMessage`           | Texto do botão de captura manual.                               | "Captura manual"                   |
| `sensorOrientationMessage`       | Aviso de orientação do dispositivo.                             | "O celular não está na horizontal" |
| `sensorStabilityMessage`         | Aviso de estabilidade do dispositivo.                           | "Mantenha o celular estável"       |
| `popupDocumentSubtitleMessage`   | Subtítulo do pop-up inicial de instrução.                       | Subtítulo padrão da instrução      |
| `passportCountryNotValidMessage` | Exibida se o país selecionado para o passaporte não for válido. | "O país selecionado não é válido"  |
| `passportCountryLoadingMessage`  | Exibida enquanto os dados do país do passaporte são carregados. | "Carregando países..."             |
| `aiScanDocumentMessage`          | Instrução para escanear um documento (IA).                      | "Escaneie um documento"            |
| `aiGetCloserMessage`             | Instrução para se aproximar (IA).                               | "Aproxime-se do documento"         |
| `aiCentralizeMessage`            | Instrução para centralizar o documento (IA).                    | "Centralize o documento"           |
| `aiMoveAwayMessage`              | Instrução para se afastar (IA).                                 | "Afaste-se do documento"           |
| `aiAlignDocumentMessage`         | Instrução para alinhar o documento (IA).                        | "Alinhe o documento"               |
| `aiTurnDocumentMessage`          | Instrução para virar/girar o documento (IA).                    | "Vire o documento"                 |
| `aiCapturedMessage`              | Confirmação de captura bem-sucedida (IA).                       | "Capturando o documento"           |

**Exemplo:**

```swift
let messageCustom = CafMessageCustomization(
    waitMessage: "Por favor, aguarde...",
    fitTheDocumentMessage: "Alinhe seu documento dentro do enquadramento."
)
// Adicione à CafDocumentDetectorConfig:
// ddCustomizations: [messageCustom, previewCustom, uploadCustom]
```

## Fluxo de captura de documento

Propriedades de `CafDocumentDetectorStep`.

| Propriedade           | Tipo                  | Descrição                                                                 | Obrigatório | Padrão                         |
| --------------------- | --------------------- | ------------------------------------------------------------------------- | ----------- | ------------------------------ |
| `stepType`            | `CafDocumentStepType` | Tipo de documento a ser capturado (por exemplo, `.rgFront`).              | Sim         |                                |
| `customStepLabel`     | `String?`             | Texto exibido na parte inferior da tela para esta etapa.                  | Não         | Rótulo padrão do documento     |
| `customIllustration`  | `UIImage?`            | Imagem exibida no pop-up de instrução desta etapa.                        | Não         | Ilustração padrão do documento |
| `showStepLabel`       | `Bool`                | Alterna a visibilidade do rótulo da etapa.                                | Não         | `true`                         |
| `customMessage`       | `String?`             | Texto de mensagem personalizado para o pop-up de instrução desta etapa.   | Não         | Mensagem padrão do documento   |
| `customOkButtonTitle` | `String?`             | Texto personalizado para o botão 'OK' no pop-up de instrução desta etapa. | Não         | "OK" (localizado)              |

#### Exemplo de código:

```swift
    let step = CafDocumentDetectorStep(
        stepType: .rgFront,
        customStepLabel: "Frente do ID",
        customIllustration: UIImage(named: "id_front_icon"),
        customMessage: "Por favor, coloque a frente do seu documento de identidade no enquadramento.",
        customOkButtonTitle: "Entendi!"
    )
```

## Personalização do envio

Propriedades de `CafUploadSettings`.

| Propriedade       | Tipo           | Descrição                                      | Padrão            |
| ----------------- | -------------- | ---------------------------------------------- | ----------------- |
| `enable`          | `Bool`         | Ativa a funcionalidade de envio de documentos. | `true`            |
| `compress`        | `Bool`         | Compacta os arquivos antes do envio.           | `true`            |
| `fileFormats`     | `[FileFormat]` | Formatos permitidos: `.png`, `.jpeg`, `.pdf`.  | Todos os formatos |
| `maximumFileSize` | `Int`          | Tamanho máximo do arquivo em KB.               | `10000` (10MB)    |

#### Exemplo de código:

```swift
let uploadSettings = CafUploadSettings(
    enable: true,
    fileFormats: [.jpeg, .pdf],
    maximumFileSize: 5000
)
```

## Personalizações de proxy

Propriedades de `CafProxySettings`.

| Propriedade | Tipo      | Descrição                         | Obrigatório |
| ----------- | --------- | --------------------------------- | ----------- |
| `hostname`  | `String`  | Host do proxy (ex.: "proxy.com"). | Sim         |
| `porta`     | `Int`     | Porta do proxy (ex.: `8080`).     | Sim         |
| `usuário`   | `String?` | Nome de usuário de autenticação.  | Não         |
| `senha`     | `String?` | Senha de autenticação.            | Não         |

#### Exemplo de código:

```swift
let proxy = CafProxySettings(hostname: "my.proxy.io", port: 443)
```

## Documentos compatíveis no Document Detector

Use estes valores estáticos de `CafDocumentStepType` (que internamente mapeiam para `CafDocument`):

| Tipo de documento | Descrição                                        |
| ----------------- | ------------------------------------------------ |
| `.rgFront`        | Frente do RG brasileiro                          |
| `.rgBack`         | Verso do RG brasileiro                           |
| `.rgFull`         | RG brasileiro (aberto, mostrando frente e verso) |
| `.cnhFront`       | Frente da CNH brasileira                         |
| `.cnhBack`        | Verso da CNH brasileira                          |
| `.cnhFull`        | CNH brasileira (aberta)                          |
| `.crlv`           | CRLV brasileiro                                  |
| `.rneFront`       | Frente do RNE brasileiro                         |
| `.rneBack`        | Verso do RNE brasileiro                          |
| `.ctpsFront`      | Frente da Carteira de Trabalho brasileira (CTPS) |
| `.ctpsBack`       | Verso da Carteira de Trabalho brasileira (CTPS)  |
| `.passport`       | Passaporte (qualquer país)                       |
| `.any`            | Documento genérico (sem validação específica)    |

**Observação:** Todos os casos do enum estão em camelCase (por exemplo, use `.rgFront` em vez de `.RG_FRONT`)

#### Exemplo de código:

```swift
var layout = CafDocumentDetectorLayout()
// A cor primária é definida globalmente via CafColorConfiguration
layout.closeButtonImage = UIImage(named: "close")

let previewCustomization = CafPreviewCustomization(title: "Verificar foto", okButton: "Parece bom")
let uploadCustomization = CafDDUploadCustomization(uploadButton: "Selecionar arquivo")
let messageCustomization = CafMessageCustomization(waitMessage: "Por favor, aguarde...")

let config = CafDocumentDetectorConfig(
    flow: [
        CafDocumentDetectorStep(stepType: .rgFront, customMessage: "Coloque a frente do seu RG aqui."),
        CafDocumentDetectorStep(stepType: .rgBack)
    ],
    layout: layout,
    uploadSettings: CafUploadSettings(enable: true),
    proxySettings: CafProxySettings(hostname: "proxy.example.com", port: 8443),
    ddCustomizations: [previewCustomization, uploadCustomization, messageCustomization]
)
```

## Suporte técnico e dicas de uso

Para mais detalhes e cenários de uso avançado, consulte os seguintes recursos:

* **Repositório no GitHub:** acesse o código-fonte, o acompanhamento de issues e as notas de lançamento no [repositório GitHub do CafSDK](https://github.com/combateafraude/caf-ios-sdk).
* **Perguntas frequentes e solução de problemas**: confira nossa seção de FAQ para problemas comuns e dicas de solução de problemas.
* **Suporte**: para assistência adicional, entre em contato com nossa equipe de suporte ou participe do fórum da comunidade de desenvolvedores.

Atualizamos continuamente a documentação à medida que novos recursos e melhorias são lançados. Fique por dentro das próximas atualizações!

***

## Notas de lançamento

## CafSDK iOS v6.4.2

### Melhorias em analytics

* **Melhoria na qualidade do payload:** As análises agora incluem metadados mais ricos e mais padronizados em todos os fluxos de captura.

### Melhorias de segurança

* **`securityEnabled` flag em `CafSDKConfiguration`:** Adicionado um novo `securityEnabled: Bool = false` propriedade a `CafSDKConfiguration`, permitindo que a aplicação de segurança seja alternada programaticamente. Quando definido como `true`, o SDK executa validação de segurança rigorosa durante a inicialização e a execução; se uma violação de segurança for detectada, o SDK lança um `securityException` e encerra o fluxo.

  **Exemplo de código:**

  ```swift
  let sdkConfig = CafSDKConfiguration(
      presentationOrder: [.faceLiveness, .documentDetector],
      securityEnabled: true
  )
  ```
* **`CAFEnforceSecurity` removido:** A `CAFEnforceSecurity` `Info.plist` flag não é mais lida pelo SDK. A aplicação de segurança agora é controlada exclusivamente pelo novo `securityEnabled` propriedade em `CafSDKConfiguration`. As integrações existentes que dependem da flag no Info.plist precisam migrar para definir `securityEnabled` programaticamente.

### Correções de bugs

* **Document Detector — fluxo RG:** Corrigidos problemas que afetavam o fluxo de captura do documento RG em `DocumentDetector`.

## CafSDK iOS v6.3.0

### Atualizações de arquitetura

* **Remoção da dependência KMP/CafSolutions:** A pilha do provedor de liveness não depende mais de `CafSolutions`.

### Melhorias em analytics

* **Melhoria na qualidade do payload:** As análises agora incluem metadados mais ricos e mais padronizados.

## CafSDK iOS v6.2.0

{% hint style="warning" %}
Versões anteriores à 6.2.0 farão com que o iProov Liveness deixe de funcionar a partir de 12 de março de 2026. Para garantir o funcionamento adequado e a continuidade do serviço, use a versão 6.2.0 ou posterior.
{% endhint %}

### Mudanças incompatíveis

* **Versão mínima do iOS atualizada:** O SDK agora requer **iOS 15.0+**.

### Atualizações

* **Atualização de dependência:** Dependência do iProov atualizada para **13.1.0**.
* **Novas opções de falha:** Adicionados novos casos de falha a `CafFailureType` para um tratamento de falhas melhor:
  * `óculos`
  * `faceNotFound`
  * `framesBlurry`
  * `lightingIssues`
  * `motionIssue`
  * `backgroundIssue`
  * `deviceIssue`
  * `deviceRestart`
  * `systemError`
  * `rejected`
  * `timeout`
  * `userNotFound`
  * `processingFault`

### Aviso importante

* **Aviso de descontinuação do reverse proxy:** O suporte a reverse proxy será descontinuado em uma versão futura. Uma atualização necessária relacionada ao iProov é exigida para manter o iProov funcionando corretamente e evitar problemas de certificado. **Após 15 de março de 2026, os serviços Faceliveness e Faceauth poderão ficar indisponíveis.**

## CafSDK iOS v6.1.0

### Novos recursos

* **Integração avançada de analytics:** Implementação de analytics atualizada.

## CafSDK iOS v6.0.0

### Mudanças incompatíveis

* **`CafInstructionsConfiguration` renomeação de propriedades:** As propriedades a seguir foram renomeadas para oferecer suporte às telas de instrução de captura e upload:
  * `title` → `captureTitle`
  * `descriptionText` → `captureDescriptionText`
  * `steps` → `captureSteps`
  * `buttonTitle` → `captureButtonTitle`
  * `headerImage` → `captureHeaderImage`
  * Novas propriedades adicionadas: `uploadTitle`, `uploadDescriptionText`, `uploadSteps`, `uploadButtonTitle`, `uploadHeaderImage`

### Melhorias de segurança

* **Proteção em tempo de execução:** Implementamos verificações abrangentes para instrumentação dinâmica e melhorias de segurança.
* **Novo tipo de erro:** Adicionado `securityException` a `CafErrorType`. O SDK agora encerrará imediatamente o fluxo e retornará esse erro se uma violação de segurança for detectada durante a inicialização ou execução.

## CafSDK iOS v5.7.0

### Novos recursos

* **Pré-carregamento de sessão para Face Liveness:**
  * `CafSDKProvider` agora expõe `loadSession()` para pré-carregar a sessão do Face Liveness antes de chamar `start()`.
  * Enquanto um pré-carregamento está em execução, o callback unificado emite `.loading` e `.loaded` eventos, permitindo que você atualize a UI de acordo.

### Document Detector

* **Melhorias em analytics:**
  * Novos campos de analytics foram adicionados para entender melhor o comportamento de captura de documentos.
* **Validação de fluxo e tratamento de erros:**
  * Se `CafDocumentDetectorConfig.flow` estiver vazio, o SDK agora falha rapidamente com um `libraryException` em vez de iniciar o fluxo de captura.
  * A validação de attestation e token agora distingue entre erros de rede, tokens inválidos e respostas inválidas.

### Mudanças de comportamento

* **Padrões de captura manual:**
  * `manualCaptureTime` em `CafDocumentDetectorConfig` agora usa como padrão `0` segundos (sem contagem regressiva). A captura manual ainda pode ser configurada explicitamente via `manualCaptureEnabled` e `manualCaptureTime`.

## CafSDK iOS v5.6.2

### Novos recursos

* **Tratamento de erros de autenticação facial:** Adicionado um novo `faceAuthentication` caso a `CafErrorType` para lidar especificamente com erros de backend quando `executeFaceAuth` estiver ativado.

### Atualizações

* **Analytics:** Validação de analytics melhorada.

## CafSDK iOS v5.5.1

### Correções de bugs

* **CafFaceliveness:** Correção do fluxo de tentar novamente do CafFaceliveness.

### Atualizações

* Redução do Fingerprint `2.7.0` > `2.6.0` devido a problemas de compatibilidade, será atualizada em versões futuras.

## CafSDK iOS v5.5.0

### Novos recursos

* **Integração do provedor PayFace (Fortface):** Provedor opcional de Face Liveness agora disponível.
  * produto SPM: `FortfaceProvider`
  * subspec do CocoaPods: `CafSDKiOS/FortfaceProvider`
* **Personalizações genéricas do Face Liveness:** Novo `flCustomizations` propriedade em `CafFaceLivenessConfig` com `CafFLPayFaceCustomization` para personalizar os textos e a fonte da UI do PayFace.
* **Sufixo de lado do documento para títulos personalizados**: Ao usar `customTitles` em `CafSelectDocumentConfig`, o SDK agora adiciona automaticamente um sufixo localizado (por exemplo, "Frente"/"Verso") para documentos que têm dois lados.

### Atualizações

* Os exemplos de início rápido foram atualizados para incluir o provedor Fortface opcional e `flCustomizations` uso.

## CafSDK iOS v5.4.4

### Novos recursos

* Personalização dos rótulos de seleção de documento: agora você pode substituir os títulos e descrições por documento na tela de seleção de documento por meio de `CafSelectDocumentConfig.customTitles` e `customDescriptions` usando `CafDocumentTypeKey` chaves. Isso afeta tanto a lista de seleção quanto os rótulos das etapas aplicados após a seleção.

## CafSDK iOS v5.4.3

### Melhorias

* Mensagens de erro e falha normalizadas: os callbacks agora exibem descrições mais limpas e legíveis, extraindo mensagens aninhadas dos payloads JSON quando disponíveis
* A apresentação da tela de falha agora é em tela cheia para consistência

## CafSDK iOS v5.4.2

### Correções de bugs

* Confiabilidade da conclusão quando nenhum modal é apresentado: os provedores agora garantem callbacks mesmo quando as telas de instrução/transição estão desativadas e nenhum view controller é apresentado
* Lógica de dismiss mais segura tanto no Face Liveness quanto nos provedores do Document Detector para evitar callbacks perdidos ou UI travada em casos extremos

## CafSDK iOS v5.4.1

### Melhorias

* Validação do upload de documentos: feedback mais claro para arquivos PDF, incluindo mensagens explícitas quando um arquivo está criptografado, bloqueado ou ilegível
* Comportamento de cancelamento mais consistente durante o upload de documentos

### Correções

* Confiabilidade da conclusão do fluxo quando as telas de transição estão desativadas: as sessões agora são finalizadas corretamente e os callbacks são entregues tanto no modo em lote quanto no modo sem lote
* A seleção de documentos agora preserva a ordem de documentos configurada ao confirmar seleções múltiplas

## CafSDK iOS v5.4.0

### Novos recursos

* **Controle aprimorado da tela de transição:** Adicionado `enableTransitionScreens` parâmetro a `CafSDKConfiguration` para controlar se as telas de transição são exibidas entre os módulos
  * Quando definido como `true` (padrão), as telas de confirmação são exibidas entre os módulos
  * Quando definido como `false`, os módulos são executados sequencialmente sem telas intermediárias para uma experiência mais fluida
* **Tratamento de erros aprimorado:** Gerenciamento e padronização de erros aprimorados em todos os módulos
  * Melhor categorização de erros com tipos de erro padronizados
  * Analytics aprimorados para rastreamento e depuração de erros
* **Integração avançada de analytics:** Sistema de analytics atualizado com recursos abrangentes de rastreamento
  * Analytics de erro aprimorados com parâmetros de erro padronizados
  * Melhor rastreamento de sessão e ponto de entrada

### Atualizações

* **Validação de token:** Validação de token aprimorada com mensagens de erro melhores para tokens vazios e IDs de pessoa

### Exemplo de código

```swift
let sdkConfig = CafSDKConfiguration(
    presentationOrder: [.faceLiveness, .documentDetector],
    colorConfig: CafColorConfiguration(
        primaryColor: "#FF0000",
        secondaryColor: "#FFFFFF",
        contentColor: "#000000",
        backgroundColor: "#FFFFFF",
        mediumColor: "#CCCCCC",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"
    ),
    waitForAllServices: true,
    enableTransitionScreens: true // Novo parâmetro
)
```

## CafSDK iOS v5.3.0

### Novos recursos

* **Personalização aprimorada de diálogos:** Adicionadas novas propriedades de configuração de cores para personalizar a aparência de diálogos e pop-ups:
  * `dialogBackgroundColor`: personalize a cor de fundo de diálogos e pop-ups (o padrão é uma cor dinâmica com base no estilo da interface: `#1C1C1E` para o modo escuro, `#FFFFFF` para o modo claro)
  * `dialogBorderColor`: personalize a cor da borda de diálogos e pop-ups (o padrão é `#E5E5E7`)

### Exemplo de código

```swift
let colorConfig = CafColorConfiguration(
    primaryColor: "#FF0000",
    secondaryColor: "#FFFFFF",
    contentColor: "#000000",
    backgroundColor: "#FFFFFF",
    mediumColor: "#CCCCCC",
    dialogBackgroundColor: "#FFFFFF", // Novo
    dialogBorderColor: "#E5E5E7"      // Novo
)
```

## CafSDK iOS v5.2.0

### Novos recursos

* **Lógica aprimorada do fluxo de documentos:** Quando documentos digitais (RG Digital ou CNH Digital) estão presentes no fluxo, o SDK agora automaticamente:
  * força a ativação do modo de upload
  * pula a tela de seleção da origem da foto
  * vai diretamente para o fluxo de upload para uma experiência de usuário mais fluida

### Atualizações

* **Padrão das configurações de upload alterado:** `CafUploadSettings.enable` agora usa como padrão `true` em vez de `false`
  * Isso afeta `CafDocumentDetectorConfig`, `CafUploadSettings`
* **Lógica de seleção de documentos:** Lógica aprimorada para seleção de documentos RG e CNH:
  * Quando os documentos frente/verso e completo estão disponíveis, o SDK seleciona inteligentemente os documentos de frente e verso na ordem correta
  * As opções de documento digital têm prioridade e são exibidas primeiro nas telas de seleção

### Correções

* **Fluxo de upload:** Corrigido um problema relacionado a documentos incorretos que causavam um erro no fluxo de upload.

## CafSDK iOS v5.1.0

### Atualizações

* Melhorias de segurança em DocumentDetector e CafFaceliveness
* Novo parâmetro `maxRetryAttempts` no DocumentDetector para definir o número máximo de tentativas de repetição no fluxo de erro do servidor do DocumentCapture (o padrão é `2`)

### Correções

* inicialização de erro do CafSDKProvider, ambos `mobileToken` e `personId` são obrigatórios

## CafSDK iOS v5.0.2

### Atualizações

* Atualização da versão de build do Xcode de `16.2` a `16.4`.

## CafSDK iOS v5.0.1

### Atualizações

* Atualizado `Iproov` versão de `12.3.0` a `12.3.1`.

### Novos recursos

* Atualizado `reverseProxyConfig: CafReverseProxyConfig` a **CafFaceLivenessConfig**, consolidando `authBaseUrl`, `livenessBaseUrl`, e `certificates` parâmetros.
* Novo `executeFaceAuth` parâmetro adicionado para definir se a autenticação facial deve ser realizada.
* Novo `maxRetryAttempts` método para `CafFaceLivenessConfig` definir o número máximo de tentativas de repetição para a validação de Face Liveness.

## CafSDK iOS v4.1.1

### Melhorias

* Melhorias para analytics híbridas (`Flutter / React Native`)

## CafSDK iOS v4.1.0

### Novos recursos

* Adicionado `customLocalization: String?` a **FaceLiveness** construtores.
* Novos tipos de personalização para o DocumentDetector:
  * `CafUploadMessagesCustomization`
  * `CafFailedPhotoCustomization`

## CafSDK iOS v4.0.0

### Mudanças significativas

* **API de resposta unificada:** `CafUnifiedResponse` agora expõe apenas `signedResponse: String` (não há mais `[String: Any]` dicionário de resultados).
* **Tratamento de erros:** Adicionado `invalidResponseException` a `CafErrorType`;
* **Mudanças incompatíveis:**
  1. `CafUnifiedResponse` a assinatura do inicializador mudou: sem `result` parâmetro.
  2. Propriedade `result` removido; substitua todos os usos por `signedResponse`.
* **Retry atualizado no upload de documentos:** em conexões mais lentas ou uploads interrompidos, o fluxo documentDetector integrou uma opção de retry para o upload de documentos

**Guia de migração da v3.x**

1. **Atualizar dependência**
   * SPM: use `from: "4.0.0"`
   * CocoaPods: `pod 'CafSDKiOS', '~> 4.0.0'`
2. **Tratamento de callbacks**

   ```swift
   case .success(let responses):
       responses.forEach { response in
           print("Módulo: \(response.moduleName) Resposta assinada: \(response.signedResponse)")
       }
   ```
3. **Remover** `response.result`
   * Todas as referências ao `[String: Any]` mapa result devem usar response.`signedResponse` em vez disso.
4. **Trate** `invalidResponseException`
   * No seu `.error` switch, adicione um case para `.invalidResponseException`.
5. Fluxos do Document Detector
   * Se você dependia do antigo dicionário de resultados, faça a migração para analisar seu JWT de `signedResponse`.

## CafSDK iOS v3.0.0

### Novos recursos

* **Análises aprimoradas**
* **Tratamento de eventos de falha:** Adicionado detalhado `falha` caso a `CafUnifiedEvent` com resposta do servidor, tipo de erro e descrição
* **Personalização da UI do Document Detector:**
  * Introduzido `CafDDCustomization` protocolo e tipos concretos (`CafPreviewCustomization`, `CafDDUploadCustomization`, `CafMessageCustomization`) para permitir substituir textos e imagens padrão em telas específicas do Document Detector (por exemplo, pré-visualização, pop-up de upload, mensagens no fluxo). Isso é configurado por meio do novo `ddCustomizations` propriedade em `CafDocumentDetectorConfig`.
  * `CafDocumentDetectorStep` agora inclui `customMessage` e `customOkButtonTitle` propriedades para personalizar o pop-up de instruções para cada etapa.
* **Atualização de tema:**
  * Propriedades de cor específicas do Document Detector (como `primaryColor`, `uploadBackGroundColor`, `previewBackGroundColor`) foram removidas de `CafDocumentDetectorLayout`. A UI agora herda principalmente seu tema do global `CafColorConfiguration` definida em `CafSDKConfiguration`, garantindo uma aparência e sensação mais consistentes.

### Atualizações

* Melhor diferenciação no tratamento de erros:
  * Use `CafFailureType` tipo enum para falhas operacionais específicas do módulo do SDK
  * Use `CafErrorType` tipo enum para erros gerais de execução

### Mudanças incompatíveis

1. **Atualizações na assinatura do evento:**

```swift
case .failure(response: String?, type: CafFailureType, description: String?)
case .error(type: CafErrorType, description: String)  // Substitui o antigo erro baseado em String
```

2. **Aplicação de segurança de tipos:**

* Todas as comparações de tipo de erro/falha devem usar casos de enum em vez de strings brutas

3. **`CafDocumentDetectorConfig` Alterações:**
   * Removido `previewTitle`, `previewSubtitle`, `previewConfirmLabel`, `previewRetryLabel` propriedades. Use `CafPreviewCustomization` dentro de `ddCustomizations` em vez disso.
   * Removido `messageSettings` propriedade. Use `CafMessageCustomization` dentro de `ddCustomizations` em vez disso.
4. **`CafDocumentDetectorLayout` Alterações:**
   * Removido `primaryColor`, `uploadBackGroundColor`, `previewBackGroundColor` propriedades. As cores agora são definidas globalmente por meio de `CafColorConfiguration`.

### Guia de migração

1. Atualize para v3.0.0+.
2. Inclua o novo `.failure`evento

```swift
case .failure(response: String?, type: CafFailureType, description: String?)
```

3. Atualizar `.error` evento

```swift
case .error(type: CafErrorType, description: String)  // Substitui o antigo erro baseado em String
```

4. **Atualizar `CafDocumentDetectorConfig`:**
   * Se você estava usando `previewTitle`, `previewSubtitle`, etc., crie um `CafPreviewCustomization` objeto, defina suas propriedades e adicione-o ao `ddCustomizations` array em `CafDocumentDetectorConfig`.
   * Se você estava usando `messageSettings`, crie um `CafMessageCustomization` objeto, defina suas propriedades e adicione-o ao `ddCustomizations` array.
5. **Atualizar `CafDocumentDetectorStep`:**
   * Se você precisar personalizar a mensagem do pop-up de instruções ou o texto do botão OK para uma etapa específica, use os novos `customMessage` e `customOkButtonTitle` inicializadores/propriedades de `CafDocumentDetectorStep`.
6. **Revisar tema:**
   * Certifique-se de que seu global `CafColorConfiguration` (em `CafSDKConfiguration`) esteja configurado conforme desejado, pois os elementos da UI do Document Detector agora usarão principalmente essas cores.

## CafSDK iOS v2.0.0

### Novos recursos

* **Flag de resultados em lote:** `CafSDKConfiguration(waitForAllServices: true)` agora agrega todas as respostas dos módulos em uma única `.success(responses: [...])`.
* **Unificado `.success` Atualização:** `.success` agora sempre carrega um array de respostas.

### Mudanças incompatíveis

* Assinatura de `CafUnifiedEvent.success` alterada para `success(responses: [CafUnifiedResponse])`.

### Guia de migração

1. Atualize para v2.0.0+.
2. Altere o manipulador para esperar um array:

   ```
   case .success(let responses):
       responses.forEach { resp in /* ... */ }
   ```

## CafSDK iOS v1.4.0

### Novos recursos

* **Apresentando `CafSDKProvider`:** Um ponto de entrada unificado para integrar os módulos Face Liveness e Document Detector com uma única configuração.
* **Padrão Builder:** Inicialização simplificada usando `CafSDKProvider.Builder` para configuração modular e com segurança de tipos.
* **Configuração unificada:** Configure ambos os módulos usando `CafSDKConfiguration`, incluindo a ordem de execução (`presentationOrder`) e a definição de tema da interface (`CafColorConfiguration`).
* **Consistência entre módulos:** Autenticação, ambiente e registro compartilhados entre os módulos.

### Atualizações na documentação

* Guias revisados para integração com Swift Package Manager (SPM) e CocoaPods.
* Adicionados exemplos detalhados para `CafFaceLivenessConfig` e `CafDocumentDetectorConfig`.

### Melhorias na configuração

#### Face Liveness

* Personalize instruções (`CafInstructionsConfiguration`).
* Configure endpoints de proxy reverso (`authBaseUrl`, `livenessBaseUrl`).

#### Document Detector

* Defina fluxos de captura em várias etapas (`[CafDocumentDetectorStep]`).
* Personalização da UI (`CafDocumentDetectorLayout`, `CafMessageSettings`).
* Suporte a proxy (`CafProxySettings`).

### Mudanças incompatíveis

* **Novo módulo de integração:** `CafSDK`
* **Renomeação de módulos:** `FaceLiveness` → `CafFaceLiveness`, `DocumentDetector` → `CafDocumentDetector`
* **Dependências atualizadas:** Requer Xcode 16.2+ e iOS 13.0+

### Guia de migração

1. Substitua os inicializadores independentes do módulo por `CafSDKProvider`
2. Atualize os casos do enum para minúsculas (por exemplo, `.CNH_FRONT` → `.cnhFront`)
3. Use `CafDocumentDetectorStep(stepType:)` em vez de construtores legados


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.caf.io/caf-sdk/caf-sdk-pt-br/ios/getting-started-with-the-sdk-5.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
