This is the standard integration pattern for the Incode iOS SDK. It involves:
- Defining the onboarding flow locally in code with
IncdOnboardingFlowConfiguration - Implementing an
IncdOnboardingDelegateto receive results - Running the session with one call to
startOnboarding(sessionConfig:flowConfig:delegate:)
The SDK presents the Incode UI for each module in turn.
Use this integration pattern when you want full control over the flow in client code. If you prefer to define the flow in Dashboard instead, see Run Flows Configured in Dashboard. If you need to insert your own screens or logic between SDK modules, see Configure Flows Locally and Run Step by Step. For more information about these patterns, see Integration Approaches.
This page covers building the flow, receiving results, and starting the session. Ensure you have followed the steps to install and initialize the Incode iOS SDK first.
Imports and Package Paths
The snippets below use short type names. The iOS SDK ships as a single module, so one import brings in the entry point, configuration, delegate, and result types:
import IncdOnboarding
The key types used on this page are:
IncdOnboardingManager: The entry point. Access the shared instance withIncdOnboardingManager.shared.IncdOnboardingFlowConfiguration: Builds the flow withaddXxx(...)calls. MostaddXxx(...)methods add a single module, but a few differ:addIdScan(scanStep: .both), for example, also appends the Process ID module, and some methods add nothing in certain SDK modes. For example, ID processing and user score are skipped in the Capture Only and Submit Only modes.IncdOnboardingSessionConfiguration: The session settings passed to every start call.IncdOnboardingDelegate: The protocol your object conforms to in order to receive results. Your class adopts this protocol directly.- Result types (
IdScanResult,SelfieScanResult,FaceMatchResult, …) are delivered to the delegate. Each is documented on its own page in Modules.
Set Up This Integration Pattern
The pattern uses five actions: initialize the SDK, set the presenting view controller, build an IncdOnboardingFlowConfiguration, implement an IncdOnboardingDelegate, and call startOnboarding(sessionConfig:flowConfig:delegate:).
startOnboarding(sessionConfig:flowConfig:delegate:) takes a sessionConfig argument. The argument is required, but every field of IncdOnboardingSessionConfiguration is optional. Pass IncdOnboardingSessionConfiguration() if you don't need to customize the session. Session customization is covered in Optional Configuration below.
Build a Flow Configuration
Build an IncdOnboardingFlowConfiguration and add the modules you want in the flow. Modules appear in the order you add them; omitted modules are not shown.
let flow = IncdOnboardingFlowConfiguration() // or .init(waitForTutorials:)
flow.addIntro(checks: [])
flow.addPhone(otpVerification: true, defaultRegionPrefix: 1)
flow.addEmail(otpVerification: true)
flow.addIdScan(scanStep: .both)
flow.addSelfieScan()
flow.addFaceMatch(matchType: .idSelfie, idCategory: .primary)
flow.addApproval()
IncdOnboardingManager.shared.startOnboarding(
sessionConfig: IncdOnboardingSessionConfiguration(token: "<SESSION_TOKEN>"),
flowConfig: flow,
delegate: self
)
Each module exposes its own configuration through the parameters of its addXxx(...) method. For example, addIdScan(...) accepts an idType, a scanStep, tutorial toggles, and more. Several builders take defaulted parameters; for example, addApproval(forceApproval: Bool? = nil) may be called with no arguments (forceApproval defaults to nil), as shown above. See Modules for the options, result type, and callbacks of each module.
Danger
Warning
Some modules have order dependencies. Some modules are required by others. For example, addIntro(checks:) is intended to be the first module added. Modules that consume data, such as Face Match, should come after the modules that collect data.
The SDK defines these ordering and dependency rules per module but does not currently enforce them at session start: the addXxx(...) methods do not throw, and an invalid order or a missing module is not validated or rejected when the session begins. Add the modules in a valid order yourself; an invalid configuration is not caught for you.
Create a Delegate to Receive SDK Results
Conform to IncdOnboardingDelegate to receive results from each module and the overall flow. Only onSuccess() and onError(_:) are required. Every other method has a default empty implementation. Override only the events for the modules your flow includes.
final class VerificationCoordinator: IncdOnboardingDelegate {
// MARK: Required
func onSuccess() {
// User successfully finished the whole onboarding flow.
}
func onError(_ error: IncdFlowError) {
// Onboarding flow was aborted due to an error.
print("Flow error: \(error.description)")
}
// MARK: Optional (each has a default empty implementation)
func userCancelledSession() {
// User backed out of the flow.
}
func onOnboardingSessionCreated(_ result: OnboardingSessionResult) {
// Session created successfully.
}
func onAddPhoneNumberCompleted(_ result: PhoneNumberResult) {
// Phone number step completed.
}
func onIdFrontCompleted(_ result: IdScanResult) {
// Front of the ID captured.
}
func onIdBackCompleted(_ result: IdScanResult) {
// Back of the ID captured.
}
func onIdProcessed(_ result: IdProcessResult) {
// ID processing/validation completed.
}
func onSelfieScanCompleted(_ result: SelfieScanResult) {
// Selfie scan completed.
}
func onFaceMatchCompleted(_ result: FaceMatchResult) {
// Face match completed.
}
func onApproveCompleted(_ result: ApprovalResult) {
// Onboarding approval completed.
}
}
The video-conference queue also reports progress through onQueuePositionChanged(_:) and onEstimatedWaitingTime(_:). For the shape and fields of each result object, see the corresponding page in Modules.
Start the Onboarding Process
After building the flow configuration and your delegate, set the presenting view controller and call startOnboarding(sessionConfig:flowConfig:delegate:). The sessionConfig argument is required; its contents are optional.
IncdOnboardingManager.shared.presentingViewController = self // required for UI flows
let session = IncdOnboardingSessionConfiguration() // or a customized session (see below)
IncdOnboardingManager.shared.startOnboarding(
sessionConfig: session,
flowConfig: flow,
delegate: self
)
Optional Configuration
These configuration points are optional. Use the session configuration to bind a Dashboard flow, resume a session, or set custom fields. Use the manager's UX properties to adjust presentation behavior.
Session Configuration
Customize the onboarding session by constructing an IncdOnboardingSessionConfiguration, which configures the session for startOnboardingSection, startFlow(sessionConfig:delegate:), and startWorkflow(sessionConfig:delegate:), but not the URL-based startFlow(url:delegate:isShortened:).
iOS uses a single initializer whose parameters are all optional. The table below highlights the most commonly used ones; see the full initializer signature at the end of this section.
| Parameter | Description |
|---|---|
configurationId |
The flow ID from Dashboard, to apply the configuration set on that flow. You still add onboarding steps via IncdOnboardingFlowConfiguration to display the flow. |
validationModules |
The list of OnboardingValidationModule values used for user scoring and approval. Defaults to .id, .liveness, .faceRecognition. |
customFields |
A [String: String] of custom fields stored for this session. |
interviewId |
The ID of the onboarding session. Use it to resume an existing session. |
token |
The JSON Web Token (JWT) of the onboarding session. Use it to resume an existing session. |
externalId |
An ID used outside of the Incode Platform. If the first session is interrupted and a session with the same externalId already exists, that session is resumed. |
externalCustomerId |
Similar to externalId, but always creates a new session if interrupted, even if a session with the same externalCustomerId already exists. |
queue |
The ConferenceQueue the user enters after the flow completes when using the Conference module. If none is specified, the user goes to the default queue. |
Bind a Dashboard flow by its configuration ID:
let session = IncdOnboardingSessionConfiguration(configurationId: "xxxxxxxxxxxxxxxx")
Resume an existing session—for example, one started API to API—by its interviewId:
let session = IncdOnboardingSessionConfiguration(interviewId: "<INTERVIEW_ID>")
For reference, here is the complete IncdOnboardingSessionConfiguration initializer:
let session = IncdOnboardingSessionConfiguration(
configurationId: nil,
validationModules: nil,
customFields: ["partnerId": "abc123"],
interviewId: nil,
token: "<SESSION_TOKEN>",
externalId: nil,
externalCustomerId: nil,
queue: nil,
downloadImagesEnabled: nil,
e2eEncryptionEnabled: false,
mergeSessionRecordings: nil,
language: "en"
)
Presentation and UX Configuration
On iOS, presentation and UX behaviors are set as properties on the shared IncdOnboardingManager rather than through a separate configuration object. Set them before starting the flow.
| Property | Default | Description |
|---|---|---|
presentingViewController |
nil |
The view controller the SDK presents its UI from. Required for UI flows. |
dismissOnCompletion |
true |
Whether the SDK dismisses its UI automatically when the flow finishes. Set to false to dismiss it yourself. |
modalTransitionStyle |
.coverVertical |
The UIModalTransitionStyle used when presenting the SDK UI. |
ageAssurance |
false |
Enables the Age Assurance UX (privacy tutorials and customized capture screens). |
sendDiagnosticsData |
true |
Whether the SDK sends diagnostics data. |
externalAnalyticsEnabled |
true |
Whether external analytics events are emitted. |
enableExternalScreenshots |
false |
Whether screenshots are allowed while the SDK UI is on screen. |
let manager = IncdOnboardingManager.shared
manager.presentingViewController = self
manager.dismissOnCompletion = true
manager.modalTransitionStyle = .coverVertical
manager.ageAssurance = false
Interrupt or Dismiss the Session
Use these to end a session before it reaches a terminal delegate callback, or to control the SDK's presented UI directly.
// Interrupt an in-progress flow (optionally try to finish it first)
IncdOnboardingManager.shared.forceInterrupt(tryFinishingFlow: true) { success, error in /* … */ }
// Dismiss the SDK UI
IncdOnboardingManager.shared.dismiss(forceInterrupt: false)
allowUserToCancel controls whether the SDK shows its own cancel button; dismissOnCompletion (see Presentation and UX Configuration) controls whether the SDK dismisses itself automatically when the flow ends.