A standard iOS integration looks like this:
- add the
TruliooSwift package - initialize with a shortcode
- call
sendDeviceInformation(...) - optionally provide subject reference data
- branch on accepted or failed and log the returned identifiers and
debugTrace
- public-facing product name:
Trulioo Device - Swift package product:
Trulioo - package name:
Trulioo - minimum iOS version:
15.0
The package includes the runtime components required by the public Trulioo API.
Supported iOS integrations must use the Trulioo-supported runtime contract for the current package version.
- the Trulioo iOS SDK requires the encrypted payload bundle from the runtime submit callback
- runtime paths that only expose
eventIdare unsupported eventIdremains part of the Trulioo device event model for polling and diagnostics after seed submission succeeds
Add the package:
dependencies: [
.package(url: "https://github.com/Trulioo/trulioo-ios.git", from: "X.Y.Z")
]For beta builds, depend on the prerelease tag explicitly:
dependencies: [
.package(url: "https://github.com/Trulioo/trulioo-ios.git", exact: "X.Y.Z-beta.N")
]Then link the product:
.target(
name: "YourApp",
dependencies: [
.product(name: "Trulioo", package: "Trulioo")
]
)Main entry points:
Trulioo.initialize(...)Trulioo.sendDeviceInformation(...)Trulioo.collectDeviceIntelligence(...)Trulioo.getDeviceInformation(...)Trulioo.sessionClient(...)
Important types:
Trulioo.InitializationOptionsTrulioo.InitializationResultTrulioo.DeviceInformationSendOptionsSendDeviceInformationResultDeviceIntelligencePollingOptionsDeviceSubjectReferenceDeviceSubjectOtherFieldDeviceSeedResponseDeviceEventResponseDebugTraceEntryTruliooSessionClient
iOS initialization is callback-based over async work:
Trulioo.initialize(
shortcode: shortcode,
options: Trulioo.InitializationOptions(
allowLocalDevelopment: false,
sdkVersion: "1.0.0"
),
onComplete: { result in
// Persist the result for later collection
},
onError: { error in
// Initialization failed
}
)Initialization:
- resolves the backend host from shortcode
- performs challenge and authorization
- fetches session configuration
- returns the initialization result
- remembers device-intelligence configuration when enabled
Initialization does not mean the device-intelligence flow has already run.
Trulioo.InitializationOptions supports:
allowLocalDevelopmentdeviceIntelligencePollingenableNativeDeviceDebugLogsdkVersion
Use cases:
allowLocalDevelopmentEnable only for local or emulator shortcode testing.enableNativeDeviceDebugLogUse only for intentional diagnostic sessions. Leave off in normal production integrations.sdkVersionSet this to your integration version so operational logs and support cases are easier to map.
Use fire-and-forget send as the default production integration:
let result = await Trulioo.sendDeviceInformation(
initialization: initialized,
options: Trulioo.DeviceInformationSendOptions(
reference: DeviceSubjectReference(
firstName: "Jane",
lastName: "Doe",
dateOfBirth: "1990-01-01",
phoneNumber: "+15551234567"
)
)
)sendDeviceInformation(...), collectDeviceIntelligence(...), and getDeviceInformation(...) also accept userId.
Use userId only when your downstream device-intelligence runtime expects a runtime-specific user identifier. It is not a Trulioo transaction ID replacement.
- send happens after initialization
- the public contract does not accept runtime credential overrides
referenceis subject-only- the SDK generates device basic information internally
- a failed reference call is debug-only and non-blocking
- a runtime submit that does not return the encrypted payload bundle fails before Trulioo seed submission
Use blocking collection only when debug or diagnostics need the resolved device event and normalized seed:
let result = try await Trulioo.collectDeviceIntelligence(
initialization: initialized,
polling: DeviceIntelligencePollingOptions(),
reference: DeviceSubjectReference(
firstName: "Jane",
lastName: "Doe"
)
)If debug tooling only needs the normalized device result:
Trulioo.getDeviceInformation(
initialization: initialized,
onComplete: { device in
// device is DeviceSeedResponse?
},
onError: { error in
// Collection failed
}
)iOS also exposes a post-bootstrap authorized session client.
Use this when your integration needs approved Trulioo routes after initialization, such as:
- typed authorized JSON requests
- typed authorized binary uploads
Create the session client from a successful initialization result:
let sessionClient = try Trulioo.sessionClient(
initialization: initialized,
allowedAuthorizedPaths: [
"/vendor/device/session"
]
)The zero-argument overload only enables the base SDK's default device-owned post-bootstrap routes. Feature SDKs that own additional approved routes must register them explicitly through allowedAuthorizedPaths.
Available operations:
authorizedPost(path:body:)authorizedGet(path:)authorizedPostWithoutResponse(path:body:)authorizedPostWithoutBody(path:)authorizedGetWithoutResponse(path:)authorizedUpload(path:body:contentType:headers:timeoutMilliseconds:)
Example typed authorized POST:
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
- the default helper only includes the base SDK's built-in device route allowlist
- register any extra approved routes explicitly through
allowedAuthorizedPaths - use approved relative paths only
- treat this as an advanced contract, not the default device-information integration path
Default polling:
maxAttempts = 32intervalMilliseconds = 1250
Example override:
let polling = DeviceIntelligencePollingOptions(
maxAttempts: 10,
intervalMilliseconds: 1000
)The public iOS reference type accepts subject data only:
let reference = DeviceSubjectReference(
firstName: "Jane",
lastName: "Doe",
dateOfBirth: "1990-01-01",
phoneNumber: "+15551234567",
other: [
DeviceSubjectOtherField(customKey: "middleName", value: "Ann")
]
)Do not construct or pass basic-information payloads from the app. The SDK owns those fields.
Trulioo.InitializationResult contains:
baseURLaccessTokenconfigurationdeviceEventdeviceSeeddebugTrace
Use those fields like this:
configurationConfirms what the backend enabled for the session.deviceEventSource of truth for terminal status and failure reason.deviceSeedNormalized device result for product logic and UI.debugTraceSupport and troubleshooting timeline.
Current iOS runtime metadata is derived from:
UIDeviceLocaleBundle
The authorization runtime metadata currently resolves:
- platform:
apple - manufacturer:
Apple - software: iOS version or OS string
This is SDK-owned behavior. App consumers should not need to duplicate it.
Initialization errors are delivered through the onError callback.
Send errors:
- return
SendDeviceInformationResult.failed - include a stable failure code, failed stage, message, identifiers when known, and
debugTrace
Device collection throws on failure. When troubleshooting, inspect:
- the thrown error
deviceEvent?.failureReasondebugTrace
Reference submission failures are captured in debugTrace and do not become direct user-facing collection errors by default.
Environment resolution is shortcode-driven.
| Shortcode Pattern | Environment |
|---|---|
| default | production |
.dv suffix |
development |
.pr suffix |
preview |
.local suffix or local |
local |
.emulator suffix or emulator |
emulator |
local@host:port |
local override |
emulator@host:port |
emulator override |
Supported region prefixes:
useuap/apacca
Local and emulator shortcodes are blocked unless allowLocalDevelopment is explicitly enabled.
- assuming initialization also performs collection
- trying to pass runtime credential data from app code
- coupling app-owned form data with SDK-owned basic-information fields
- treating reference failure as a full collection failure
- enabling native debug logging in normal production builds without need
If device intelligence does not run:
- Confirm initialization succeeded.
- Confirm
configuration.deviceConfiguration?.intelligenceEnabled == true. - Confirm the backend returned a device credential.
- Confirm send was explicitly invoked, or confirm the debug wait path was intentionally chosen.
- Inspect
debugTrace.
If the terminal event failed:
- inspect
deviceEvent?.failureReason - inspect processor details when present
- compare the terminal event with the
device_reference_submittrace so reference failure is not mistaken for full collection failure
When handing an iOS issue to support or engineering, capture:
- the shortcode used and whether it targeted production, development, preview, local, or emulator
- the app version, iOS version, and device model
- whether
allowLocalDevelopmentorenableNativeDeviceDebugLogwas enabled - the terminal
deviceEvent.status,failureReason, and relevant processor details - the
transactionId,eventId, and the relevantdebugTraceentries - whether subject reference data was provided and whether
device_reference_submitappeared - whether a runtime-specific
userIdwas supplied to send or debug collection
Use these principles to keep an iOS integration simple and predictable:
- initialize first
- send second
- subject data is caller-owned
- device basic information is SDK-owned
- the device event is the authoritative outcome