> ## 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 d'iOS amb Swift per a verificació d'identitat

> SDK natiu de Didit per a iOS amb Swift: verificació d'identitat, prova de vida i NFC. $10 gratuïts al mes, sense contractes.



Prompt d'integració del SDK per a iOS
        Copia el prompt al porta-retalls



      
      

\<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>



      
      

Enganxa a

Un SDK per a iOS lleuger i controlat pel servidor per a la verificació d'identitat, que requereix una configuració mínima. **Última versió: 4.13.2.**> [card] [Repositori de GitHub](https://github.com/didit-protocol/sdk-ios)
>
> Consulta el codi font, les versions i el registre de canvis complet a GitHub> [!NOTE]
>
> ### **SDK natiu**: Aquesta és l'opció recomanada per a aplicacions iOS. Els SDK natius ofereixen la millor experiència d'usuari, una gestió de la càmera optimitzada i suport complet per a NFC.***## Requisits| Requisit | Versió mínima |
| - | - |
| iOS | 13.0+ |
| Xcode | 15.0+ |
| Swift | 5.9+ |### Compatibilitat amb les versions d'iOS| Versió d'iOS | Funcionalitats disponibles |
| - | - |
| iOS 13.0 - 14.x | Totes les funcionalitats **excepte** la lectura de passaports amb NFC |
| iOS 15.0+ | Totes les funcionalitats, incloent-hi la lectura de passaports amb NFC |> [!NOTE]
>
> **El consentiment biomètric requereix el SDK natiu 4.10.0 o posterior.** Per a les persones cobertes per les lleis d'Illinois, Texas o Colorado, Didit pot demanar un [consentiment biomètric](https://docs.didit.me/ca/getting-started/biometric-consent.md) explícit abans de la primera captura facial. L'SDK d'iOS 4.10.0 i les versions posteriors mostren aquest pas. Les versions anteriors no el poden mostrar: les seves sessions s'executen com abans, i la decisió indica que el consentiment no s'ha recollit (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`). Actualitza si verifiques persones en aquests estats.***## InstallationDes de `4.0.0`, el SDK es distribueix en diverses variants instal·lables, de manera que la teva aplicació només paga el cost binari de les funcionalitats que utilitza. Tria exactament una variant: un subspec de CocoaPods i un producte de biblioteca de SwiftPM.| Variant | CocoaPods | Producte SwiftPM | NFC | Autodetecció | OpenSSL | iOS mínim |
| - | - | - | :-: | :-: | - | - |
| **Core** | `DiditSDK/Core` | `DiditSDKCore` | – | ✓ | cap | iOS 13.0+ |
| **AutoDetection** (obsolet) | `DiditSDK/AutoDetection` | `DiditSDKAutoDetection` | – | ✓ | cap | iOS 13.0+ |
| **NFC** | `DiditSDK/NFC` | `DiditSDKNFC` | ✓ | ✓ | `3.3.3` inclòs | iOS 15.0+ |
| **All** (per defecte) | `DiditSDK/All` | `DiditSDK` | ✓ | ✓ | `3.3.3` inclòs | iOS 15.0+ |- **Core**: la menor mida, amb captura automàtica de document i selfie amb els detectors lleugers propis de Didit. Sense `OpenSSL.xcframework` ni runtime de CoreNFC.
- **AutoDetection**: obsolet des de 4.11.0 i idèntic a **Core**; utilitza **Core** en lloc seu.
- **NFC**: **Core** més la lectura de xips de passaports i eID amb NFC.
- **All**: totes les funcionalitats. És la variant per defecte quan instal·les `DiditSDK` sense indicar cap subspec ni producte.Què afegeix cada variant al paquet de la teva aplicació (binari Mach-O arm64, mesurat en comparació amb `4.9.0`): **Core** \~11,1 MB, **NFC** \~11,7 MB més \~4 MB d'OpenSSL, **AutoDetection** \~16,0 MB, **All** \~16,6 MB més OpenSSL.
Els models de detecció es descarreguen en temps d'execució i s'emmagatzemen a la memòria cau, de manera que mai no compten en la mida de descàrrega de la teva aplicació.Des de `4.11.0`, la captura automàtica s'executa amb els detectors lleugers propis de Didit en totes les variants. TensorFlow Lite ja no forma part del SDK, i el framework és més petit perquè les seves traduccions es carreguen des de fora del binari.Des de `4.6.0`, els frameworks distribuïts ja no inclouen descriptors d'ABI de Swift (metadades de compilació que Xcode copiava a cada aplicació però mai no llegia) ni vídeos tutorials que la variant no pot reproduir. Si actualitzes des de `4.5.4` o una versió anterior, la teva aplicació es redueix en uns 7-8 MB només amb això, sense cap canvi de codi.
L'App Store comprimeix els binaris per al lliurament, de manera que el cost de descàrrega per via aèria és menor; consulta l'informe de mida de l'aplicació a App Store Connect per conèixer la diferència exacta per dispositiu.> [!NOTE]
>
> Les variants **NFC** i **All** inclouen `OpenSSL.xcframework` (**OpenSSL 3.3.3**, distribuït com a `OpenSSL-Universal 3.3.3001` a través de `NFCPassportReader`), necessari per a l'autenticació del xip NFC i que requereix iOS 15.0+. Les versions **fins a la 4.0.6 inclosa** incloïen OpenSSL `1.1.1s`; les **4.0.7 i posteriors** distribueixen OpenSSL 3.3.3 amb el seu propi manifest de privacitat i la seva signatura de codi. Instal·la sempre la **4.0.7 o posterior**. Tingues en compte que actualitzar alinea les *versions* d'OpenSSL però no elimina els conflictes d'incrustació: si una altra dependència de la teva aplicació també incrusta un `OpenSSL.framework` (mateix nom de fitxer, mateix identificador de paquet `com.github.krzyzanowskim.OpenSSL`), les dues còpies col·lisionen en el pas d'incrustació, independentment de la versió. Mantén exactament una còpia: per exemple, substitueix l'altre paquet per identitat de SPM per utilitzar el `OpenSSL.xcframework` publicat per Didit, de manera que el binari del paquet sigui aquell contra el qual s'ha compilat aquest SDK. Les variants **Core** i **AutoDetection** no enllacen cap OpenSSL.`import DiditSDK` és el mateix al codi de la teva aplicació, independentment de la variant que instal·lis.### Swift Package Manager (recomanat)Afegeix el paquet al teu projecte amb Xcode:1) Ves a **File > Add Package Dependencies**
2) Introdueix la URL del repositori:```
https://github.com/didit-protocol/sdk-ios.git
```3) Selecciona la versió (o **Up to Next Major** a partir de `4.13.2`) i fes clic a **Add Package**
4) Quan se't demani que triïs un producte, tria exactament un producte de biblioteca per a la teva variant (consulta la taula de dalt)O bé al teu `Package.swift`:```swift theme={null}
dependencies: [
    .package(url: "https://github.com/didit-protocol/sdk-ios.git", from: "4.13.2")
]
```A continuació, afegeix exactament un d'aquests productes al teu 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]
>
> **Swift Package Manager no t'imposa el requisit mínim d'iOS 15.** `Package.swift` declara
> `platforms: [.iOS(.v13)]` per a tot el paquet, de manera que Xcode et deixarà afegir `DiditSDK` o
> `DiditSDKNFC` a un target d'iOS 13 o 14 sense cap avís; però tots dos inclouen `OpenSSL.xcframework` i llegeixen els xips a través de `NFCPassportReader`, que requereixen **iOS 15.0+**. Quan utilitzis el producte `All` o `NFC`, defineix tu mateix l'objectiu de desplegament del teu objectiu a 15.0. CocoaPods ho aplica automàticament mitjançant el `deployment_target` del subspec.### CocoaPods`DiditSDK` es distribueix com a podspec binari allotjat al repositori (no és al Trunk públic de CocoaPods), de manera que has de referenciar la URL del podspec. Tria exactament un 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
````Core` i `AutoDetection` són compatibles amb iOS 13 com a versió mínima; `NFC` i `All` requereixen iOS 15 per `NFCPassportReader`.A continuació, executa:```bash theme={null}
pod install
```> [!NOTE]
>
> Després de `pod install`, obre el `.xcworkspace` generat (no el `.xcodeproj`).> [!NOTE]
>
> **Errors de rsync a Xcode 15+**: si veus errors de rsync `Operation not permitted` durant la compilació, defineix **Build Settings → User Script Sandboxing** (`ENABLE_USER_SCRIPT_SANDBOXING`) a **No** al projecte, tant per a Debug com per a Release.### Manual (XCFramework)Cada versió publica un XCFramework per variant. Descarrega els zips de la teva variant des de [GitHub Releases](https://github.com/didit-protocol/sdk-ios/releases), després arrossega les carpetes `.xcframework` a Xcode i defineix **Embed & Sign**.| Variant | Descàrrega |
| - | - |
| **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` |***## PermisosEl SDK requereix els permisos següents. Afegeix-los al `Info.plist` de la teva aplicació:| Permís | Clau d'Info.plist | Descripció | Obligatori |
| - | - | - | - |
| Càmera | `NSCameraUsageDescription` | Escaneig de documents i verificació facial | ✅ Sí |
| Micròfon | `NSMicrophoneUsageDescription` | Enregistrament de vídeo per a les proves de vida | ✅ Sí |
| Biblioteca de fotos | `NSPhotoLibraryUsageDescription` | Pujada de documents des de la galeria del dispositiu | ✅ Sí |
| NFC | `NFCReaderUsageDescription` | Lectura de xips NFC en passaports i targetes d'identitat | ⚠️ Només amb l'SDK complet |
| Ubicació | `NSLocationWhenInUseUsageDescription` | Geolocalització per a la prevenció del frau | ❌ Opcional |### Exemples d'entrades per a 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>
```### Configuració de NFCObligatori només en instal·lar la variant **NFC** o **All**. Omet aquesta secció si has instal·lat la variant **Core** o **AutoDetection**.Per habilitar la lectura NFC de passaports i targetes d'identitat amb xip:1) **Afegeix la capacitat NFC** a Xcode:
   * Selecciona l'objectiu → **Signing & Capabilities** → **+ Capability** → **Near Field Communication Tag Reading**

