> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK iOS Swift para Verificação de Identidade: KYC Móvel

> SDK nativo iOS em Swift da Didit para verificação de identidade, prova de vida e leitura NFC de passaportes. $10 grátis/mês, sem contratos.



Prompt de integração do SDK para iOS
        Copiar o prompt para a área de transferência



      
      

\<pre>

\`Integrate Didit identity verification into my iOS app using the native Swift SDK (DiditSDK 4.13.2).

\## Requirements
\- iOS 13.0+, Xcode 15.0+, Swift 5.9+
\- NFC chip reading requires iOS 15+ and a compatible device with NFC hardware
\- Since 4.0.0 the SDK ships in four variants; pick exactly one:
\- Core (DiditSDKCore): no NFC, no auto-detection, no OpenSSL, iOS 13.0+, smallest binary (manual capture only)
\- AutoDetection (DiditSDKAutoDetection): ML auto-capture, no NFC, no OpenSSL, iOS 13.0+
\- NFC (DiditSDKNFC): NFC passport reading, bundles OpenSSL 3.3.3, iOS 15.0+
\- All (DiditSDK — default): every feature, bundles OpenSSL 3.3.3, iOS 15.0+

\## Installation

\### Option A: Swift Package Manager (recommended)
1\. In Xcode: File > Add Package Dependencies
2\. Enter URL: https://github.com/didit-protocol/sdk-ios.git
3\. Select version 4.13.2 (or "Up to Next Major") and click Add Package
4\. Add exactly one library product for your variant:
\- All (NFC + auto-detection): product "DiditSDK"
\- Core (no NFC, no auto-detection): product "DiditSDKCore"
\- AutoDetection (auto-capture, no NFC): product "DiditSDKAutoDetection"
\- NFC (NFC, no auto-detection): product "DiditSDKNFC"

In Package.swift:
.package(url: "https://github.com/didit-protocol/sdk-ios.git", from: "4.13.2")
Then add one product, e.g. .product(name: "DiditSDK", package: "DiditSDK") or .product(name: "DiditSDKCore", package: "DiditSDK"). Your code always writes import DiditSDK regardless of variant.

\### Option B: CocoaPods (binary podspec — DiditSDK is not on the public Trunk)
podspec_url = 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'
\# Pick exactly one subspec:
\# All (NFC + auto-detection, iOS 15+):
platform :ios, '15.0'
pod 'DiditSDK/All', :podspec => podspec_url
\# Core (no NFC, no auto-detection, iOS 13+):        pod 'DiditSDK/Core', :podspec => podspec_url
\# AutoDetection (auto-capture, no NFC, iOS 13+):    pod 'DiditSDK/AutoDetection', :podspec => podspec_url
\# NFC (NFC, no auto-detection, iOS 15+):            pod 'DiditSDK/NFC', :podspec => podspec_url

Then run: pod install
Open the .xcworkspace (not .xcodeproj).

On Xcode 15+ if you hit rsync "Operation not permitted", set Build Setting ENABLE_USER_SCRIPT_SANDBOXING to No on the project (Debug and Release).

\## Required Permissions (Info.plist)
\- NSCameraUsageDescription (required) — Document scanning and face verification
\- NSMicrophoneUsageDescription (required) — Video recording for liveness checks
\- NSPhotoLibraryUsageDescription (required) — Upload documents from gallery
\- NFCReaderUsageDescription (only if using the NFC or All variant) — Read NFC chips in passports/IDs
\- NSLocationWhenInUseUsageDescription (optional) — Geolocation for fraud prevention

\## NFC Configuration (NFC or All variant only — skip for the Core or AutoDetection variants)
1\. Add "Near Field Communication Tag Reading" capability in Xcode > Signing & Capabilities
2\. Add ISO7816 identifiers to Info.plist:
com.apple.developer.nfc.readersession.iso7816.select-identifiers:
\["D23300000045737445494420763335", "A0000002471001", "A0000002472001", "00000000000000", "D392F000260100000001"]
(D392F000260100000001 is the Japan My Number Card's JPKI application: without it, iOS does not report that card to the SDK.)
3\. Add to entitlements file:
com.apple.developer.nfc.readersession.formats: ["TAG"]

\## Backend: Create Session (your server)
POST https://verification.didit.me/v3/session/
Headers: { "x-api-key": DIDIT_API_KEY, "Content-Type": "application/json" }
Body: { "workflow_id": DIDIT_WORKFLOW_ID, "vendor_data": "user-id" }
Response: { "session_id": "uuid", "session_token": "short-token", "url": "https://verify.didit.me/session/short-token", "status": "Not Started" }
Send session_token to the iOS app (never expose DIDIT_API_KEY to the device).

\## SwiftUI Integration (recommended)
import SwiftUI
import DiditSDK

struct ContentView: View {
var body: some View {
    Button("Verify Identity") {
        // Option A: With session token from your backend (recommended)
        DiditSdk.shared.startVerification(token: "session-token-from-backend")

        // Option B: With workflow ID (SDK creates session internally — UniLink, vendorData only)
        // DiditSdk.shared.startVerification(workflowId: "your-workflow-id", vendorData: "user-id")
    }
    .diditVerification { result in
        switch result {
        case .completed(let session):
            // session.status: VerificationStatus = .approved | .pending | .declined
            if session.status == .approved { /* grant access */ }
        case .cancelled(let session):
            // User dismissed the flow; session may be nil if none was created
            \_ = session
        case .failed(let error, _):
            // VerificationError — show error.localizedDescription
            \_ = error
        }
    }
}
}

\## Programmatically dismissing the verification (3.6.0+)
Call DiditSdk.shared.dismiss() to end an active verification (e.g. on app backgrounding).
It dismisses the UI, resets state, and fires the .diditVerification handler with .cancelled(session:).
Do NOT toggle DiditSdk.shared.isPresented = false or call UIKit dismiss() on the topmost VC — that bypasses the completion pipeline.

\## Result Statuses (SDK enum / API string)
\- .approved / "Approved"  — user identity verified, grant access
\- .declined / "Declined"  — verification failed, show retry or contact support
\- .pending  / "In Review" — needs manual review by your compliance team

\## Full Verification Results
The SDK only returns the status. Full decision data (document fields, face match scores, AML hits, etc.) arrives via webhook to your backend.
Set up webhooks: https://docs.didit.me/integration/webhooks

\## Rate Limits (session creation)
\- 600 session-create requests / minute per x-api-key (see https://docs.didit.me/integration/rate-limiting)
\- On 429, retry honouring Retry-After / X-RateLimit-* headers

\## Environment Variables (backend only — never expose in the iOS app)
\- DIDIT_API_KEY — from Didit Console > API & Webhooks
\- DIDIT_WORKFLOW_ID — from Didit Console > Workflows

\## App Store Note
If you ship the NFC or All variant, Apple may request an NFC demo video during review. Request ours from [support@didit.me](mailto:support@didit.me).

\## Docs
\- iOS SDK: https://docs.didit.me/integration/native-sdks/ios-sdk
\- GitHub: https://github.com/didit-protocol/sdk-ios
\- Webhooks: https://docs.didit.me/integration/webhooks
\- API Reference: https://docs.didit.me/api-reference/overview`

