Trulioo SDK - iOS Guide

The Trulioo iOS SDK lets you add identity verification to your iOS application. A standard integration collects device intelligence, optionally submits KYC subject data, and returns a terminal result you can act on.

Quick Start

Add the Trulioo Swift package to your project, then import it:

import Trulioo

A standard integration looks like this:

  1. Get a shortcode from your backend for the active transaction.
  2. Call Trulioo.initialize(shortcode:...).
  3. Call Trulioo.sendDeviceInformation(...).
  4. Optionally include subject reference data (name, date of birth, etc.).
  5. Branch on accepted or failed and log the returned identifiers and debugTrace.

What This SDK Covers

The base Trulioo iOS SDK provides three verification flows:

  • Device Intelligence — via sendDeviceInformation(...), collectDeviceIntelligence(...), and getDeviceInformation(...)
  • KYC Data verification — via verifyData(...)
  • eID verification — via listEidProviders(...), prepareEid(...), and verifyEid(...)

Package and Compatibility

PropertyValue
Swift package productTrulioo
Minimum iOS version15.0
DistributionSwift Package Manager

Installation

Add the package to your Package.swift:

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

For beta builds, pin to the prerelease tag explicitly:

dependencies: [
    .package(url: "https://github.com/Trulioo/trulioo-ios.git", exact: "X.Y.Z-beta.N")
]

Then link the product to your target:

.target(
    name: "YourApp",
    dependencies: [
        .product(name: "Trulioo", package: "Trulioo")
    ]
)

Initialization

Call Trulioo.initialize(...) before any other SDK operation. Initialization resolves the session, authorizes it against Trulioo APIs, and fetches the configuration for your transaction.

Trulioo.initialize(
    shortcode: shortcode,
    options: Trulioo.InitializationOptions(
        allowLocalDevelopment: false,
        sdkVersion: "1.0.0"
    ),
    onComplete: { result in
        // Persist result for later use
    },
    onError: { error in
        // Initialization failed — no product operations can proceed
    }
)

Initialization options (Trulioo.InitializationOptions):

OptionDescription
allowLocalDevelopmentEnables local or emulator shortcode testing. Blocked by default.
deviceIntelligencePollingOverride default polling settings for debug collection.
enableNativeDeviceDebugLogEnables diagnostic logging. Use only for intentional debug sessions, not production.
sdkVersionYour integration's version string. Helps map logs and support cases.

Device Intelligence

Use Device Intelligence to collect device-risk telemetry from the current app session.

Standard Integration (Recommended)

For most integrations, use sendDeviceInformation(...). This submits the device event and returns a terminal result.

Trulioo.initialize(
    shortcode: shortcode,
    options: Trulioo.InitializationOptions(
        allowLocalDevelopment: false,
        sdkVersion: "1.0.0"
    ),
    onComplete: { initialized in
        Task {
            let result = await Trulioo.sendDeviceInformation(
                initialization: initialized,
                options: Trulioo.DeviceInformationSendOptions(
                    reference: DeviceSubjectReference(
                        firstName: "Jane",
                        lastName: "Doe",
                        dateOfBirth: "1990-01-01"
                    )
                )
            )

            switch result {
            case .accepted(let accepted):
                print("device accepted", accepted.transactionId, accepted.eventId)
            case .failed(let failed):
                print("device failed", failed.error.code, failed.error.stage, failed.debugTrace)
            }
        }
    },
    onError: { error in
        print(error)
    }
)

Debug Integration

Use collectDeviceIntelligence(...) only when you need the resolved device event and normalized seed for diagnostics.

let debugResult = try await Trulioo.collectDeviceIntelligence(
    initialization: initialized,
    polling: DeviceIntelligencePollingOptions(),
    reference: DeviceSubjectReference(
        firstName: "Jane",
        lastName: "Doe"
    )
)

print(debugResult.deviceEvent)
print(debugResult.deviceSeed)

Callback-Only (Normalized Seed)

If you only need the normalized device result in a callback:

Trulioo.getDeviceInformation(
    initialization: initialized,
    onComplete: { device in
        // device is DeviceSeedResponse?
    },
    onError: { error in
        // Collection failed
    }
)

Key behaviors to know:

  • sendDeviceInformation(...) is the standard production path.
  • collectDeviceIntelligence(...) is a blocking debug path — do not use it in production unless you specifically need the terminal event.
  • reference is caller-supplied subject data only. The SDK generates device basic information internally — do not attempt to pass those fields yourself.
  • A failed reference submission is recorded in debugTrace but does not fail the device event.
  • Initialization and device collection are separate — your app controls when collection runs.

