Migration Guide: DocV iOS 2.x to KYC Documents iOS

This guide covers everything you need to update when migrating from the legacy DocV iOS 2.x SDK to the current Trulioo KYC Documents iOS SDK.

Use this guide if your integration uses any of the following :

  • pod 'TruliooDocV' as your CocoaPods dependency
  • import TruliooSDK
  • TruliooDelegate for lifecycle callbacks
  • TruliooWorkflow to configure the launch
  • Trulioo().initialize(delegate:workflow:) or Trulioo().launch(delegate:)

What's Changed: At a Glance

Area2.xCurrent
DistributionCocoaPods TruliooDocV)Swift Package Manager TruliooKYCDocuments)
Importimport TruliooSDKimport TruliooKYCDocuments
Lifecycle modelDelegate-based TruliooDelegate)Explicit initialize-then-launch with callbacks
Launch configurationTruliooWorkflow objectShortcode string only
Theme and localeSet in TruliooWorkflowSet in backend transaction configuration
Initializationinitialize(delegate:workflow:)initialize(shortcode:completion:)
Launch (UIKit)launch(delegate:)launchController(callbacks:)
Launch (SwiftUI)Not availablelaunch(callbacks:)
Result modelonComplete, onError, onExceptionTruliooCallbacks with onComplete and onError

Before You Start

The 3.x SDK drops CocoaPods entirely in favor of Swift Package Manager. If your project still uses CocoaPods for other dependencies, you can mix SPM and CocoaPods in the same project — but the Trulioo SDK itself must be added through SPM.

Step 1: replace the Dependency


Remove the CocoaPods dependency and add the Swift package instead.

Remove from your Podfile:

pod 'TruliooDocV'

Add to your Package.swift :

dependencies: [
    .package(url: "https://github.com/Trulioo/kyc-documents.git", from: "X.Y.Z")
]

For beta builds, pin 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")
    ]
)

Update your import:

// Before
import TruliooSDK

// After
import TruliooKYCDocuments

Step 2: Remove TruliooDelegate

The delegate-based lifecycle has been removed. Delete your TruliooDelegate conformance and all delegate methods:

// Remove all of this
final class YourViewController: UIViewController, TruliooDelegate {
    func onInitialized() { ... }
    func onComplete(result: TruliooSuccess) { ... }
    func onError(error: TruliooError) { ... }
    func onException(exception: TruliooException) { ... }
}

Callbacks are now passed directly to launch(callbacks:) or launchController(callbacks:) using TruliooCallbacks. See Step 4.

Step 3: Remove TruliooWorkflow

TruliooWorkflow and TruliooWorkflowTheme have been removed from the public iOS contract. Delete any usage of these in your host app:

// Remove this entirely
let workflow = TruliooWorkflow(
    shortcode: shortcode,
    locale: "en-US",
    isDemoMode: false,
    enableRegionSelection: true,
    enableDocumentAutoCapture: true,
)

Settings that were previously passed through TruliooWorkflow — locale, theme, region selection, capture behavior — are now resolved from the transaction configuration on your backend. Move these settings to the backend flow that generates the shortcode.

Note on locale: The current SDK resolves locale from device settings or transaction configuration. Remove any host-side locale injection and rely on the current SDK-controlled behavior.

Step 4: Update the Launch Contract


Replace the old delegate-based initialize and launch pattern with the explicit initialize-then-launch flow.


UIKit

// Before
import TruliooSDK

final class YourViewController: UIViewController, TruliooDelegate {
    func start(shortcode: String) {
        let workflow = TruliooWorkflow(shortcode: shortcode, locale: "en-US")
        Trulioo().initialize(delegate: self, workflow: workflow)
    }

    func onInitialized() {
        Trulioo().launch(delegate: self)
    }

    func onComplete(result: TruliooSuccess) { print(result.transactionId) }
    func onError(error: TruliooError) { print(error.message) }
    func onException(exception: TruliooException) { print(exception.message) }
}

// After
import TruliooKYCDocuments

final class DocsHostViewController: UIViewController {
    private let trulioo = Trulioo()