\</pre>



      
      

Colar em

Um SDK para iOS leve e orientado pelo servidor, para verificação de identidade com configuração mínima. **Versão mais recente: 4.13.2.**> [card] [Repositório no GitHub](https://github.com/didit-protocol/sdk-ios)
>
> Veja o código-fonte, as versões e o registo de alterações completo no GitHub> [!NOTE]
>
> ### **SDK nativo**: Esta é a abordagem recomendada para aplicações iOS. Os SDKs nativos oferecem a melhor experiência do utilizador, uma gestão da câmara otimizada e suporte NFC completo.***## Requisitos| Requisito | Versão mínima |
| - | - |
| iOS | 13.0+ |
| Xcode | 15.0+ |
| Swift | 5.9+ |### Compatibilidade com versões do iOS| Versão do iOS | Funcionalidades disponíveis |
| - | - |
| iOS 13.0 - 14.x | Todas as funcionalidades **exceto** a leitura de passaportes por NFC |
| iOS 15.0+ | Todas as funcionalidades, incluindo a leitura de passaportes por NFC |> [!NOTE]
>
> **O consentimento biométrico requer o SDK nativo 4.10.0 ou posterior.** Para pessoas abrangidas pela lei do Illinois, do Texas ou do Colorado, a Didit pode pedir um [consentimento biométrico](https://docs.didit.me/pt/getting-started/biometric-consent.md) explícito antes da primeira captura facial. O SDK para iOS 4.10.0 e versões posteriores apresentam esse passo. As versões anteriores não o conseguem apresentar: as sessões são executadas como antes, e a decisão indica que o consentimento não foi recolhido (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`). Atualize a versão se verificar pessoas nesses estados.***## InstalaçãoDesde `4.0.0`, o SDK é distribuído em várias variantes instaláveis, para que a sua aplicação só pague o custo binário das funcionalidades que usa. Escolha exatamente uma variante: um subspec do CocoaPods e um produto de biblioteca do SwiftPM.| Variante | CocoaPods | Produto SwiftPM | NFC | Deteção automática | OpenSSL | iOS mínimo |
| - | - | - | :-: | :-: | - | - |
| **Core** | `DiditSDK/Core` | `DiditSDKCore` | – | ✓ | nenhum | iOS 13.0+ |
| **AutoDetection** (obsoleta) | `DiditSDK/AutoDetection` | `DiditSDKAutoDetection` | – | ✓ | nenhum | iOS 13.0+ |
| **NFC** | `DiditSDK/NFC` | `DiditSDKNFC` | ✓ | ✓ | `3.3.3` incluído | iOS 15.0+ |
| **All** (predefinida) | `DiditSDK/All` | `DiditSDK` | ✓ | ✓ | `3.3.3` incluído | iOS 15.0+ |- **Core**: o tamanho mais reduzido, com captura automática de documento e selfie através dos detetores leves da própria Didit. Sem `OpenSSL.xcframework` e sem runtime do CoreNFC.
- **AutoDetection**: obsoleta desde a 4.11.0 e idêntica à **Core**; use a **Core** em vez desta.
- **NFC**: a **Core** mais a leitura do chip de passaportes e eID por NFC.
- **All** — todas as funcionalidades. É a predefinição quando instala o `DiditSDK` sem indicar um subspec ou produto.O que cada variante acrescenta ao pacote da sua aplicação (Mach-O arm64, medido com a `4.9.0`): **Core** \~11,1 MB, **NFC** \~11,7 MB mais \~4 MB de OpenSSL, **AutoDetection** \~16,0 MB, **All** \~16,6 MB mais OpenSSL.
Os modelos de deteção são transferidos em tempo de execução e ficam em cache, pelo que nunca contam para o tamanho de transferência da sua aplicação.Desde a `4.11.0`, a captura automática funciona com os detetores leves da própria Didit em todas as variantes. O TensorFlow Lite deixou de fazer parte do SDK, e a framework ficou mais pequena porque as traduções são carregadas a partir do exterior do binário.Desde a `4.6.0`, as frameworks distribuídas deixaram de incluir os descritores ABI do Swift (metadados de compilação que o Xcode copiava para todas as aplicações, mas nunca lia) e os vídeos tutoriais que a variante não consegue reproduzir. Ao atualizar a partir da `4.5.4` ou de versões anteriores, a sua aplicação fica cerca de 7-8 MB mais pequena só por esse motivo, sem alterações de código.
A App Store comprime os binários para distribuição, pelo que o custo de transferência sem fios é inferior. Consulte o relatório de tamanho da aplicação no App Store Connect para ver a diferença exata por dispositivo.> [!NOTE]
>
> As variantes **NFC** e **All** incluem o `OpenSSL.xcframework` (**OpenSSL 3.3.3**, distribuído como `OpenSSL-Universal 3.3.3001` através do `NFCPassportReader`), necessário para a autenticação do chip NFC, e requerem iOS 15.0+. As versões **até à 4.0.6 inclusive** incluíam o OpenSSL `1.1.1s`; as **4.0.7 e posteriores** distribuem o OpenSSL 3.3.3 com o seu próprio manifesto de privacidade e assinatura de código. Instale sempre a **4.0.7 ou posterior**. Atualizar alinha as *versões* do OpenSSL, mas não elimina conflitos de *embed*: se outra dependência da sua aplicação também incorporar um `OpenSSL.framework` (mesmo nome de ficheiro, mesmo bundle id `com.github.krzyzanowskim.OpenSSL`), as duas cópias entram em conflito no passo de embed, independentemente da versão. Mantenha apenas uma cópia; por exemplo, substitua o outro pacote, através da respetiva identidade SPM, para utilizar o `OpenSSL.xcframework` publicado pela Didit, de forma a que o binário incluído na aplicação seja o mesmo contra o qual este SDK foi compilado. As variantes **Core** e **AutoDetection** não fazem qualquer ligação ao OpenSSL.`import DiditSDK` é igual no código da sua aplicação, independentemente da variante instalada.### Swift Package Manager (recomendado)Adicione o pacote ao seu projeto através do Xcode:1) Aceda a **File > Add Package Dependencies**
2) Introduza o URL do repositório:```
https://github.com/didit-protocol/sdk-ios.git
```3) Selecione a versão (ou **Up to Next Major** a partir da `4.13.2`) e clique em **Add Package**
4) Quando lhe for pedido para escolher um produto, selecione exatamente um produto de biblioteca para a sua variante (consulte a tabela acima)Ou no seu `Package.swift`:```swift theme={null}
dependencies: [
    .package(url: "https://github.com/didit-protocol/sdk-ios.git", from: "4.13.2")
]
```Em seguida, adicione exatamente um destes produtos ao seu target:```swift theme={null}
// All (default — NFC + auto-detection)
.product(name: "DiditSDK", package: "DiditSDK")

// Core (no NFC, no auto-detection, no OpenSSL)
.product(name: "DiditSDKCore", package: "DiditSDK")

// AutoDetection (auto-capture, no NFC)
.product(name: "DiditSDKAutoDetection", package: "DiditSDK")

// NFC (NFC passport reading, no auto-detection)
.product(name: "DiditSDKNFC", package: "DiditSDK")
```> [!WARNING]
>
> **O Swift Package Manager não impõe o mínimo de iOS 15 por si.** O `Package.swift` declara `platforms: [.iOS(.v13)]` para o pacote inteiro, pelo que o Xcode permite adicionar o `DiditSDK` ou o `DiditSDKNFC` a um target iOS 13 ou 14 sem qualquer aviso. No entanto, ambos incluem o `OpenSSL.xcframework` e leem os chips através do `NFCPassportReader`, que requerem **iOS 15.0+**. Defina você próprio o deployment target do target como 15.0 ao usar o produto `All` ou `NFC`. O CocoaPods aplica isto automaticamente através do `deployment_target` do subspec.### CocoaPodsO `DiditSDK` é distribuído como um podspec binário alojado no repositório (não está no CocoaPods Trunk público), pelo que tem de referenciar o URL do podspec. Escolha exatamente um subspec:```ruby theme={null}
podspec_url = 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.13.2/DiditSDK.podspec'

