> ## 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.

# Verifica dell'identità SDK iOS Swift: KYC mobile

> SDK iOS Swift di Didit per verifica dell'identità, vitalità e lettura NFC dei passaporti. A consumo, $10 gratis al mese, senza contratti.



Prompt di integrazione iOS SDK
        Copia il prompt negli appunti



      
      

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



      
      

Incolla in

Un SDK iOS leggero e guidato dal server per la verifica dell'identità, che richiede una configurazione minima. **Ultima versione: 4.13.2.**> [card] [Repository GitHub](https://github.com/didit-protocol/sdk-ios)
>
> Visualizza il codice sorgente, le release e il changelog completo su GitHub> [!NOTE]
>
> ### **SDK nativo**: Questo è l'approccio consigliato per le app iOS. Gli SDK nativi offrono la migliore esperienza utente, una gestione ottimizzata della fotocamera e pieno supporto NFC.***## Requisiti| Requisito | Versione minima |
| - | - |
| iOS | 13.0+ |
| Xcode | 15.0+ |
| Swift | 5.9+ |### Compatibilità delle versioni iOS| Versione iOS | Funzionalità disponibili |
| - | - |
| iOS 13.0 - 14.x | Tutte le funzionalità **tranne** la lettura del passaporto via NFC |
| iOS 15.0+ | Tutte le funzionalità, inclusa la lettura del passaporto via NFC |> [!NOTE]
>
> **Il consenso biometrico richiede l'SDK nativo 4.10.0 o successivo.** Per le persone soggette alle leggi dell'Illinois, del Texas o del Colorado, Didit può richiedere un [consenso biometrico](https://docs.didit.me/it/getting-started/biometric-consent.md) esplicito prima della prima acquisizione del volto. L'SDK iOS 4.10.0 e successivi mostra questo passaggio. Le versioni precedenti non possono mostrarlo: le loro sessioni proseguono come prima e la decisione riporta il consenso come non raccolto (`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`). Aggiorna se verifichi persone in questi stati.***## InstallazioneA partire dalla versione `4.0.0` l'SDK è distribuito in diverse varianti installabili, così la tua app paga in termini di dimensione del binario solo per le funzionalità che usa. Scegli esattamente una variante: un subspec CocoaPods e un prodotto di libreria SwiftPM.| Variante | CocoaPods | Prodotto SwiftPM | NFC | Rilevamento automatico | OpenSSL | iOS minimo |
| - | - | - | :-: | :-: | - | - |
| **Core** | `DiditSDK/Core` | `DiditSDKCore` | – | ✓ | nessuno | iOS 13.0+ |
| **AutoDetection** (deprecata) | `DiditSDK/AutoDetection` | `DiditSDKAutoDetection` | – | ✓ | nessuno | iOS 13.0+ |
| **NFC** | `DiditSDK/NFC` | `DiditSDKNFC` | ✓ | ✓ | `3.3.3` incluso | iOS 15.0+ |
| **All** (predefinita) | `DiditSDK/All` | `DiditSDK` | ✓ | ✓ | `3.3.3` incluso | iOS 15.0+ |- **Core** — la versione più leggera, con acquisizione automatica di documento e selfie tramite i rilevatori leggeri di Didit. Nessun `OpenSSL.xcframework`, nessun runtime CoreNFC.
- **AutoDetection** — deprecata dalla versione 4.11.0 e identica a **Core**; usa invece **Core**.
- **NFC** — **Core** più la lettura del chip di passaporti ed eID tramite NFC.
- **All** — tutte le funzionalità. Questa è la variante predefinita quando installi `DiditSDK` senza indicare un subspec o un prodotto.Ciò che ogni variante aggiunge al bundle della tua app (Mach-O arm64, misurato sulla versione `4.9.0`): **Core** \~11,1 MB, **NFC** \~11,7 MB più \~4 MB di OpenSSL, **AutoDetection** \~16,0 MB, **All** \~16,6 MB più OpenSSL.
I modelli di rilevamento vengono scaricati a runtime e memorizzati nella cache, quindi non incidono mai sulla dimensione del download della tua app.A partire dalla versione `4.11.0` l'acquisizione automatica usa i rilevatori leggeri di Didit in ogni variante. TensorFlow Lite non fa più parte dell'SDK e il framework è più piccolo perché le sue traduzioni vengono caricate dall'esterno del binario.A partire dalla versione `4.6.0` i framework distribuiti non includono più i descrittori ABI di Swift (metadati di build che Xcode copiava in ogni app senza mai leggerli) né i video tutorial che la variante non può riprodurre. Aggiornando dalla `4.5.4` o da una versione precedente, la tua app si riduce di circa 7-8 MB senza bisogno di modifiche al codice.
L'App Store comprime i binari per la distribuzione, quindi il costo effettivo del download è inferiore: controlla il report sulla dimensione dell'app in App Store Connect per la differenza esatta per dispositivo.> [!NOTE]
>
> Le varianti **NFC** e **All** includono `OpenSSL.xcframework` (**OpenSSL 3.3.3**, distribuito come `OpenSSL-Universal 3.3.3001` tramite `NFCPassportReader`), necessario per l'autenticazione del chip NFC e richiede iOS 15.0+. Le release **fino alla 4.0.6 inclusa** contenevano OpenSSL `1.1.1s`; le **4.0.7 e successive** distribuiscono OpenSSL 3.3.3 con il proprio manifesto sulla privacy e la propria firma del codice: installa sempre la **4.0.7 o successiva**. Tieni presente che l'aggiornamento allinea le *versioni* di OpenSSL ma non elimina i *conflitti di embed*: se un'altra dipendenza della tua app incorpora anch'essa un `OpenSSL.framework` (stesso nome file, stesso bundle id `com.github.krzyzanowskim.OpenSSL`), le due copie entrano in conflitto durante la fase di embed, indipendentemente dalla versione. Mantieni una sola copia: ad esempio, sostituisci l'altro package in base all'identità SPM per usare il `OpenSSL.xcframework` pubblicato da Didit, così il binario nel bundle è quello con cui questo SDK è stato compilato. Le varianti **Core** e **AutoDetection** non collegano alcuna libreria OpenSSL.`import DiditSDK` è identico nel codice della tua app, indipendentemente dalla variante installata.### Swift Package Manager (consigliato)Aggiungi il pacchetto al tuo progetto con Xcode:1) Vai su **File > Add Package Dependencies**
2) Inserisci l'URL del repository:```
https://github.com/didit-protocol/sdk-ios.git
```3) Seleziona la versione (oppure **Up to Next Major** a partire da `4.13.2`) e fai clic su **Add Package**
4) Quando ti viene chiesto di scegliere un prodotto, seleziona esattamente un prodotto di libreria per la tua variante (vedi la tabella sopra)Oppure nel tuo `Package.swift`:```swift theme={null}
dependencies: [
    .package(url: "https://github.com/didit-protocol/sdk-ios.git", from: "4.13.2")
]
```Poi aggiungi esattamente uno di questi prodotti al tuo 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 non applica da solo il requisito minimo di iOS 15.** `Package.swift` dichiara
> `platforms: [.iOS(.v13)]` per l'intero package, quindi Xcode ti permetterà di aggiungere `DiditSDK` o
> `DiditSDKNFC` a un target iOS 13 o 14 senza segnalare errori. Tuttavia entrambi includono `OpenSSL.xcframework` e leggono i chip tramite `NFCPassportReader`, che richiedono **iOS 15.0+**. Imposta manualmente il deployment target del tuo target su 15.0 quando usi il prodotto `All` o `NFC`. CocoaPods lo impone automaticamente tramite il `deployment_target` del subspec.### CocoaPods`DiditSDK` è distribuito come podspec binario ospitato nel repository (non è presente sul CocoaPods Trunk pubblico), quindi devi indicare l'URL del podspec. Scegli esattamente 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` e `AutoDetection` supportano iOS 13; `NFC` e `All` richiedono iOS 15 a causa di `NFCPassportReader`.Poi esegui:```bash theme={null}
pod install
```> [!NOTE]
>
> Dopo `pod install`, apri il file `.xcworkspace` generato (non `.xcodeproj`).> [!NOTE]
>
> **Errori rsync con Xcode 15+**: se durante la build compaiono errori rsync `Operation not permitted`, imposta **Build Settings → User Script Sandboxing** (`ENABLE_USER_SCRIPT_SANDBOXING`) su **No** nel progetto, sia per Debug sia per Release.### Manuale (XCFramework)Ogni release pubblica un XCFramework per variante. Scarica gli zip della tua variante dalla pagina [GitHub Releases](https://github.com/didit-protocol/sdk-ios/releases), poi trascina le cartelle `.xcframework` in Xcode e imposta **Embed & Sign**.| Variante | Download |
| - | - |
| **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` |***## AutorizzazioniL'SDK richiede le seguenti autorizzazioni. Aggiungile al file `Info.plist` della tua app:| Autorizzazione | Chiave Info.plist | Descrizione | Obbligatorio |
| - | - | - | - |
| Fotocamera | `NSCameraUsageDescription` | Scansione dei documenti e verifica facciale | ✅ Sì |
| Microfono | `NSMicrophoneUsageDescription` | Registrazione video per i controlli di rilevamento della vitalità | ✅ Sì |
| Libreria foto | `NSPhotoLibraryUsageDescription` | Caricamento di documenti dalla galleria del dispositivo | ✅ Sì |
| NFC | `NFCReaderUsageDescription` | Lettura dei chip NFC di passaporti e carte d'identità | ⚠️ Solo SDK completo |
| Posizione | `NSLocationWhenInUseUsageDescription` | Geolocalizzazione per la prevenzione delle frodi | ❌ Facoltativo |### Esempi di voci 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>
```### Configurazione NFCRichiesta solo se installi la variante **NFC** o **All**. Salta questa sezione se hai installato la variante **Core** o **AutoDetection**.Per abilitare la lettura NFC di passaporti e carte d'identità con chip:1) **Aggiungi la capability NFC** in Xcode:
   * Seleziona il tuo target → **Signing & Capabilities** → **+ Capability** → **Near Field Communication Tag Reading**