2) **Afegeix els identificadors ISO7816** a `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` permet que l'SDK llegeixi la My Number Card del Japó a través de [JPKI](https://docs.didit.me/ca/core-technology/nfc-verification/overview.md#japan-my-number-card-jpki): sense aquest identificador, iOS no informa l'SDK de la targeta. La lectura de la My Number Card encara no està habilitada en producció, i l'identificador no canvia res per a altres documents, així que pots afegir-lo ara.3) **Afegeix els Entitlements** (al teu fitxer `.entitlements`):```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```> [!WARNING]
>
> **Limitació del simulador (variants NFC i All)**: Aquestes variants enllacen amb CoreNFC, i des de Xcode 12 falta `libnfshared.dylib` als simuladors. Consulta [aquest fil de Stack Overflow](https://stackoverflow.com/questions/63915728/xcode12-corenfc-simulator-library-not-loaded) per a una solució alternativa. Això **no** s'aplica a les variants **Core** o **AutoDetection**. Prova les funcionalitats NFC només en dispositius físics.> [!NOTE]
>
> ### **Revisió a l'App Store (variants NFC i All)**: si instal·les la variant **NFC** o **All**, Apple pot demanar un vídeo de demostració durant la revisió perquè el codi relacionat amb NFC forma part del binari de l'SDK, fins i tot si el teu flux de treball no utilitza NFC. Sol·licita el nostre vídeo de demostració NFC per enviar-lo a Apple a [support@didit.me](mailto:support@didit.me). Això no s'aplica a la variant **Core** o **AutoDetection**.***## Inici ràpid### Integració amb 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)")
        }
    }
}
```### Integració amb 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ètodes d'integracióL'SDK admet dos mètodes d'integració:### Mètode 1: UniLink (el més senzill)No requereix backend. L'SDK crea la sessió directament amb l'ID del teu flux de treball de la [Didit Console](https://business.didit.me). El mètode UniLink (`startVerification(workflowId:)`) només admet `vendorData`; per a qualsevol altre paràmetre de sessió, utilitza el mètode 2.> [!NOTE]
>
> Perquè `vendorData` s'associï a la sessió mitjançant UniLink, activa l'opció **Dades del proveïdor** a la [Didit Console](https://business.didit.me).```swift theme={null}
DiditSdk.shared.startVerification(
    workflowId: "your-workflow-id",
    vendorData: "user-123"
)
```### Mètode 2: Sessió al backend (recomanat per a producció)El backend crea la sessió mitjançant l'[API per crear sessions de verificació](https://docs.didit.me/ca/sessions-api/create-session.md) (`POST /v3/session/`) amb suport complet de paràmetres (`contact_details`, `expected_details`, `metadata`, `callback`, etc.), i després passa el `session_token` a l'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)
```Aquest enfocament et dona control total sobre:- Associar les sessions amb els teus usuaris (`vendor_data`)
- Definir les dades de contacte i les dades esperades per a la validació creuada
- Definir metadades personalitzades
- Configurar els callbacks per sessió
  Aquestes dades (dades de contacte, dades esperades, metadades, callback) s'envien a l'[API per crear sessions de verificació](https://docs.didit.me/ca/sessions-api/create-session.md).***## ConfiguracióPersonalitza el comportament del SDK amb `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
)
```### Opcions de configuració| Propietat | Tipus | Valor per defecte | Descripció |
| - | - | - | - |
| `languageLocale` | `SupportedLanguage?` | Idioma del dispositiu | Força un idioma concret |
| `showLanguageSelector` | `Bool` | `false` | Mostra el selector d'idioma d'estil web a la pantalla de benvinguda |
| `fontFamily` | `String?` | Tipografia del sistema | Nom de la família tipogràfica personalitzada (cal registrar-la a l'aplicació mitjançant `UIAppFonts` a `Info.plist`) |
| `loggingEnabled` | `Bool` | `false` | Activa el registre de depuració del SDK |
| `showCloseButton` | `Bool` | `true` | Mostra el botó de tancar (X) a les pantalles dels passos de verificació |
| `showExitConfirmation` | `Bool` | `true` | Mostra un diàleg de confirmació quan l'usuari intenta sortir |
| `closeOnComplete` | `Bool` | `false` | Tanca automàticament la interfície de verificació en completar-la (equivalent del Web SDK: `closeModalOnComplete`) |
| `defaultDocumentCamera` | `CameraLens` | `.back` | Òptica que s'utilitza quan s'obre la pantalla de captura del document |
| `defaultLivenessCamera` | `CameraLens` | `.front` | Òptica que s'utilitza quan s'obre la pantalla de captura facial (prova de vida) |
| `showDocumentCameraSwitchButton` | `Bool` | `true` | Mostra el selector de càmera durant la captura a la pantalla de captura del document |
| `showLivenessCameraSwitchButton` | `Bool` | `true` | Mostra el selector de càmera durant la captura a la pantalla de captura facial |### Opcions de càmeraLes opcions de càmera coincideixen amb les [opcions de càmera del Web SDK](https://docs.didit.me/ca/integration/web-sdks/javascript-sdk.md#opcions-de-càmera).
Cada òptica és `.front` o `.back`.
Si el dispositiu no té l'òptica sol·licitada, el SDK utilitza la primera càmera que tingui.
El selector de càmera també s'amaga en els dispositius que només tenen una càmera.
Estableix una opció del selector a `false` per limitar l'usuari a l'òptica per defecte d'aquest pas.```swift theme={null}
let configuration = DiditSdk.Configuration(
    defaultLivenessCamera: .back,
    showLivenessCameraSwitchButton: false
)
```> [!NOTE]
>
> **Personalització i colors**: Els colors, els fons i la configuració de les pantalles d'introducció es configuren mitjançant la [configuració de marca blanca](https://business.didit.me) a la Didit Console, i no a la configuració del SDK. Així es garanteix una imatge de marca coherent a totes les plataformes.> [!NOTE]
>
> Les opcions `showLanguageSelector`, `showCloseButton`, `showExitConfirmation` i `closeOnComplete` coincideixen amb el `DiditSdkConfiguration` del Web SDK. Les opcions específiques del mòbil `languageLocale` i `fontFamily` existeixen perquè el SDK per a mòbil renderitza la interfície de verificació completa de manera nativa (a diferència del Web SDK, que delega al frontend allotjat dins d'un iframe).***## Suport d'idiomesEl SDK admet **54 idiomes**. Si no s'especifica cap idioma, el SDK utilitza l'idioma del dispositiu, amb l'anglès com a 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()
```**[Consulta tots els idiomes admesos →](https://docs.didit.me/ca/integration/supported-languages.md)*****## Paràmetres avançats de la sessióPer als paràmetres avançats de la sessió (`contact_details`, `expected_details`, `metadata`, `callback`), utilitza el mètode **Backend Session**. El teu backend crida l'[API per crear una sessió de verificació](https://docs.didit.me/ca/sessions-api/create-session.md) amb tots els paràmetres i després passa el `session_token` al SDK.***## Gestió dels resultatsL'enumeració `VerificationResult` proporciona el resultat de la verificació:### Casos de resultat| Cas | Descripció |
| - | - |
| `.completed(session:)` | El flux de verificació s'ha completat (consulta `session.status` per al resultat) |
| `.cancelled(session:)` | L'usuari ha cancel·lat el flux de verificació |
| `.failed(error:session:)` | S'ha produït un error durant la verificació |### Propietats de SessionData| Propietat | Tipus | Descripció |
| - | - | - |
| `sessionId` | `String` | Identificador únic de la sessió |
| `status` | `VerificationStatus` | `.approved`, `.pending` o `.declined` |
| `country` | `String?` | Codi de país (ISO 3166-1 alpha-3) |
| `documentType` | `String?` | Tipus de document utilitzat per a la verificació |### Tipus d'error| Error | Descripció |
| - | - |
| `.sessionExpired` | La sessió ha caducat |
| `.networkError` | Problema de connectivitat de xarxa |
| `.cameraAccessDenied` | No s'ha concedit el permís de càmera |
| `.unknown(String)` | Un altre error amb missatge |### Connexió perdudaSi el dispositiu perd la connexió durant la verificació, el SDK mostra una pantalla de «Sense connexió a Internet» que cobreix el flux, en lloc de deixar un pas en estat de càrrega.
Continua comprovant la connexió en segon pla i tanca la pantalla automàticament en el moment en què es pot tornar a contactar amb Didit, i l'usuari continua des del pas on era.
La pantalla ofereix **Torna-ho a provar** i, quan `showCloseButton` és `true` (el valor per defecte), **Surt de la verificació**.
En sortir, la verificació finalitza amb `.failed(error: .networkError, session:)`, de manera que la teva aplicació sap que l'usuari ha sortit a causa del problema de connexió.### Exemple complet de gestió de resultats```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
    }
}
```***## Tancar la verificació de manera programàtica> [!NOTE]
>
> Disponible a partir de la versió **3.6.0+** de DiditSDK.L'aplicació amfitriona pot finalitzar una verificació activa de manera programàtica amb `DiditSdk.shared.dismiss()`. Aquesta és la manera recomanada de tancar la verificació quan l'aplicació amfitriona necessita prendre el control de la pantalla, per exemple quan l'aplicació passa a segon pla.```swift theme={null}
DiditSdk.shared.dismiss()
````dismiss()` segueix el flux de finalització normal del SDK: tanca la interfície presentada, reinicia l'estat intern i invoca el gestor `.diditVerification` amb `.cancelled(session:)`, que inclou el `sessionId` actual si s'ha creat una sessió. No fa res si no hi ha cap verificació activa.### Exemple: tancar la verificació quan l'aplicació passa a segon pla```swift theme={null}
NotificationCenter.default.addObserver(
    forName: UIApplication.didEnterBackgroundNotification,
    object: nil,
    queue: .main
) { _ in
    DiditSdk.shared.dismiss()
}
```> [!WARNING]
>
> **No** estableixis `DiditSdk.shared.isPresented = false` per tancar la verificació. Aquest indicador només activa la presentació en el seu flanc ascendent, i establir-lo a `false` no fa res. De la mateixa manera, no s'admet cridar `dismiss(animated:)` de UIKit sobre el controlador de vista superior, perquè salta el flux de finalització del SDK i el gestor `.diditVerification` no s'executarà mai.***## Observar l'estat del SDKPots observar l'estat del SDK per crear una interfície de càrrega personalitzada:```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)")
            }
        }
    }
}
```***## Exemple de principi a fi (sessió al backend → SDK d'iOS → resultat)Aquest patró és la integració a punt per a producció. El teu backend crea la sessió, la teva aplicació d'iOS rep el `session_token` i el SDK executa el flux.### 1. Backend: crear la sessió```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: intercanviar el token i iniciar el 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: rebre la decisió final mitjançant webhookEl resultat del SDK és útil per donar retroacció a la interfície, però el resultat definitiu arriba mitjançant webhook. Consulta la [Guia de webhooks](https://docs.didit.me/ca/integration/webhooks.md) per a la verificació 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);
});
```***## Exemple complet de 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.