# All (NFC + auto-detection, iOS 15.0+):
platform :ios, '15.0'
pod 'DiditSDK/All', :podspec => podspec_url

# Core (no NFC, no auto-detection, iOS 13.0+):
# pod 'DiditSDK/Core', :podspec => podspec_url

# AutoDetection (auto-capture, no NFC, iOS 13.0+):
# pod 'DiditSDK/AutoDetection', :podspec => podspec_url

# NFC (NFC passport reading, iOS 15.0+):
# pod 'DiditSDK/NFC', :podspec => podspec_url
```As variantes `Core` e `AutoDetection` funcionam a partir do iOS 13; `NFC` e `All` requerem iOS 15 por causa do `NFCPassportReader`.Em seguida, execute:```bash theme={null}
pod install
```> [!NOTE]
>
> Após o `pod install`, abra o `.xcworkspace` gerado (e não o `.xcodeproj`).> [!NOTE]
>
> **Erros de rsync no Xcode 15+**: se vir erros de rsync `Operation not permitted` durante a compilação, defina **Build Settings → User Script Sandboxing** (`ENABLE_USER_SCRIPT_SANDBOXING`) como **Não** no projeto, tanto para Debug como para Release.### Manual (XCFramework)Cada versão publica um XCFramework por variante. Transfira os zips da sua variante a partir das [GitHub Releases](https://github.com/didit-protocol/sdk-ios/releases), arraste as pastas `.xcframework` para o Xcode e defina **Embed & Sign**.| Variante | Transferência |
| - | - |
| **Core** | `DiditSDK-Core.xcframework.zip` |
| **AutoDetection** | `DiditSDK-AutoDetection.xcframework.zip` |
| **NFC** | `DiditSDK-NFC.xcframework.zip` + `OpenSSL.xcframework.zip` |
| **All** | `DiditSDK.xcframework.zip` + `OpenSSL.xcframework.zip` |***## PermissõesO SDK requer as seguintes permissões. Adicione-as ao ficheiro `Info.plist` da sua aplicação:| Permissão | Chave do Info.plist | Descrição | Obrigatório |
| - | - | - | - |
| Câmara | `NSCameraUsageDescription` | Digitalização de documentos e verificação facial | ✅ Sim |
| Microfone | `NSMicrophoneUsageDescription` | Gravação de vídeo para as verificações de prova de vida | ✅ Sim |
| Biblioteca de fotos | `NSPhotoLibraryUsageDescription` | Carregar documentos a partir da galeria do dispositivo | ✅ Sim |
| NFC | `NFCReaderUsageDescription` | Ler chips NFC em passaportes e cartões de identificação | ⚠️ Apenas SDK completo |
| Localização | `NSLocationWhenInUseUsageDescription` | Geolocalização para prevenção de fraude | ❌ Opcional |### Exemplos de entradas do Info.plist```xml theme={null}
<key>NSCameraUsageDescription</key>
<string>Camera access is required to scan your identity documents for verification.</string>