2) **Aggiungi gli identificatori 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` permette all'SDK di leggere la My Number Card giapponese tramite [JPKI](https://docs.didit.me/it/core-technology/nfc-verification/overview.md#japan-my-number-card-jpki): senza di esso, iOS non segnala la carta all'SDK. La lettura della My Number Card non è ancora abilitata in produzione e l'identificatore non modifica nulla per gli altri documenti, quindi puoi aggiungerlo già ora.3) **Aggiungi gli entitlement** (nel tuo file `.entitlements`):```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```> [!WARNING]
>
> **Limitazione del simulatore (varianti NFC e All)**: Queste varianti collegano CoreNFC e, da Xcode 12, la libreria `libnfshared.dylib` manca nei simulatori. Per una soluzione alternativa, consulta [questo thread di Stack Overflow](https://stackoverflow.com/questions/63915728/xcode12-corenfc-simulator-library-not-loaded). Questo **non** vale per le varianti **Core** o **AutoDetection**. Testa le funzionalità NFC solo su dispositivi fisici.> [!NOTE]
>
> ### **Revisione su App Store (varianti NFC e All)**: Se installi la variante **NFC** o **All**, Apple può chiedere un video dimostrativo durante la revisione, perché il codice relativo a NFC fa parte del binario dell'SDK, anche se il tuo workflow non usa NFC. Richiedi il nostro video dimostrativo NFC da inviare ad Apple a [support@didit.me](mailto:support@didit.me). Questo non vale per le varianti **Core** o **AutoDetection**.***## Avvio rapido### Integrazione con 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)")
        }
    }
}
```### Integrazione con 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")
    }
}
```***## Metodi di integrazioneL'SDK supporta due metodi di integrazione:### Metodo 1: UniLink (il più semplice)Non richiede un backend. L'SDK crea la sessione direttamente usando l'ID del tuo workflow dalla [Didit Console](https://business.didit.me). Il metodo UniLink (`startVerification(workflowId:)`) supporta solo `vendorData`; per qualsiasi altro parametro di sessione usa il Metodo 2.> [!NOTE]
>
> Perché `vendorData` venga associato alla sessione tramite UniLink, abilita l'opzione **Dati Fornitore** nella [Didit Console](https://business.didit.me).```swift theme={null}
DiditSdk.shared.startVerification(
    workflowId: "your-workflow-id",
    vendorData: "user-123"
)
```### Metodo 2: sessione lato backend (consigliato per la produzione)Il tuo backend crea la sessione tramite l'[API di creazione della sessione di verifica](https://docs.didit.me/it/sessions-api/create-session.md) (`POST /v3/session/`) con supporto completo dei parametri (`contact_details`, `expected_details`, `metadata`, `callback` e altri), poi passa il `session_token` all'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)
```Questo approccio ti offre il pieno controllo su:- Associare le sessioni ai tuoi utenti (`vendor_data`)
- Impostare i dettagli di contatto e i dettagli attesi per la convalida incrociata
- Impostare metadati personalizzati
- Configurare i callback per sessione
  Questi dati (dettagli di contatto, dettagli attesi, metadati, callback) vengono inviati all'[API di creazione della sessione di verifica](https://docs.didit.me/it/sessions-api/create-session.md).***## ConfigurazionePersonalizza il comportamento dell'SDK con `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
)
```### Opzioni di configurazione| Proprietà | Tipo | Predefinito | Descrizione |
| - | - | - | - |
| `languageLocale` | `SupportedLanguage?` | Lingua del dispositivo | Forza una lingua specifica |
| `showLanguageSelector` | `Bool` | `false` | Mostra il selettore della lingua in stile web sulla schermata di benvenuto |
| `fontFamily` | `String?` | Font di sistema | Nome della famiglia di font personalizzata (deve essere registrata nell'app tramite `UIAppFonts` in `Info.plist`) |
| `loggingEnabled` | `Bool` | `false` | Abilita il log di debug dell'SDK |
| `showCloseButton` | `Bool` | `true` | Mostra il pulsante di chiusura (X) sulle schermate dei passaggi di verifica |
| `showExitConfirmation` | `Bool` | `true` | Mostra una finestra di conferma quando l'utente tenta di uscire |
| `closeOnComplete` | `Bool` | `false` | Chiude automaticamente l'interfaccia di verifica al completamento (equivalente nell'SDK Web: `closeModalOnComplete`) |
| `defaultDocumentCamera` | `CameraLens` | `.back` | Obiettivo utilizzato quando si apre la schermata di acquisizione del documento |
| `defaultLivenessCamera` | `CameraLens` | `.front` | Obiettivo utilizzato quando si apre la schermata di acquisizione del volto (liveness) |
| `showDocumentCameraSwitchButton` | `Bool` | `true` | Mostra il selettore della fotocamera durante l'acquisizione sulla schermata di acquisizione del documento |
| `showLivenessCameraSwitchButton` | `Bool` | `true` | Mostra il selettore della fotocamera durante l'acquisizione sulla schermata di acquisizione del volto |### Opzioni della fotocameraLe opzioni della fotocamera corrispondono alle [opzioni della fotocamera dell'SDK Web](https://docs.didit.me/it/integration/web-sdks/javascript-sdk.md#opzioni-della-fotocamera).
Ogni obiettivo è `.front` o `.back`.
Se il dispositivo non dispone dell'obiettivo richiesto, l'SDK utilizza la prima fotocamera disponibile.
Il selettore della fotocamera è inoltre nascosto sui dispositivi che hanno una sola fotocamera.
Imposta un'opzione del selettore su `false` per bloccare l'utente sull'obiettivo predefinito di quel passaggio.```swift theme={null}
let configuration = DiditSdk.Configuration(
    defaultLivenessCamera: .back,
    showLivenessCameraSwitchButton: false
)
```> [!NOTE]
>
> **Tema e colori**: i colori, gli sfondi e le impostazioni della schermata introduttiva si configurano tramite le tue [impostazioni White label](https://business.didit.me) nella Didit Console, non nella configurazione dell'SDK. Questo garantisce un'identità del marchio coerente su tutte le piattaforme.> [!NOTE]
>
> Le opzioni `showLanguageSelector`, `showCloseButton`, `showExitConfirmation` e `closeOnComplete` corrispondono a `DiditSdkConfiguration` dell'SDK Web. Le opzioni specifiche per dispositivi mobili `languageLocale` e `fontFamily` esistono perché l'SDK mobile visualizza l'intera interfaccia di verifica in modo nativo (a differenza dell'SDK Web, che delega al frontend ospitato all'interno di un iframe).***## Supporto linguisticoL'SDK supporta **54 lingue**. Se non viene specificata alcuna lingua, l'SDK utilizza la lingua del dispositivo, con l'inglese come lingua di ripiego.```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()
```**[Visualizza tutte le lingue supportate →](https://docs.didit.me/it/integration/supported-languages.md)*****## Parametri avanzati della sessionePer i parametri avanzati della sessione (`contact_details`, `expected_details`, `metadata`, `callback`), usa il metodo **Backend Session**. Il tuo backend chiama la [API Create Verification Session](https://docs.didit.me/it/sessions-api/create-session.md) con tutti i parametri, quindi passa il `session_token` all'SDK.***## Gestione dei risultatiL'enum `VerificationResult` fornisce l'esito della verifica:### Casi del risultato| Caso | Descrizione |
| - | - |
| `.completed(session:)` | Il flusso di verifica è stato completato (controlla `session.status` per il risultato) |
| `.cancelled(session:)` | L'utente ha annullato il flusso di verifica |
| `.failed(error:session:)` | Si è verificato un errore durante la verifica |### Proprietà di SessionData| Proprietà | Tipo | Descrizione |
| - | - | - |
| `sessionId` | `String` | Identificatore univoco della sessione |
| `status` | `VerificationStatus` | `.approved`, `.pending` o `.declined` |
| `country` | `String?` | Codice del paese (ISO 3166-1 alpha-3) |
| `documentType` | `String?` | Tipo di documento utilizzato per la verifica |### Tipi di errore| Errore | Descrizione |
| - | - |
| `.sessionExpired` | La sessione è scaduta |
| `.networkError` | Problema di connettività di rete |
| `.cameraAccessDenied` | Autorizzazione alla fotocamera non concessa |
| `.unknown(String)` | Altro errore con messaggio |### Connessione persaSe il dispositivo perde la connessione durante la verifica, l'SDK mostra una schermata "Nessuna connessione Internet" al posto di lasciare un passaggio in caricamento.
Continua a controllare in background e chiude la schermata da sola non appena Didit torna raggiungibile, e l'utente prosegue dal passaggio in cui si trovava.
La schermata offre **Riprova** e, quando `showCloseButton` è `true` (predefinito), **Esci dalla verifica**.
Uscire termina la verifica con `.failed(error: .networkError, session:)`, così la tua app sa che l'utente è uscito a causa della connessione.### Esempio completo di gestione dei risultati```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
    }
}
```***## Chiusura della verifica in modo programmatico> [!NOTE]
>
> Disponibile in DiditSDK **3.6.0+**.L'app host può terminare una verifica attiva in modo programmatico con `DiditSdk.shared.dismiss()`. Questo è il modo consigliato per chiudere la verifica quando l'app host deve prendere il controllo dello schermo, ad esempio quando l'app passa in background.```swift theme={null}
DiditSdk.shared.dismiss()
````dismiss()` passa attraverso la normale pipeline di completamento dell'SDK: chiude l'interfaccia presentata, reimposta lo stato interno e richiama il gestore `.diditVerification` con `.cancelled(session:)`, che contiene il `sessionId` corrente se è stata creata una sessione. Se non è attiva alcuna verifica, non ha alcun effetto.### Esempio: chiusura quando l'app passa in background```swift theme={null}
NotificationCenter.default.addObserver(
    forName: UIApplication.didEnterBackgroundNotification,
    object: nil,
    queue: .main
) { _ in
    DiditSdk.shared.dismiss()
}
```> [!WARNING]
>
> Non impostare `DiditSdk.shared.isPresented = false` per chiudere la verifica: il flag attiva la presentazione solo sul fronte di salita, quindi impostarlo a `false` non ha alcun effetto. Allo stesso modo, chiamare `dismiss(animated:)` di UIKit sul controller di vista più in alto non è supportato: aggira la pipeline di completamento dell'SDK e il gestore `.diditVerification` non viene mai eseguito.***## Osservazione dello stato dell'SDKPuoi osservare lo stato dell'SDK per creare un'interfaccia di caricamento personalizzata:```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)")
            }
        }
    }
}
```***## Esempio end-to-end (sessione backend → SDK iOS → risultato)Questo schema è l'integrazione pronta per la produzione. Il backend crea la sessione, l'app iOS riceve il `session_token` e l'SDK esegue il flusso.### 1. Backend: creare la sessione```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: scambiare il token e avviare l'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: ricevere la decisione finale tramite webhookIl risultato dell'SDK è comodo per il feedback nell'interfaccia, ma l'esito definitivo arriva tramite webhook. Consulta la [guida ai webhook](https://docs.didit.me/it/integration/webhooks.md) per la verifica 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);
});
```***## Esempio SwiftUI completo```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.