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

# iOS本人確認SDK（Swift）：モバイルKYC

> DiditのiOS向けネイティブSwift SDKで、本人確認、生体認証によるライブネス検出、NFCでのICパスポート読み取りを実装できます。従量課金制で毎月$10分無料、契約不要です。



iOS SDK連携プロンプト
        プロンプトをクリップボードにコピー



      
      

\<pre>

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

\## 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.9.1 (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.9.1")
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.9.1/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>



      
      

貼り付け先

最小限の設定で利用できる、軽量でサーバー駆動型の本人確認用のiOS SDKです。**最新バージョン：4.9.1**> [card] [GitHubリポジトリ](https://github.com/didit-protocol/sdk-ios)
>
> ソースコード、リリース、完全な変更ログをGitHubで確認できます> [!NOTE]
>
> ### **ネイティブSDK**: iOSアプリにはこの方法を推奨します。ネイティブSDKは最適なユーザー体験、最適化されたカメラ処理、完全なNFCサポートを提供します。***## 要件| 要件 | 最小バージョン |
| - | - |
| iOS | 13.0+ |
| Xcode | 15.0+ |
| Swift | 5.9+ |### iOSバージョンの互換性| iOSバージョン | 利用可能な機能 |
| - | - |
| iOS 13.0 - 14.x | NFCによるパスポート読み取り**以外**のすべての機能 |
| iOS 15.0+ | NFCによるパスポート読み取りを含むすべての機能 |> [!NOTE]
>
> **生体認証の同意にはネイティブSDK 4.10.0以降が必要です。** イリノイ州、テキサス州、コロラド州の法律が適用される人については、Diditは最初の顔撮影の前に明示的な[生体認証の同意](https://docs.didit.me/ja/getting-started/biometric-consent.md)を求めることができます。iOS SDK 4.10.0以降はこのステップを表示します。それより前のバージョンではこのステップを表示できません。セッションは従来どおり実行され、判定では同意が未取得として報告されます（`biometric_consent.reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`）。これらの州に居住する人を認証する場合はアップグレードしてください。***## インストール`4.0.0`以降、SDKは**4種類のインストール可能なバリアント**で提供されるため、アプリには使用する機能の分のバイナリサイズしか加わりません。バリアントは必ず1つだけ選択してください。CocoaPodsのサブスペック1つ、SwiftPMのライブラリプロダクト1つです。| バリアント | CocoaPods | SwiftPMプロダクト | NFC | 自動検出 | OpenSSL | 最小iOS |
| - | - | - | :-: | :-: | - | - |
| **Core** | `DiditSDK/Core` | `DiditSDKCore` | – | – | なし | iOS 13.0+ |
| **AutoDetection** | `DiditSDK/AutoDetection` | `DiditSDKAutoDetection` | – | ✓ | なし | iOS 13.0+ |
| **NFC** | `DiditSDK/NFC` | `DiditSDKNFC` | ✓ | – | `3.3.3`同梱 | iOS 15.0+ |
| **All**(デフォルト) | `DiditSDK/All` | `DiditSDK` | ✓ | ✓ | `3.3.3`同梱 | iOS 15.0+ |- **Core**: 最小のフットプリントで、手動撮影のみに対応します。`OpenSSL.xcframework`、CoreNFCランタイム、MLランタイムはいずれも含まれません。
- **AutoDetection**: MLベースの書類・顔の自動撮影に対応しますが、NFCチップの読み取りには対応しません。
- **NFC**: 自動撮影用のMLランタイムなしで、パスポートやeIDのNFCチップ読み取りに対応します。
- **All**: すべての機能を含みます。サブスペックやプロダクトを指定せずに`DiditSDK`をインストールした場合のデフォルトです。各バリアントがアプリバンドルに追加するサイズ(arm64 Mach-O、`4.9.0`で計測)は、**Core**が約11.1MB、**NFC**が約11.7MBに加えてOpenSSLが約4MB、**AutoDetection**が約16.0MB、**All**が約16.6MBに加えてOpenSSLです。
検出モデル自体は実行時にダウンロードされてキャッシュされるため、アプリのダウンロードサイズには含まれません。`4.7.1`以降、**AutoDetection**と**All**のバリアントは、`4.6.0`まで使われていたMediaPipeランタイムに代わり、より軽量なMLランタイムで自動撮影の推論を実行します。これはオプトインのバリアントではなく全面的な切り替えであり、`4.7.1`以降を使用するすべての方に無条件で適用されます。そのため、代わりにインストールできる「旧エンジン」のバリアントは別途用意されていません。リリース成果物での計測では、App Storeの圧縮済みダウンロードペイロードが**-3.4MB(-28%)**、アプリに同梱されるarm64バイナリが**-8.5MB(-35%)**削減されています(非圧縮のデバイススライスのフレームワーク自体は約12MB小さくなっています)。検出の動作は、リリース前に実機のマトリクスで旧エンジンとフレーム単位で同一であることを検証済みで、書類の推論は計測上も高速化しています。> [!NOTE]
>
> **ランタイム変更のロールバック**: これはバリアントではなく切り替えであるため、元に戻すにはフラグを切り替えるのではなく、依存関係を`4.6.0`に固定します(SwiftPM: 「Up to Next Major」ではなくバージョン`4.6.0`を選択。CocoaPods: `podspec_url`を`4.6.0`タグに向ける)。Didit はリリース後1サイクルにわたり、このランタイムの実運用でのパフォーマンスを追跡します。リグレッションが見つかった場合の対応は、バージョン固定を促すアドバイザリと、現行ランタイムでのパッチリリースです。バリアントは存在しないため、バリアントの切り替えで対応することは決してありません。`4.6.0`以降、配布されるフレームワークには、Swift ABI記述子(Xcodeがすべてのアプリにコピーするものの一切読み込まないビルドメタデータ)や、そのバリアントでは再生できないチュートリアル動画が含まれなくなりました。`4.5.4`以前からアップグレードするだけで、コードを変更しなくてもアプリサイズが約7-8MB縮小します。
App Storeは配信時にバイナリを圧縮するため、OTAでのサイズはこれより小さくなります。デバイスごとの正確な差分は、App Store Connectのアプリサイズレポートで確認してください。> [!NOTE]
>
> **NFC**と**All**のバリアントには`OpenSSL.xcframework`(**OpenSSL 3.3.3**、`NFCPassportReader`経由で`OpenSSL-Universal 3.3.3001`として配布)が同梱されています。これはNFCチップ認証に必要で、iOS 15.0+が必要です。**4.0.6以前**のリリースにはOpenSSL `1.1.1s`が同梱されていました。**4.0.7以降**は、独自のプライバシーマニフェストとコード署名を備えたOpenSSL 3.3.3を同梱しています。必ず**4.0.7以降**をインストールしてください。なお、アップグレードによってOpenSSLの*バージョン*は揃いますが、*埋め込み*の衝突は解消されません。アプリ内の別の依存関係も`OpenSSL.framework`(同じファイル名、同じ`com.github.krzyzanowskim.OpenSSL`バンドルID)を埋め込んでいる場合、バージョンにかかわらず、埋め込みのステップで2つのコピーが衝突します。コピーは必ず1つだけにしてください。たとえば、もう一方のパッケージをSPMのIDでオーバーライドしてDidit が公開している`OpenSSL.xcframework`を使用させ、バンドル内のバイナリがこのSDKのビルドに使われたものになるようにします。**Core**と**AutoDetection**のバリアントはOpenSSLを一切リンクしません。アプリのコードでの`import DiditSDK`は、インストールするバリアントにかかわらず同じです。### Swift Package Manager (推奨)Xcodeを使ってプロジェクトにパッケージを追加します。1) **File > Add Package Dependencies**を開きます
2) リポジトリのURLを入力します。```
https://github.com/didit-protocol/sdk-ios.git
```3) バージョン(または`4.9.1`からの**Up to Next Major**)を選択し、**Add Package**をクリックします
4) プロダクトの選択を求められたら、使用するバリアントのライブラリプロダクトを必ず1つだけ選択します(上の表を参照)または`Package.swift`に以下を記述します。```swift theme={null}
dependencies: [
    .package(url: "https://github.com/didit-protocol/sdk-ios.git", from: "4.9.1")
]
```次に、以下のプロダクトのうち1つだけをターゲットに追加します。```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はiOS 15の下限を自動では適用しません。** `Package.swift`はパッケージ全体に対して
> `platforms: [.iOS(.v13)]`を宣言しているため、Xcodeでは`DiditSDK`や`DiditSDKNFC`を
> iOS 13または14のターゲットに追加しても警告は出ません。しかし、どちらも`OpenSSL.xcframework`を同梱し、
> `NFCPassportReader`経由でチップを読み取るため、\*\*iOS 15.0+\*\*が必要です。`All`または`NFC`プロダクトを使用する場合は、
> ターゲットのデプロイメントターゲットをご自身で15.0に設定してください。CocoaPodsでは、サブスペックの`deployment_target`により
> これが自動的に適用されます。### CocoaPods`DiditSDK`はリポジトリでホストされるバイナリpodspecとして配布されており(公開のCocoaPods Trunkにはありません)、podspecのURLを参照する必要があります。サブスペックは必ず1つだけ選択してください。```ruby theme={null}
podspec_url = 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.9.1/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`と`AutoDetection`はiOS 13以降に対応します。`NFC`と`All`は`NFCPassportReader`の要件によりiOS 15が必要です。次に以下を実行します。```bash theme={null}
pod install
```> [!NOTE]
>
> `pod install`の後は、生成された`.xcworkspace`を開いてください(`.xcodeproj`ではありません)。> [!NOTE]
>
> **Xcode 15+でのrsyncエラー**: ビルド中に`Operation not permitted`というrsyncエラーが表示される場合は、プロジェクトの**Build Settings → User Script Sandboxing**(`ENABLE_USER_SCRIPT_SANDBOXING`)を、DebugとReleaseの両方で**No**に設定してください。### 手動 (XCFramework)リリースごとに、バリアントごとのXCFrameworkが1つずつ公開されます。[GitHub Releases](https://github.com/didit-protocol/sdk-ios/releases)ページから使用するバリアントのzipをダウンロードし、`.xcframework`フォルダーをXcodeにドラッグして**Embed & Sign**を設定してください。| バリアント | ダウンロード |
| - | - |
| **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` |***## 権限SDKには次の権限が必要です。アプリの`Info.plist`に追加してください。| 権限 | Info.plistキー | 説明 | 必須 |
| - | - | - | - |
| カメラ | `NSCameraUsageDescription` | 書類のスキャンと顔認証 | ✅ はい |
| マイク | `NSMicrophoneUsageDescription` | ライブネスチェック用の動画録画 | ✅ はい |
| フォトライブラリ | `NSPhotoLibraryUsageDescription` | デバイスのギャラリーからの書類アップロード | ✅ はい |
| NFC | `NFCReaderUsageDescription` | パスポートやIDカードのNFCチップの読み取り | ⚠️ フルSDKのみ |
| 位置情報 | `NSLocationWhenInUseUsageDescription` | 不正防止のための位置情報取得 | ❌ 任意 |### 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>
```### NFCの設定**NFC**または**All**バリアントをインストールする場合にのみ必要です。**Core**または**AutoDetection**バリアントをインストールした場合は、このセクションをスキップしてください。チップ付きのパスポートやIDカードのNFC読み取りを有効にするには、次の手順を行います。1) Xcodeで**NFC Capabilityを追加**します。
   * ターゲットを選択 → **Signing & Capabilities** → **+ Capability** → **Near Field Communication Tag Reading**

2) `Info.plist`に**ISO7816識別子を追加**します。```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`により、SDKは[JPKI](https://docs.didit.me/ja/core-technology/nfc-verification/overview.md#日本のマイナンバーカード-jpki)を通じて日本のマイナンバーカードを読み取れるようになります。この識別子がないと、iOSはカードをSDKに通知しません。マイナンバーカードの読み取りは本番環境ではまだ有効になっていませんが、この識別子は他の書類には一切影響しないため、今のうちに追加しておけます。3) **Entitlementsを追加**します(`.entitlements`ファイル内)。```xml theme={null}
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>TAG</string>
</array>
```> [!WARNING]
>
> **シミュレーターの制限 (NFCおよびAllバリアント)**: これらのバリアントはCoreNFCをリンクしますが、Xcode 12以降、シミュレーターには`libnfshared.dylib`が存在しません。回避策については[こちらのStack Overflowのスレッド](https://stackoverflow.com/questions/63915728/xcode12-corenfc-simulator-library-not-loaded)を参照してください。これは**Core**または**AutoDetection**バリアントには**該当しません**。NFC機能のテストは実機でのみ行ってください。> [!NOTE]
>
> ### **App Store審査 (NFCおよびAllバリアント)**: **NFC**または**All**バリアントをインストールすると、NFC関連のコードがSDKバイナリに含まれるため、ワークフローでNFCを使用していない場合でも、審査中にAppleからデモ動画を求められることがあります。Appleに提出するためのNFCデモ動画は、[support@didit.me](mailto:support@didit.me)にご依頼ください。これは**Core**または**AutoDetection**バリアントには該当しません。***## クイックスタート### 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)")
        }
    }
}
```### 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")
    }
}
```***## 連携方法SDKは2つの連携方法に対応しています。### 方法1: UniLink (最もシンプル)バックエンドは不要です。SDKは[Didit Console](https://business.didit.me)のワークフローIDを使って、セッションを直接作成します。UniLink方式(`startVerification(workflowId:)`)が対応しているのは`vendorData`のみです。その他のセッションパラメーターを使う場合は方法2を使用してください。> [!NOTE]
>
> UniLink経由で`vendorData`をセッションに付与するには、[Didit Console](https://business.didit.me)で**Vendor Data**オプションを有効にしてください。```swift theme={null}
DiditSdk.shared.startVerification(
    workflowId: "your-workflow-id",
    vendorData: "user-123"
)
```### 方法2: バックエンドセッション (本番環境に推奨)バックエンドが[Create Verification Session API](https://docs.didit.me/ja/sessions-api/create-session.md)(`POST /v3/session/`)を通じて、すべてのパラメーター(`contact_details`、`expected_details`、`metadata`、`callback`など)を指定してセッションを作成し、`session_token`を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)
```この方法では、次の項目を完全に制御できます。- セッションとユーザーの関連付け(`vendor_data`)
- クロスバリデーションのための連絡先情報と期待値の設定
- カスタムメタデータの設定
- セッションごとのコールバックの設定
  これらのデータ(連絡先情報、期待値、メタデータ、コールバック)は[Create Verification Session API](https://docs.didit.me/ja/sessions-api/create-session.md)に送信されます。***## 設定`DiditSdk.Configuration`でSDKの動作をカスタマイズします。```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
)
```### 設定オプション| プロパティ | 型 | デフォルト | 説明 |
| - | - | - | - |
| `languageLocale` | `SupportedLanguage?` | デバイスのロケール | 特定の言語を強制します |
| `showLanguageSelector` | `Bool` | `false` | ウェルカム画面にWeb版と同じ言語セレクターを表示します |
| `fontFamily` | `String?` | システムフォント | カスタムフォントファミリー名(`Info.plist`の`UIAppFonts`でアプリに登録しておく必要があります) |
| `loggingEnabled` | `Bool` | `false` | SDKのデバッグログを有効にします |
| `showCloseButton` | `Bool` | `true` | 認証ステップの画面に閉じる(X)ボタンを表示します |
| `showExitConfirmation` | `Bool` | `true` | ユーザーが終了しようとしたときに確認ダイアログを表示します |
| `closeOnComplete` | `Bool` | `false` | 完了時に認証UIを自動で閉じます(Web SDKでの相当オプション:`closeModalOnComplete`) |
| `defaultDocumentCamera` | `CameraLens` | `.back` | 書類撮影画面を開いたときに使用するレンズ |
| `defaultLivenessCamera` | `CameraLens` | `.front` | 顔(ライブネス)撮影画面を開いたときに使用するレンズ |
| `showDocumentCameraSwitchButton` | `Bool` | `true` | 書類撮影画面に撮影中のカメラ切り替えボタンを表示します |
| `showLivenessCameraSwitchButton` | `Bool` | `true` | 顔撮影画面に撮影中のカメラ切り替えボタンを表示します |### カメラオプションカメラオプションは[Web SDKのカメラオプション](https://docs.didit.me/ja/integration/web-sdks/javascript-sdk.md#カメラオプション)と同じです。
各レンズは`.front`または`.back`です。
指定したレンズがデバイスにない場合、SDKはデバイスで利用可能な最初のカメラを使用します。
カメラが1つしかないデバイスでは、カメラ切り替えボタンも非表示になります。
切り替えボタンのオプションを`false`に設定すると、ユーザーはそのステップのデフォルトレンズに固定されます。```swift theme={null}
let configuration = DiditSdk.Configuration(
    defaultLivenessCamera: .back,
    showLivenessCameraSwitchButton: false
)
```> [!NOTE]
>
> **テーマとカラー**:カラー、背景、イントロ画面の設定は、SDKの設定ではなく、Didit Consoleの[ホワイトラベル設定](https://business.didit.me)で行います。これにより、すべてのプラットフォームで一貫したブランディングが保たれます。> [!NOTE]
>
> オプション`showLanguageSelector`、`showCloseButton`、`showExitConfirmation`、`closeOnComplete`はWeb SDKの`DiditSdkConfiguration`と同じです。モバイル固有のオプション`languageLocale`と`fontFamily`が存在するのは、モバイルSDKが認証UI全体をネイティブで描画するためです(Web SDKは、iframe内のホスト型フロントエンドに処理を委ねます)。***## 言語サポートSDKは**54言語**に対応しています。言語が指定されていない場合、SDKはデバイスのロケールを使用し、フォールバックとして英語を使用します。```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()
```**[対応言語をすべて表示 →](https://docs.didit.me/ja/integration/supported-languages.md)*****## 高度なセッションパラメーター高度なセッションパラメーター(`contact_details`、`expected_details`、`metadata`、`callback`)を使用するには、**Backend Session**方式を使用してください。バックエンドがすべてのパラメーターを指定して[Create Verification Session API](https://docs.didit.me/ja/sessions-api/create-session.md)を呼び出し、その後`session_token`をSDKに渡します。***## 結果の処理`VerificationResult`列挙型は認証の結果を提供します。### 結果のケース| ケース | 説明 |
| - | - |
| `.completed(session:)` | 認証フローが完了しました(結果は`session.status`で確認してください) |
| `.cancelled(session:)` | ユーザーが認証フローをキャンセルしました |
| `.failed(error:session:)` | 認証中にエラーが発生しました |### SessionDataのプロパティ| プロパティ | 型 | 説明 |
| - | - | - |
| `sessionId` | `String` | 一意のセッション識別子 |
| `status` | `VerificationStatus` | `.approved`、`.pending`、または`.declined` |
| `country` | `String?` | 国コード(ISO 3166-1 alpha-3) |
| `documentType` | `String?` | 認証に使用された書類の種類 |### エラーの種類| エラー | 説明 |
| - | - |
| `.sessionExpired` | セッションの有効期限が切れています |
| `.networkError` | ネットワーク接続の問題 |
| `.cameraAccessDenied` | カメラの権限が付与されていません |
| `.unknown(String)` | メッセージ付きのその他のエラー |### 接続の切断認証中にデバイスの接続が切れた場合、SDKはステップを読み込み中のままにせず、「No internet connection」画面を表示します。
SDKはバックグラウンドで接続状況の確認を続け、Diditに再び接続できるようになるとすぐにこの画面を自動で閉じます。ユーザーは中断したステップから続行できます。
この画面には**Try Again**が表示され、`showCloseButton`が`true`(デフォルト)の場合は**Exit Verification**も表示されます。
終了すると認証は`.failed(error: .networkError, session:)`で終了するため、ユーザーが接続の問題で離脱したことをアプリで把握できます。### 結果処理の完全な例```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
    }
}
```***## プログラムによる認証の終了> [!NOTE]
>
> DiditSDK \*\*3.6.0+\*\*で利用できます。ホストアプリは`DiditSdk.shared.dismiss()`を使って、進行中の認証をプログラムで終了できます。ホスト側が画面の制御を引き継ぐ必要がある場合(たとえばアプリがバックグラウンドに移行するとき)は、この方法で認証を終了することを推奨します。```swift theme={null}
DiditSdk.shared.dismiss()
````dismiss()`はSDKの通常の完了処理を経由します。表示中のUIを閉じ、内部状態をリセットしたうえで、`.diditVerification`ハンドラーを`.cancelled(session:)`で呼び出します。セッションが作成済みの場合は、現在の`sessionId`がこれに含まれます。進行中の認証がない場合は何も行いません。### 例: アプリのバックグラウンド移行時に終了する```swift theme={null}
NotificationCenter.default.addObserver(
    forName: UIApplication.didEnterBackgroundNotification,
    object: nil,
    queue: .main
) { _ in
    DiditSdk.shared.dismiss()
}
```> [!WARNING]
>
> 認証を終了する目的で`DiditSdk.shared.isPresented = false`を設定**しないでください**。このフラグは値がfalseからtrueに切り替わったときにのみ表示をトリガーするもので、`false`に設定しても何も起こりません。同様に、最前面のビューコントローラーに対してUIKitの`dismiss(animated:)`を呼び出す方法もサポートされていません。SDKの完了処理を経由しないため、`.diditVerification`ハンドラーが一切呼び出されません。***## SDKの状態の監視SDKの状態を監視して、独自の読み込みUIを実装できます。```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)")
            }
        }
    }
}
```***## エンドツーエンドの例 (バックエンドのセッション → iOS SDK → 結果)このパターンは本番環境向けの連携方法です。バックエンドがセッションを作成し、iOSアプリが`session_token`を受け取り、SDKがフローを実行します。### 1. バックエンド: セッションを作成する```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: 交換して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. バックエンド: Webhookで最終的な判定を受け取るSDKの結果はUI上のフィードバックには便利ですが、正式な結果はWebhookで届きます。HMACによる検証については[Webhookガイド](https://docs.didit.me/ja/integration/webhooks.md)を参照してください。```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);
});
```***## 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.