<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required to record video for liveness verification.</string>

<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is required to upload document images.</string>

<key>NFCReaderUsageDescription</key>
<string>NFC access is required to read the chip in your identity document.</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Location access helps verify your identity and prevent fraud.</string>
```### Configuração de NFCNecessário apenas ao instalar a variante **NFC** ou **All**. Ignore esta secção se tiver instalado a variante **Core** ou **AutoDetection**.Para ativar a leitura NFC de passaportes e cartões de identificação com chip:1) **Adicione a capacidade NFC** no Xcode:
   * Selecione o seu alvo → **Signing & Capabilities** → **+ Capability** → **Near Field Communication Tag Reading**

2) **Adicione os identificadores ISO7816** ao `Info.plist`:```xml theme={null}
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
    <string>D23300000045737445494420763335</string>
    <string>A0000002471001</string>
    <string>A0000002472001</string>
    <string>00000000000000</string>
    <string>D392F000260100000001</string>
</array>
````D392F000260100000001` permite ao SDK ler o Cartão My Number do Japão através do [JPKI](https://docs.didit.me/pt/core-technology/nfc-verification/overview.md#cartão-my-number-do-japão-jpki): sem ele, o iOS não comunica o cartão ao SDK. A leitura do Cartão My Number ainda não está ativada em produção, e o identificador não altera nada para os outros documentos, pelo que pode adicioná-lo desde já.3) **Adicione os direitos (entitlements)** (no seu ficheiro `.entitlements`):```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```> [!WARNING]
>
> **Limitação do simulador (variantes NFC e All)**: Estas variantes fazem ligação ao CoreNFC e, desde o Xcode 12, o `libnfshared.dylib` está em falta nos simuladores. Consulte [esta publicação do Stack Overflow](https://stackoverflow.com/questions/63915728/xcode12-corenfc-simulator-library-not-loaded) para uma solução alternativa. Isto **não** se aplica às variantes **Core** ou **AutoDetection**. Teste as funcionalidades NFC apenas em dispositivos físicos.> [!NOTE]
>
> ### **Revisão na App Store (variantes NFC e All)**: Se instalar a variante **NFC** ou **All**, a Apple pode pedir um vídeo de demonstração durante a revisão, porque o código relacionado com NFC faz parte do binário do SDK, mesmo que o seu fluxo não use NFC. Peça o nosso vídeo de demonstração NFC para submeter à Apple através de [support@didit.me](mailto:support@didit.me). Isto não se aplica às variantes **Core** ou **AutoDetection**.***## Início rápido### Integração com SwiftUI```swift theme={null}
import SwiftUI
import DiditSDK

