Skip to main content

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.8'
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

TierIncludes
.basicDocument 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

ParameterTypeDefaultDescription
apiKeyStringRequiredYour API key (kora_… for sandbox, kora_… for production)
tenantIdStringRequiredYour tenant UUID
environmentAPIEnvironment.sandbox.sandbox or .production (auto-detected from API key prefix; explicit setting overrides)
baseURLURL?nilOverride base URL (for on-premise deployments)
themeKoraThemeDefaultsCustom theme colors and styling
livenessModeLivenessMode.active.active (challenges) or .passive (auto-detect)
timeoutTimeInterval600Network request timeout in seconds
debugLoggingBoolfalseVerbose 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
))

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 CodeDescriptionRecovery
.networkErrorNetwork request failedCheck connection, retry
.cameraAccessDeniedCamera permission not grantedOpen Settings, request permission
.sessionExpiredVerification session timed outCreate a new verification
.userCancelledUser dismissed the UIPrompt 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
))
}
}
}
}