iOS SDK
Integrate the TrustPlatform iOS SDK into your iOS app
This page covers the iOS setup. For what the SDK does and how it fits into your integration, see the Mobile SDK overview.
Requirements
| Requirement | Minimum version |
|---|---|
| iOS | 15.0 |
| Swift | 6.0 |
These are the Trust Platform SDK's requirements. If you add native document verification, the DocIDV SDK's requirements also apply.
Installation
- In Xcode, select File > Add Package Dependencies…
- Paste the repository URL:
https://github.com/idnow/trustplatform-sdk-ios
- Click Add Package (We recommend setting the version rule to Up to Next Major Version).
- In the package product selection sheet, add TrustPlatform to your app target. Click Add Package.
Configure Your App
Check which device capabilities your flow needs, then add the matching keys to your Info.plist file. iOS shows each usage description to the user when the app first asks for access, so explain the real reason.
| Key | Type | Notes |
|---|---|---|
Privacy - Camera Usage Description | string | Required for document and biometric capture |
Privacy - Microphone Usage Description | string | Required for video-based verification steps, such as agent video calls |
Privacy - NFC Scan Usage Description | string | Required for NFC chip reading. See native document verification |
Configure the SDK
Call IDnowTrustPlatform.configure(environment:) once at app startup, before you create a session.
// AppDelegate.application(_:didFinishLaunchingWithOptions:)
// or your @main struct init:
IDnowTrustPlatform.configure(environment: .production)
| Environment | Description |
|---|---|
.production | The production environment |
.sandbox | The sandbox environment for development and testing (default) |
Start a Session
- Create a new session via the /sessions API.
- Use the session token to initialize a new
TPSessioninstance. - Call
run(from:)with an event handler.
func startVerification(from viewController: UIViewController) async {
let session = TPSession(token: sessionToken)
await session.run(from: viewController) { event in
switch event {
case .progress:
break // See Follow progress below.
case .completed:
// The flow completed. Query your backend for the outcome.
// See https://docs.eu.platform.idnow.io/docs/integration/get-session-results
break
case .aborted:
// The session was aborted on the server.
break
case .failed(let error):
// Show error.errorDescription. See Handle Errors below.
break
@unknown default:
break
}
}
// The SDK is off screen.
}
run(from:) is async and returns once the SDK is off screen. That happens when:
- the flow ends and the SDK dismisses itself. With
dismissOnFinishset tofalse, it happens when the user closes the SDK instead. - your app calls
session.stop()or cancels the task that awaitsrun(from:). See Close the SDK early.
Session details reach you through the event handler, which runs on the main actor.
Session Options
To configure a session, pass a TPSessionOptions value when you create it. Options are fixed when the session is created.
let session = TPSession(
token: sessionToken,
options: TPSessionOptions(dismissOnFinish: false)
)
| Option | Default | Description |
|---|---|---|
dismissOnFinish | true | When true, the SDK dismisses the flow as soon as it ends, whether it completed, was aborted, or failed. When false, the flow stays on screen until the user closes it: the last screen when the flow ends, or the built-in error screen when it fails. |
With either setting, you receive the same events. Calling session.stop() always dismisses the flow. See When the SDK stays on screen for how dismissOnFinish: false affects when run(from:) returns.
Handle Events
The event handler receives progress while the flow runs, and then how the flow ended.
| Event | When it occurs |
|---|---|
.progress(_:) | The current step reports what it is waiting for. See Follow progress |
.completed | The flow finished (the outcome might be accepted or rejected) |
.aborted | The session was aborted on the server, for example because the user quit from the flow's own quit dialog |
.failed(_:) | A technical failure prevented the flow from running or completing. The value is a TrustPlatformError. See Handle Errors |
You receive any number of .progress events, then at most one terminal event: .completed, .aborted or .failed. Nothing follows it. If you close the SDK yourself with stop(), no terminal event is sent.
.completed only signals that the flow finished. To retrieve the actual outcome, query the Get session results API endpoint using the sessionId you received when creating the session. See Interpret session results for how to act on it. If the user returns after .aborted, start a new session.
Follow progress
.progress events tell your app what the current step is waiting for. Use them to track where the user is in the flow, or to react, for example by closing the SDK when a manual review starts.
await session.run(from: viewController) { event in
switch event {
case .progress(let progress):
analytics.track("verification_progress", ["progress": String(describing: progress)])
if progress == .inManualReview {
// Optional: close the SDK here if the user has nothing left to do while the review runs.
session.stop()
}
// ... the other events
}
}
StepProgress is an open set: more values will follow, so treat one you don't recognise as inProgress. The values, and which steps report them, are described in Track step progress.
Progress is reported when the value changes, and short-lived values can be skipped. If you must not miss a change, follow the session with step events on your backend.
Close the SDK early
Call session.stop() to close the SDK while the flow runs. If you call it while the progress is inManualReview, the review carries on. stop() doesn't end the session, and run(from:) returns without a further event. Because no event follows, put anything your app needs after closing the SDK after the await, not in an event case.
Run again
To open the SDK again for the same session, call run(from:) again. This starts a new run on the device, with no memory of the previous one, and the session carries on from where it is. If the current step is already waiting when the run starts, you receive its progress value straight away, for example .progress(.inManualReview) right after opening. Don't run two SDK instances for the same session at the same time: the second one is treated as a takeover from another device.
When the SDK stays on screen
With dismissOnFinish set to false, the event is delivered when the flow ends, but the await remains pending for as long as the screen is open. Because run(from:) returns nothing, the event handler is where you receive the result and react to it. As the handler runs on the main actor, any task that does intensive work and could block it should run in a separate task.
Handle Errors
A .failed event carries a TrustPlatformError when a technical failure prevents the flow from running or completing.
| Case | When it occurs |
|---|---|
flowFailure | A technical failure occurred within the flow |
invalidToken | The session token is not valid for an SDK session |
sessionExpired | The session timed out on the server |
networkFailure(underlying:) | No connection or a request failed |
nativeHandlerFailure(code:message:) | A native handler reported a non-recoverable failure |
internalError | An unexpected SDK-internal failure |
errorDescription on each case is localized and safe to display to end users.
By default, the SDK dismisses the flow when it fails, so your app must show the error when it receives .failed. If you set dismissOnFinish to false, the SDK shows its built-in error screen instead, and the screen stays up until the user closes it.
Native document verification (optional)
The TrustPlatformDocIDV module runs document capture, and NFC chip reading where the flow uses it, as native screens instead of in the webview. It uses IDnow's DocIDV SDK, which the module brings in as a dependency. Sessions, outcomes and data blocks are the same either way. See the Mobile SDK overview.
The DocIDV SDK's requirements apply when you add this module. For details specific to the DocIDV SDK, see the standalone DocIDV SDK documentation.
Add the Framework
- Select your app target, then open the Frameworks, Libraries, and Embedded Content list.
- Click + and add TrustPlatformDocIDV from the TrustPlatform package. Swift Package Manager resolves the DocIDV SDK for you.
Configure Your App for NFC
NFC chip reading needs the following entitlement and Info.plist entries. NFC results are processed by the Verifying ID document (v3) step.
Entitlements File
- Open your app's entitlements file. If you do not have one, select File > New File > Property List and name it
YourApp.entitlements. - Add a key Near Field Communication Tag Reader Session Formats of type Array.
- Add one item to the array:
- Type: String
- Value:
TAG
Info.plist File
- Open your
Info.plistfile. - Add the key Privacy - NFC Scan Usage Description and enter a string that explains why the app uses NFC.
- Add the key ISO7816 application identifiers for NFC Tag Reader Session of type Array.
- Add the following two string items to the array:
A00000045645444C2D3031A0000002471001
How It Works
Linking TrustPlatformDocIDV is enough: you do not need to call anything to register it. If the framework is not linked, the SDK runs the document step in the webview instead.