struct ContentView: View {
    var body: some View {
        Button("Verify Identity") {
            // Method 1: UniLink — no backend required
            DiditSdk.shared.startVerification(workflowId: "your-workflow-id")
            
            // Method 2: Backend Session — full parameter control
            // DiditSdk.shared.startVerification(token: "your-session-token")
        }
        .diditVerification { result in
            handleResult(result)
        }
    }
    
    private func handleResult(_ result: VerificationResult) {
        switch result {
        case .completed(let session):
            print("Completed: \(session.status)")
        case .cancelled(let session):
            print("Cancelled")
        case .failed(let error, _):
            print("Failed: \(error.localizedDescription)")
        }
    }
}
```### Integração com UIKit```swift theme={null}
import UIKit
import DiditSDK

class VerificationViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Start verification when ready
        DiditSdk.shared.startVerification(token: "your-session-token")
    }
}
```***## Métodos de integraçãoO SDK suporta dois métodos de integração:### Método 1: UniLink (o mais simples)Não requer backend. O SDK cria a sessão diretamente com o ID do seu fluxo de verificação obtido na [Didit Console](https://business.didit.me). O método UniLink (`startVerification(workflowId:)`) suporta apenas `vendorData`; para quaisquer outros parâmetros de sessão, use o Método 2.> [!NOTE]
>
> Para que o `vendorData` seja associado à sessão através do UniLink, ative a opção **Dados do fornecedor** na [Didit Console](https://business.didit.me).```swift theme={null}
DiditSdk.shared.startVerification(
    workflowId: "your-workflow-id",
    vendorData: "user-123"
)
```### Método 2: Sessão no backend (recomendado para produção)O seu backend cria a sessão através da [API de criação de sessão de verificação](https://docs.didit.me/pt/sessions-api/create-session.md) (`POST /v3/session/`), com suporte completo de parâmetros (`contact_details`, `expected_details`, `metadata`, `callback`, etc.), e depois transmite o `session_token` ao SDK.```swift theme={null}
// Your backend creates a session and returns the token
let sessionToken = await yourBackend.createVerificationSession(userId: currentUser.id)

// Pass the token to the SDK
DiditSdk.shared.startVerification(token: sessionToken)
```Esta abordagem oferece-lhe controlo total sobre:- Associar sessões aos seus utilizadores (`vendor_data`)
- Definir os dados de contacto e os dados esperados para validação cruzada
- Definir metadados personalizados
- Configurar os callbacks por sessãoEstes dados (dados de contacto, dados esperados, metadados, callback) são enviados para a [API de criação de sessão de verificação](https://docs.didit.me/pt/sessions-api/create-session.md).***## ConfiguraçãoPersonalize o comportamento do SDK com `DiditSdk.Configuration`:```swift theme={null}
let configuration = DiditSdk.Configuration(
    languageLocale: .spanish,      // Force Spanish language
    showLanguageSelector: true,    // Let the user change language
    fontFamily: "Avenir",          // Custom font (must be registered in your app)
    loggingEnabled: true,          // Enable debug logging
    showCloseButton: true,         // Show close (X) button on step screens
    showExitConfirmation: true,    // Show confirmation dialog when user taps close
    closeOnComplete: false         // Don't auto-dismiss on completion
)

