Trulioo KYC Documents SDK — iOS
The KYC Documents SDK delivers a complete, Trulioo-designed document verification UI for iOS. The SDK owns the full capture experience — your application initializes it with a shortcode, launches the hosted flow, and handles the terminal callback.
Need full UI control? If you want to design your own capture experience, see the KYC Documents Capture iOS SDK instead.
Biometric Data Notice
Some US states impose obligations on businesses that collect biometric identifiers or biometric information, which may include facial scan data extracted during a document verification transaction. One such law is the Illinois Biometric Information Privacy Act (BIPA). Businesses subject to BIPA must inform individuals of the purpose of data collection and obtain their consent before proceeding.
Trulioo requires a notice and consent mechanism for all document verification transactions. Customers using our API must confirm via API whether an individual is located in the United States and has consented in the prescribed manner. We strongly encourage all customers to consult with legal counsel to ensure their own compliance.
For more information, refer to our Service Specific Terms for Document Verification.
Quick Start
- Add the
TruliooKYCDocumentsSwift package to your project. - Create a
Truliooinstance. - Get a shortcode from your backend for the active transaction.
- Call
trulioo.initialize(shortcode:completion:)and wait for.authorized. - Launch the hosted flow with
trulioo.launch(callbacks:)(SwiftUI) ortrulioo.launchController(callbacks:)(UIKit). - Handle the
onCompleteandonErrorcallbacks. - Call
trulioo.reset()when the flow is done.
What This SDK Covers
The SDK owns the full document verification experience. Your application owns initialization, launch timing, and the terminal result.
| Your application owns | The SDK owns |
|---|---|
| The shortcode | Authorization of the active Docs transaction |
| SwiftUI or UIKit presentation state | Hosted document and selfie capture UI |
| Completion, error, retry, and navigation behavior | Transaction-scoped selection and capture rules |
Deciding when to call reset() | Hosted-flow completion and structured error callbacks |
Package and Compatibility
| Property | Value |
|---|---|
| GitHub repository | https://github.com/Trulioo/kyc-documents.git |
| Swift package product | TruliooKYCDocuments |
| Minimum iOS version | 15.0 |
| Distribution | Swift Package Manager |
The package includes the hosted KYC Docs UI flow for iPhone and resolves its Trulioo and TruliooKYCDocumentsCapture dependencies through the package release metadata.
Installation
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/Trulioo/kyc-documents.git", from: "X.Y.Z")
]For beta builds, pin to the prerelease tag explicitly:
dependencies: [
.package(url: "https://github.com/Trulioo/kyc-documents.git", exact: "X.Y.Z-beta.N")
]Link the product to your target:
.target(
name: "YourApp",
dependencies: [
.product(name: "TruliooKYCDocuments", package: "kyc-documents")
]
)Then import the module:
import TruliooKYCDocumentsSwiftUI Integration Example
import SwiftUI
import TruliooKYCDocuments
struct HostedDocsView: View {
@State private var trulioo = Trulioo()
@State private var isLaunching = false
@State private var transactionId: String?
@State private var errorMessage: String?
let shortcode: String
var body: some View {
Group {
if isLaunching {
trulioo.launch(
callbacks: TruliooCallbacks(
onComplete: { value in
transactionId = value
isLaunching = false
trulioo.reset()
},
onError: { result in
if case let .error(message, _, _, _) = result {
errorMessage = message
} else {
errorMessage = String(describing: result)
}
isLaunching = false
trulioo.reset()
}
)
)
.ignoresSafeArea()
} else {
VStack(spacing: 16) {
Button("Start verification") {
trulioo.initialize(shortcode: shortcode) { result in
switch result {
case .authorized(let transactionId):
self.transactionId = transactionId
self.isLaunching = true
case .error(let message, _, _, _):
self.errorMessage = message
case .complete:
self.errorMessage = "Unexpected completion during initialize."
}
}
}
if let transactionId {
Text("Initialized transaction: \(transactionId)")
}
if let errorMessage {
Text(errorMessage)
}
}
}
}
}
}UIKit Integration Example
import TruliooKYCDocuments
import UIKit
final class DocsHostViewController: UIViewController {
private let trulioo = Trulioo()
func startVerification(shortcode: String) {
trulioo.initialize(shortcode: shortcode) { [weak self] result in
guard let self else { return }
switch result {
case .authorized:
let controller = self.trulioo.launchController(
callbacks: TruliooCallbacks(
onComplete: { _ in
self.dismiss(animated: true)
self.trulioo.reset()
},
onError: { _ in
self.dismiss(animated: true)
self.trulioo.reset()
}
)
)
controller.modalPresentationStyle = .fullScreen
self.present(controller, animated: true)
case .error(let message, _, _, _):
print("Initialize failed:", message)
case .complete:
print("Unexpected completion during initialize.")
}
}
}
}How the Launch Flow Works
- Create a
Truliooinstance. - Call
initialize(shortcode:completion:)— this authorizes the transaction and loads configuration. - Wait for
.authorized(transactionId:)before proceeding. - Call
launch(callbacks:)(SwiftUI) orlaunchController(callbacks:)(UIKit). - The SDK runs the hosted document and selfie capture experience.
- Wait for
onCompleteoronError. - Call
reset().
Do not call launch(...) or launchController(...) before initialization returns .authorized. The host application does not manage camera rendering — the hosted flow owns that UI internally.
Handling Results
Use TruliooCallbacks to react to the launched flow:
let callbacks = TruliooCallbacks(
onComplete: { transactionId in
// Terminal success
print("Completed transaction:", transactionId ?? "missing")
},
onError: { result in
// Structured product error
print("Hosted flow error:", result)
}
)Result types:
| Result | When it is returned |
|---|---|
TruliooResult.authorized(transactionId:) | Initialization succeeded — the flow is ready to launch |
TruliooResult.complete(transactionId:) | The hosted flow completed successfully |
TruliooResult.error(message:details:code:transactionId:) | The hosted flow ended with a structured product error |
Call reset() after either onComplete or onError once your application is done with the transaction.
Desktop-to-Mobile
The iOS Docs SDK supports desktop-to-mobile flows when the transaction is configured for cross-device handoff. In this flow, the user starts on desktop, scans a QR code with their iPhone, and the hosted Docs flow continues the document and selfie steps on the mobile device.
Desktop-to-mobile behavior is configured through the Trulioo transaction, not through a separate iOS SDK flag.
Customization
The hosted Docs SDK does not accept host-side theme or locale objects through the public iOS launch surface. These behaviors are controlled by the transaction configuration associated with the shortcode:
- Locale and branding
- Available countries and document types
- Capture-step requirements
- Desktop-to-mobile enablement
To change these behaviors, update the transaction configuration in the Trulioo customer handoff flow.
Common Mistakes
Calling launch(...) before initialization returns .authorized. Always wait for the .authorized result before presenting the hosted flow.
Not calling reset() after the flow completes or fails. Call reset() in both onComplete and onError before starting a new transaction.
Expecting to render Capture cameras directly. The Docs SDK owns the hosted capture UI. If you need to compose your own camera UI, use the KYC Documents Capture iOS SDK instead.
Presenting the UIKit controller before initialization completes. Only call launchController(callbacks:) inside the .authorized case of the initialization callback.
Troubleshooting
Initialization fails immediately: Verify the shortcode is valid and belongs to the expected environment.
The hosted UI does not appear: Confirm launch(...) or launchController(...) is only called after initialization returns .authorized.
The flow completes but the host screen does not update: Handle onComplete and dismiss or swap screens in your application — the SDK does not navigate for you.
The flow returns an error: Log the message, code, and transactionId from the error result before deciding whether to retry.
Diagnostic Checklist
When filing a support issue, include:
- Docs SDK version.
- iPhone model and iOS version.
- The shortcode environment used (production, development, preview).
- Whether the host used SwiftUI or UIKit launch.
- Whether the flow was pure mobile or desktop-to-mobile.
- Whether initialization reached
.authorized(transactionId:). - The final callback result and transaction ID, if available.
- Whether
reset()was called before retrying the transaction.

