iOS SDK
The Kora IDV iOS SDK provides a complete verification UI — document capture, selfie, and liveness detection — built with UIKit and SwiftUI support.
Requirements
- iOS 15.5+
- Xcode 14.0+
- Swift 5.7+
Installation
CocoaPods
# Podfile
pod 'KoraIDV', '~> 1.10.15'
pod install
Quick start
1. Configure the SDK
import KoraIDV
// In your AppDelegate or app initialization
KoraIDV.configure(with: Configuration(
apiKey: "kora_xxxxx",
tenantId: "your-tenant-uuid",
environment: .sandbox
))
2. Start a verification
The SDK creates the verification for you — pass your own externalId and a tier:
KoraIDV.startVerification(
externalId: "user-\(userId)",
tier: .standard,
presenting: self
) { result in
switch result {
case .success(let verification):
let status = verification.status
let riskScore = verification.riskScore ?? 0 // 0–100
let imagePersisted = verification.imagePersisted
// Handle success
case .failure(let error):
// Handle error
print(error.localizedDescription)
case .cancelled:
// User dismissed the flow
break
}
}
VerificationTier accepts: .basic, .standard, .enhanced. (See tier table.)
Verification tiers
| Tier | Includes |
|---|---|
.basic | Document OCR + basic authenticity |
.standard | + Face match + active liveness |
.enhanced | + Anti-spoof + risk signals + compliance screening (sanctions / PEP / adverse media) |
Resume an existing verification
If you have a verificationId from a webhook or previous attempt:
KoraIDV.resumeVerification(
verificationId: existingVerificationId,
presenting: self
) { result in
// Handle result
}
Configuration options
| Parameter | Type | Default | Description |
|---|---|---|---|
apiKey | String | Required | Your API key (kora_… for sandbox, kora_… for production) |
tenantId | String | Required | Your tenant UUID |
environment | APIEnvironment | .sandbox | .sandbox or .production (auto-detected from API key prefix; explicit setting overrides) |
baseURL | URL? | nil | Override base URL (for on-premise deployments) |
theme | KoraTheme | Defaults | Custom theme colors and styling |
livenessMode | LivenessMode | .active | .active (challenges) or .passive (auto-detect) |
timeout | TimeInterval | 600 | Network request timeout in seconds |
debugLogging | Bool | false | Verbose logs |
Theme customization
let theme = KoraTheme(
primaryColor: Color(hex: "#2563EB"),
backgroundColor: Color(hex: "#FFFFFF"),
textColor: Color(hex: "#1F2937"),
errorColor: Color(hex: "#DC2626"),
cornerRadius: 12,
buttonHeight: 48
)
KoraIDV.configure(with: Configuration(
apiKey: "kora_your_api_key",
tenantId: "your-tenant-uuid",
theme: theme
))
Customizing text & copy
All user-facing text in the SDK — including the intro/consent screen ("Verify your identity") — is loaded through the SDK's localization keys. To rebrand any of it, add the same key to a KoraIDVOverrides.strings file in your own app. The SDK reads this dedicated table first and falls back to its bundled default for anything you don't override — no fork required. (A dedicated filename, rather than your app's Localizable.strings, avoids a CocoaPods resource collision in which the SDK's bundled strings would otherwise take precedence.)
// YourApp/KoraIDVOverrides.strings (en)
"koraidv.consent.title" = "Verify your identity with Acme Bank";
"koraidv.consent.description" = "To keep your account secure and meet regulatory requirements, we need to confirm it's really you.";
"koraidv.consent.item.id.subtitle" = "Your passport, or the front & back of your ID card";
"koraidv.consent.item.selfie.subtitle" = "A quick selfie to match your ID";
"koraidv.consent.item.liveness.subtitle" = "A short video to confirm you're present";
"koraidv.consent.button" = "Continue";
Every SDK key is namespaced under koraidv., so overrides never collide with your own strings. Common consent-screen keys:
| Key | Default |
|---|---|
koraidv.consent.title | Verify your identity |
koraidv.consent.description | We need to verify your identity to comply with regulations and keep your account secure. |
koraidv.consent.item.id.title / .subtitle | Government-issued ID / Photo of your passport or front & back of your ID |
koraidv.consent.item.selfie.title / .subtitle | Selfie photo / A quick selfie to match your ID |
koraidv.consent.item.liveness.title / .subtitle | Liveness check / Quick video to confirm it's really you |
koraidv.consent.item.eyewear.title / .subtitle | Remove sunglasses / Your eyes must be clearly visible… |
koraidv.consent.button | Get started |
koraidv.consent.privacy | By continuing, you agree to our Privacy Policy… |
Result-screen keys (koraidv.result.approved.title, koraidv.result.rejected.subtitle, etc.) are overridable the same way.
Localization. Add the same keys under each locale in your app (e.g. an fr KoraIDVOverrides.strings); the SDK ships English and French and honours your locale variants. The verification language follows Configuration.locale.
Host-app copy override on iOS is available from KoraIDV iOS 1.10.15. On earlier versions, theme colors are customizable but copy is not.
Error handling
case .failure(let error):
switch error.code {
case .networkError:
// Check internet connection
showRetryAlert(message: error.message)
case .cameraAccessDenied:
// Prompt user to enable camera in Settings
openSettings()
case .sessionExpired:
// Create a new verification on your server
createNewVerification()
case .userCancelled:
// User dismissed the verification
break
}
| Error Code | Description | Recovery |
|---|---|---|
.networkError | Network request failed | Check connection, retry |
.cameraAccessDenied | Camera permission not granted | Open Settings, request permission |
.sessionExpired | Verification session timed out | Create a new verification |
.userCancelled | User dismissed the UI | Prompt to try again |
Privacy permissions
Add to your Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required to capture your identity document and selfie for verification.</string>
Troubleshooting
Environment naming conflict
If you have another Environment type in your project, use the fully qualified name:
KoraIDV.configure(with: Configuration(
apiKey: "kora_your_api_key",
tenantId: "your-tenant-uuid",
environment: KoraIDV.APIEnvironment.sandbox
))
Deployment target mismatch
Ensure your project's minimum deployment target is iOS 15.5 or higher. In Xcode: Project → General → Minimum Deployments.
CocoaPods cache issues
pod cache clean KoraIDV --all
pod deintegrate
pod install
Flutter bridge
If your iOS host is part of a Flutter app:
// In your AppDelegate
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(
name: "com.yourapp/koraidv",
binaryMessenger: controller.binaryMessenger
)
channel.setMethodCallHandler { call, result in
if call.method == "startVerification" {
let args = call.arguments as! [String: Any]
let verificationId = args["verificationId"] as! String
KoraIDV.startVerification(
verificationId: verificationId,
presenting: controller
) { verificationResult in
switch verificationResult {
case .success(let v):
result(["status": v.status.rawValue, "riskScore": v.riskScore ?? NSNull()])
case .failure(let error):
result(FlutterError(
code: "VERIFICATION_ERROR",
message: error.message,
details: nil
))
}
}
}
}