DiditSdk.shared.startVerification(
    token: "your-session-token",
    configuration: configuration
)
```### Opções de configuração| Propriedade | Tipo | Predefinição | Descrição |
| - | - | - | - |
| `languageLocale` | `SupportedLanguage?` | Idioma do dispositivo | Força um idioma específico |
| `showLanguageSelector` | `Bool` | `false` | Mostra o seletor de idioma no estilo do Web SDK no ecrã de boas-vindas |
| `fontFamily` | `String?` | Tipo de letra do sistema | Nome da família de tipos de letra personalizada (tem de estar registada na sua app através de `UIAppFonts` em `Info.plist`) |
| `loggingEnabled` | `Bool` | `false` | Ativa o registo de depuração do SDK |
| `showCloseButton` | `Bool` | `true` | Mostra o botão de fecho (X) nos ecrãs dos passos de verificação |
| `showExitConfirmation` | `Bool` | `true` | Mostra uma caixa de confirmação quando o utilizador tenta sair |
| `closeOnComplete` | `Bool` | `false` | Fecha automaticamente a interface de verificação quando concluída (equivalente no Web SDK: `closeModalOnComplete`) |
| `defaultDocumentCamera` | `CameraLens` | `.back` | Objetiva usada quando se abre o ecrã de captura do documento |
| `defaultLivenessCamera` | `CameraLens` | `.front` | Objetiva usada quando se abre o ecrã de captura do rosto (prova de vida) |
| `showDocumentCameraSwitchButton` | `Bool` | `true` | Mostra o seletor de câmara durante a captura no ecrã de captura do documento |
| `showLivenessCameraSwitchButton` | `Bool` | `true` | Mostra o seletor de câmara durante a captura no ecrã de captura do rosto |### Opções da câmaraAs opções de câmara correspondem às [opções de câmara do Web SDK](https://docs.didit.me/pt/integration/web-sdks/javascript-sdk.md#opções-de-câmara).
Cada objetiva é `.front` ou `.back`.
Se o dispositivo não tiver a objetiva pedida, o SDK usa a primeira câmara que tiver.
O seletor de câmara também fica oculto em dispositivos que têm apenas uma câmara.
Defina uma opção de seletor como `false` para impedir o utilizador de mudar da objetiva predefinida desse passo.```swift theme={null}
let configuration = DiditSdk.Configuration(
    defaultLivenessCamera: .back,
    showLivenessCameraSwitchButton: false
)
```> [!NOTE]
>
> **Tema e cores**: As cores, os fundos e as definições do ecrã de introdução são configurados nas suas [definições de marca branca](https://business.didit.me) na Didit Console, e não na configuração do SDK. Isto garante uma identidade visual consistente em todas as plataformas.> [!NOTE]
>
> As opções `showLanguageSelector`, `showCloseButton`, `showExitConfirmation` e `closeOnComplete` correspondem ao `DiditSdkConfiguration` do Web SDK. As opções específicas para dispositivos móveis `languageLocale` e `fontFamily` existem porque o SDK para dispositivos móveis apresenta a interface completa de verificação de forma nativa (ao contrário do Web SDK, que delega no frontend alojado dentro de um iframe).***## Suporte de idiomasO SDK suporta **54 idiomas**. Se não for especificado nenhum idioma, o SDK usa o idioma do dispositivo, com inglês como alternativa.```swift theme={null}
// Use device locale (default)
let config = DiditSdk.Configuration()

// Force specific language
let config = DiditSdk.Configuration(languageLocale: .french)

// Let the user change language on the welcome screen
let config = DiditSdk.Configuration(showLanguageSelector: true)