    func start(shortcode: String) {
        trulioo.initialize(shortcode: shortcode) { [weak self] result in
            guard let self else { return }
            guard case .authorized = result else {
                print("Initialization failed:", result)
                return
            }

            let controller = self.trulioo.launchController(
                callbacks: TruliooCallbacks(
                    onComplete: { [weak self] _ in
                        self?.dismiss(animated: true)
                        self?.trulioo.reset()
                    },
                    onError: { [weak self] error in
                        print("Hosted flow error:", error)
                        self?.dismiss(animated: true)
                        self?.trulioo.reset()
                    }
                )
            )

            self.present(controller, animated: true)
        }
    }
}

SwiftUI
SwiftUI launch is new in 3.x — there was no equivalent in 2.x. Use launch(callbacks:) after initialization returns .authorized

import SwiftUI
import TruliooKYCDocuments

struct HostedDocsView: View {
    @State private var trulioo = Trulioo()
    @State private var isAuthorized = false

    let shortcode: String

    var body: some View {
        Group {
            if isAuthorized {
                trulioo.launch(
                    callbacks: TruliooCallbacks(
                        onComplete: { _ in
                            isAuthorized = false
                            trulioo.reset()
                        },
                        onError: { _ in
                            isAuthorized = false
                            trulioo.reset()
                        }
                    )
                )
                .ignoresSafeArea()
            } else {
                Button("Start verification") {
                    trulioo.initialize(shortcode: shortcode) { result in
                        if case .authorized = result {
                            isAuthorized = true
                        }
                    }
                }
            }
        }
    }
}

Step 5: Update Result Handling


Replace the legacy delegate callback methods with TruliooCallbacks

// Before (delegate methods)
func onComplete(result: TruliooSuccess) { ... }
func onError(error: TruliooError) { ... }
func onException(exception: TruliooException) { ... }

// After (TruliooCallbacks)
let callbacks = TruliooCallbacks(
    onComplete: { transactionId in
        print("Completed:", transactionId ?? "missing")
    },
    onError: { result in
        print("Error:", result)
    }
)

Key Differences:

  • onInitialized() is replaced by waiting for .authorized(transactionId:) in the initialization completion
  • .onException has no direct equivalent — unexpected termination is handled through onError.
  • Call reset() after both onComplete and onError before starting a new transaction.

Current Result Types

ResultWhen it is returned
TruliooResult.authorized(transactionId:)Initialization succeeded — ready to launch
TruliooResult.complete(transactionId:)Hosted flow completed successfully
TruliooResult.error(message:details:code:transactionId:)Hosted flow ended with a structured error

Step 6: Review Host-Side Options (Optional)

The current SDK exposes a much narrower set of host-side options than 2.x. The only public launch option is TruliooLaunchOptions, which lets you skip the intro consent screen:

// UIKit
let controller = trulioo.launchController(
    options: TruliooLaunchOptions(skipIntroConsent: true),
    callbacks: callbacks
)

// SwiftUI
let view = trulioo.launch(
    options: TruliooLaunchOptions(skipIntroConsent: true),
    callbacks: callbacks
)

This is not a replacement for TruliooWorkflow. All other configuration belongs in the backend transaction.


Migration Checklist

  • Remove pod TruliooDocVfrom your Podfile.
  • Add the TruliooKYCDocuments Swift package from https://github.com/Trulioo/kyc-documents.git.
  • Replace import TruliooSDK with import TruliooKYCDocuments.
  • Remove TruliooDelegate conformance and all delegate method implementations.
  • Delete all TruliooWorkflow and TruliooWorkflowTheme usage from the host app.
  • Move theme, locale, demo mode, and region/capture settings to backend transaction configuration.
  • Replace initialize(delegate:workflow:) with initialize(shortcode:completion:).
  • Replace launch(delegate:) with launchController(callbacks:) (UIKit) or launch(callbacks:) (SwiftUI).
  • Update result handling to use TruliooCallbacks with onComplete and onError.
  • Call reset() after both onComplete and onError before starting a new transaction.
  • Review whether TruliooLaunchOptions(skipIntroConsent: true) is needed for your flow.