Note: sendDeviceInformation(...), collectDeviceIntelligence(...), and getDeviceInformation(...) also accept a userId field. Use this only when your downstream device-intelligence runtime expects a runtime-specific user identifier. It is not a replacement for the Trulioo transaction ID.

Default polling settings:

SettingDefault
maxAttempts32
intervalMilliseconds1250ms

To override:

let polling = DeviceIntelligencePollingOptions(
    maxAttempts: 10,
    intervalMilliseconds: 1000
)

KYC Data Verification

Use verifyData(...) when your flow has subject data and needs a terminal KYC verification result from the same initialized session.

Trulioo.initialize(
    shortcode: shortcode,
    options: Trulioo.InitializationOptions(),
    onComplete: { _ in
        Task {
            Trulioo.dataStateHandler = { state in
                print("dataState", state)
            }

            let result = try await Trulioo.verifyData(
                config: DataVerificationConfig(
                    personInfo: PersonInfo(
                        firstName: "Jane",
                        lastName: "Doe",
                        dateOfBirth: "1990-01-01"
                    ),
                    location: Location(
                        buildingNumber: "123",
                        streetName: "Example",
                        streetType: "Ave",
                        city: "Exampleville",
                        stateProvinceCode: "BC",
                        postalCode: "V0V0V0"
                    ),
                    communication: Communication(
                        emailAddress: "[email protected]",
                        mobileNumber: "+12025550123"
                    ),
                    countryCode: "CA"
                )
            )

            if result.outcome == .accept && result.recordMatch {
                print("data verified", result.transactionId)
            } else {
                print("review path", result)
            }
        }
    },
    onError: { error in
        print(error)
    }
)

Key behaviors to know:

  • verifyData(...) reuses the internally stored initialized session — you do not pass initialized to it directly.
  • The SDK submits PII but does not return PII in DataVerificationResult.
  • Trulioo.dataStateHandler lets your app observe state transitions during verification.
  • Trulioo.resetData() cancels or clears the current data flow if you need to restart it.

eID Verification

Use the eID entrypoints when your flow needs an interactive, provider-backed identity verification from the same initialized session.

Trulioo.initialize(
    shortcode: shortcode,
    options: Trulioo.InitializationOptions(),
    onComplete: { _ in
        Task {
            // Optional: inspect licensed providers before launch
            let providers = try await Trulioo.listEidProviders(countryCode: "SE")
            print("providers", providers.map(\.name))

            // Pre-warm when the eID screen becomes visible
            try await Trulioo.prepareEid(
                config: EidVerificationConfig(
                    countryCode: "SE",
                    callbackScheme: "com.example.app"
                )
            )

            // Launch the interactive provider flow
            let result = try await Trulioo.verifyEid(
                config: EidVerificationConfig(
                    countryCode: "SE",
                    callbackScheme: "com.example.app"
                )
            )

            if result.outcome == .success && result.match {
                print("eID verified", result.transactionId)
            } else {
                print("eID not verified", result)
            }
        }
    },
    onError: { error in
        print(error)
    }
)

Key behaviors to know:

  • listEidProviders(...) is optional — use it to inspect licensed providers for a country before launch.
  • prepareEid(...) pre-warms the eID screen. Call it when the eID screen becomes visible.
  • verifyEid(...) launches the interactive provider flow and waits for a terminal result.
  • Set a unique callbackScheme for your app — this is required for customer-app SDK integrations.
  • callbackHost is optional and should only be overridden when your environment requires a non-default callback host.
  • Trulioo.resetEid() clears interrupted eID state before a restart.

Advanced: Authorized Session Client

After initialization, you can access approved Trulioo routes directly using Trulioo.sessionClient(...). Use this for typed authorized requests or binary uploads.

let sessionClient = try Trulioo.sessionClient(
    initialization: initialized,
    allowedAuthorizedPaths: [
        "/vendor/device/session"
    ]
)

Available operations:

MethodDescription
authorizedPost(path:body:)Typed authorized POST
authorizedGet(path:)Typed authorized GET
authorizedPostWithoutResponse(path:body:)POST with no response body
authorizedPostWithoutBody(path:)POST with no request body
authorizedGetWithoutResponse(path:)GET with no response body
authorizedUpload(path:body:contentType:headers:timeoutMilliseconds:)Binary upload

Typed POST example:

struct StatusRequest: Encodable {
    let transactionId: String
}

struct StatusResponse: Decodable {
    let status: String
}