// Detect device locale programmatically
let deviceLanguage = SupportedLanguage.fromDeviceLocale()
```**[Ver todos os idiomas suportados →](https://docs.didit.me/pt/integration/supported-languages.md)*****## Parâmetros avançados da sessãoPara parâmetros avançados da sessão (`contact_details`, `expected_details`, `metadata`, `callback`), use o método **Backend Session**. O seu backend chama a [API para criar sessões de verificação](https://docs.didit.me/pt/sessions-api/create-session.md) com todos os parâmetros e, depois, transmite o `session_token` ao SDK.***## Tratamento dos resultadosO enum `VerificationResult` fornece o resultado da verificação:### Casos de resultado| Caso | Descrição |
| - | - |
| `.completed(session:)` | Fluxo de verificação concluído (verifique `session.status` para obter o resultado) |
| `.cancelled(session:)` | O utilizador cancelou o fluxo de verificação |
| `.failed(error:session:)` | Ocorreu um erro durante a verificação |### Propriedades de SessionData| Propriedade | Tipo | Descrição |
| - | - | - |
| `sessionId` | `String` | Identificador único da sessão |
| `status` | `VerificationStatus` | `.approved`, `.pending` ou `.declined` |
| `country` | `String?` | Código do país (ISO 3166-1 alpha-3) |
| `documentType` | `String?` | Tipo de documento usado na verificação |### Tipos de erro| Erro | Descrição |
| - | - |
| `.sessionExpired` | A sessão expirou |
| `.networkError` | Problema de ligação à rede |
| `.cameraAccessDenied` | Permissão da câmara não concedida |
| `.unknown(String)` | Outro erro com mensagem |### Ligação perdidaSe o dispositivo perder a ligação durante a verificação, o SDK apresenta um ecrã "Sem ligação à Internet" sobre o fluxo, em vez de deixar um passo a carregar.
Continua a verificar em segundo plano e fecha o ecrã automaticamente assim que for possível voltar a contactar a Didit, e o utilizador continua a partir do passo em que estava.
O ecrã oferece **Tentar novamente** e, quando `showCloseButton` é `true` (o valor predefinido), **Sair da verificação**.
Ao sair, a verificação termina com `.failed(error: .networkError, session:)`, para que a sua app saiba que o utilizador saiu por causa da ligação.### Exemplo completo de tratamento de resultados```swift theme={null}
.diditVerification { result in
    switch result {
    case .completed(let session):
        switch session.status {
        case .approved:
            print("✅ Approved! Session: \(session.sessionId)")
            // User is verified - grant access
            
        case .pending:
            print("⏳ Under review. Session: \(session.sessionId)")
            // Show "verification in progress" UI
            
        case .declined:
            print("❌ Declined. Session: \(session.sessionId)")
            // Handle declined verification
        }
        
    case .cancelled(let session):
        if let session = session {
            print("🚫 Cancelled session: \(session.sessionId)")
        }
        // User chose to cancel - maybe show retry option
        
    case .failed(let error, let session):
        print("⚠️ Error: \(error.localizedDescription)")
        // Handle error - show retry or contact support
    }
}
```***## Encerrar a verificação programaticamente> [!NOTE]
>
> Disponível no DiditSDK **3.6.0+**.A aplicação hospedeira pode terminar uma verificação ativa de forma programática com `DiditSdk.shared.dismiss()`. Esta é a forma recomendada de encerrar a verificação quando a aplicação precisa de assumir o ecrã, por exemplo, quando passa para segundo plano.```swift theme={null}
DiditSdk.shared.dismiss()
````dismiss()` segue o pipeline de conclusão normal do SDK: fecha a interface apresentada, repõe o estado interno e invoca o handler `.diditVerification` com `.cancelled(session:)`, que transporta o `sessionId` atual, se tiver sido criada uma sessão. Não tem efeito quando não há nenhuma verificação ativa.### Exemplo: encerrar quando a aplicação passa para segundo plano```swift theme={null}
NotificationCenter.default.addObserver(
    forName: UIApplication.didEnterBackgroundNotification,
    object: nil,
    queue: .main
) { _ in
    DiditSdk.shared.dismiss()
}
```> [!WARNING]
>
> **Não** defina `DiditSdk.shared.isPresented = false` para encerrar a verificação: a flag só desencadeia a apresentação na sua transição ascendente, e defini-la como `false` não tem efeito. Do mesmo modo, chamar `dismiss(animated:)` do UIKit no controlador de vista superior não é suportado: contorna o pipeline de conclusão do SDK, pelo que o seu handler `.diditVerification` nunca é acionado.***## Observar o estado do SDKPode observar o estado do SDK para criar uma interface de carregamento personalizada:```swift theme={null}
struct CustomView: View {
    @ObservedObject private var sdk = DiditSdk.shared
    
    var body: some View {
        VStack {
            switch sdk.state {
            case .idle:
                Text("Ready to verify")
            case .creatingSession:
                ProgressView("Creating session...")
            case .loading:
                ProgressView("Loading...")
            case .ready:
                Text("Verification in progress")
            case .error(let message):
                Text("Error: \(message)")
            }
        }
    }
}
```***## Exemplo de ponta a ponta (sessão no backend → SDK iOS → resultado)Este padrão é a integração pronta para produção. O seu backend cria a sessão, a aplicação iOS recebe o `session_token` e o SDK executa o fluxo.### 1. Backend: criar a sessão```ts theme={null}
// Node.js / Express example. Run on your server. NEVER ship DIDIT_API_KEY to the device.
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/verification/start", async (req, res) => {
  const response = await fetch("https://verification.didit.me/v3/session/", {
    method: "POST",
    headers: {
      "x-api-key": process.env.DIDIT_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      vendor_data: req.body.userId, // your stable user id
    }),
  });

  if (!response.ok) {
    return res.status(500).json({ error: `Didit ${response.status}` });
  }

  const { session_id, session_token } = await response.json();
  // Persist session_id <-> userId so you can match the webhook later.
  res.json({ session_id, session_token });
});
```### 2. iOS: trocar o token e iniciar o SDK```swift theme={null}
import SwiftUI
import DiditSDK

struct VerifyButton: View {
    let userId: String
    @State private var error: String?

    var body: some View {
        Button("Verify Identity") {
            Task { await start() }
        }
        .diditVerification { result in
            switch result {
            case .completed(let session) where session.status == .approved:
                // Optimistically reflect success in the UI; rely on the webhook
                // delivered to your backend as the source of truth.
                break
            case .completed(let session):
                print("Terminal status: \(session.status.rawValue)")
            case .cancelled:
                print("User cancelled")
            case .failed(let err, _):
                error = err.localizedDescription
            }
        }
    }

    private func start() async {
        do {
            var req = URLRequest(url: URL(string: "https://your-backend.example.com/api/verification/start")!)
            req.httpMethod = "POST"
            req.setValue("application/json", forHTTPHeaderField: "Content-Type")
            req.httpBody = try JSONEncoder().encode(["userId": userId])

            let (data, _) = try await URLSession.shared.data(for: req)
            struct Payload: Decodable { let session_token: String }
            let payload = try JSONDecoder().decode(Payload.self, from: data)

            await MainActor.run {
                DiditSdk.shared.startVerification(token: payload.session_token)
            }
        } catch {
            self.error = error.localizedDescription
        }
    }
}
```### 3. Backend: receber a decisão final através de webhookO resultado do SDK é útil para o feedback na interface, mas o resultado definitivo chega por webhook. Consulte o [Guia de webhooks](https://docs.didit.me/pt/integration/webhooks.md) para a verificação HMAC.```ts theme={null}
app.post("/api/webhooks/didit", express.raw({ type: "application/json" }), (req, res) => {
  // 1. Verify the X-Signature header (see Webhooks docs)
  // 2. Parse the body
  const event = JSON.parse(req.body.toString());
  if (event.webhook_type === "status.updated") {
    // event.session_id, event.status ("Approved" | "Declined" | "In Review" | ...)
    // Look up the user by session_id and update their verification state.
  }
  res.sendStatus(200);
});
```***## Exemplo completo em SwiftUI```swift theme={null}
import SwiftUI
import DiditSDK

struct HomeView: View {
    @State private var resultMessage: String?
    @State private var isVerified = false
    
    var body: some View {
        VStack(spacing: 24) {
            if isVerified {
                Image(systemName: "checkmark.circle.fill")
                    .font(.system(size: 64))
                    .foregroundColor(.green)
                Text("Identity Verified")
                    .font(.title2)
            } else {
                Button("Verify Identity") {
                    startVerification()
                }
                .font(.headline)
                .padding(.horizontal, 32)
                .padding(.vertical, 16)
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(12)
            }
            
            if let message = resultMessage {
                Text(message)
                    .foregroundColor(.secondary)
                    .multilineTextAlignment(.center)
                    .padding()
            }
        }
        .diditVerification { result in
            handleResult(result)
        }
    }
    
    private func startVerification() {
        let config = DiditSdk.Configuration(
            languageLocale: .english
        )
        
        // Method 1: UniLink — no backend required
        DiditSdk.shared.startVerification(
            workflowId: "your-workflow-id",
            vendorData: "user-123",
            configuration: config
        )
        
        // Method 2: Backend Session — full parameter control
        // DiditSdk.shared.startVerification(
        //     token: "your-session-token",
        //     configuration: config
        // )
    }
    
    private func handleResult(_ result: VerificationResult) {
        switch result {
        case .completed(let session):
            if session.status == .approved {
                isVerified = true
            }
            resultMessage = """
                Status: \(session.status.rawValue)
                Session: \(session.sessionId)
                Country: \(session.country ?? "N/A")
                Document: \(session.documentType ?? "N/A")
                """
                
        case .cancelled(let session):
            resultMessage = "Cancelled - Session: \(session?.sessionId ?? "unknown")"
            
        case .failed(let error, _):
            resultMessage = "Failed: \(error.localizedDescription)"
        }
    }
}
```***


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.