let status: StatusResponse = try await sessionClient.authorizedPost(
    path: "/vendor/device/session",
    body: StatusRequest(transactionId: "txn-123")
)

Rules:

  • Initialize first and reuse the returned session result.
  • Register any routes beyond the base SDK defaults explicitly via allowedAuthorizedPaths.
  • Use approved relative paths only.
  • This is an advanced contract. For standard device intelligence, use sendDeviceInformation(...).

Subject Reference Data

Pass caller-owned subject data using DeviceSubjectReference:

let reference = DeviceSubjectReference(
    firstName: "Jane",
    lastName: "Doe",
    dateOfBirth: "1990-01-01",
    phoneNumber: "+15551234567",
    other: [
        DeviceSubjectOtherField(customKey: "middleName", value: "Ann")
    ]
)

Do not pass device basic-information fields from your application. The SDK generates those internally.


Results

Trulioo.InitializationResult contains:

FieldUse
configurationConfirm backend enablement flags for the session
deviceEventSource of truth for terminal device status and failure reason
deviceSeedNormalized device result
debugTraceDiagnostic timeline for support
baseURLResolved environment base URL
accessTokenSession access token (managed by the SDK)

Error Handling

Failure typeBehavior
Initialization failureDelivered through the onError callback
Send failureReturns SendDeviceInformationResult.failed with a stable code, stage, message, and debugTrace
Collection failureThrows — inspect the thrown error, deviceEvent?.failureReason, and debugTrace
Reference submission failureRecorded in debugTrace; does not surface as a direct collection error

Environments and Shortcodes

Environment is resolved from the shortcode — you do not set it manually.

Shortcode patternEnvironment
defaultProduction
.dv suffixDevelopment
.pr suffixPreview
.local suffix or localLocal
.emulator suffix or emulatorEmulator
local@host:portLocal override
emulator@host:portEmulator override

Supported region prefixes: us, eu, ap / apac, ca

Local and emulator shortcodes are blocked unless allowLocalDevelopment: true is set in initialization options.


Common Mistakes

Assuming initialization also runs device collection. Initialization and collection are separate steps. You must explicitly call sendDeviceInformation(...) after initialization completes.

Passing device basic-information from your app. The SDK generates these fields internally. Supplying them yourself will cause a failure before seed submission.

Treating reference failure as a terminal collection failure. A failed subject reference submission is recorded in debugTrace but does not fail the device event. Check both separately.

Enabling native debug logging in production. enableNativeDeviceDebugLog is for intentional diagnostic sessions only. Leave it off in normal production builds.

Using local shortcodes without enabling local development. Local and emulator shortcodes are blocked by default. Set allowLocalDevelopment: true explicitly.


Troubleshooting

Device intelligence is not running:

  1. Confirm initialization succeeded.
  2. Confirm configuration.deviceConfiguration?.intelligenceEnabled == true.
  3. Confirm the backend returned a device credential.
  4. Confirm sendDeviceInformation(...) was explicitly called after initialization.
  5. Inspect debugTrace.

Terminal event failed:

  • Inspect deviceEvent?.failureReason.
  • Inspect processor details when present.
  • Compare the terminal event against device_reference_submit in debugTrace — reference failure is not the same as full collection failure.

Diagnostic Checklist

When filing a support issue, include:

  • The shortcode environment (production, development, preview, local, or emulator).
  • App version, iOS version, and device model.
  • Whether allowLocalDevelopment or enableNativeDeviceDebugLog was enabled.
  • The terminal deviceEvent.status, failureReason, and relevant processor details.
  • transactionId, eventId, and relevant debugTrace entries.
  • Whether subject reference data was provided and whether device_reference_submit appears in debugTrace.
  • Whether a userId was supplied to send or debug collection.

Public API Reference

Main entry points:

Trulioo.initialize(...) · Trulioo.sendDeviceInformation(...) · Trulioo.collectDeviceIntelligence(...) · Trulioo.getDeviceInformation(...) · Trulioo.verifyData(...) · Trulioo.listEidProviders(...) · Trulioo.prepareEid(...) · Trulioo.verifyEid(...) · Trulioo.sessionClient(...)

Key types:

Trulioo.InitializationOptions · Trulioo.InitializationResult · Trulioo.DeviceInformationSendOptions · SendDeviceInformationResult · DeviceIntelligencePollingOptions · DeviceSubjectReference · DeviceSubjectOtherField · DeviceSeedResponse · DeviceEventResponse · DebugTraceEntry · TruliooSessionClient