App Components
Integration Options
App Components are standalone functionality modules for Android and iOS mobile apps. They capture images and data for you to upload via the API, leveraging Fourthline's data extraction AI services, and provide real-time feedback to the client. If you build custom user journeys, with your own UI, business logic, and orchestration, components reduce development time and effort.
Fourthline provides the UI for the components, which you can customize in the same way as the App Drop-in.
You can dynamically adjust functionality during workflows, e.g. disable the tilted photo step.
App Drop-in vs App Components
How it works
SDKs
We offer the following SDKs:
- Android SDK and iOS SDK
- Cordova, Flutter, and React Native plugins
Supported solutions
You can use App Components for the following solutions:
Workflow
The workflow is as follows:
Components workflow
Configuration
Error handling
You need to handle the following error values:
Starting a workflow session with Orca.workflowSession … .start completes with WorkflowError. The Document, Biometrics, and QES components complete with WorkflowFailure instead (code + recovery). See the WorkflowFailure accordion below and each component tab for module-specific codes.
Android & iOS errors (workflow session start)
Android & iOS errors
These errors apply when you start a workflow session (Orca.workflowSession … .start). Component present callbacks return WorkflowFailure (see the next accordion).
| Error | Description |
|---|---|
Canceled | The client canceled the workflow. Action: Consider creating a new validationCode. |
ClientRejected | The client was rejected. Action: You cannot create a new workflow for this client. |
ConfigurationNotSupported | The workflowName created with the validationCode isn't supported. Action: Consider updating your SDK to the latest version. |
InvalidSession | The WorkflowSession is invalid, e.g. • "InvalidValidationCode": The validationCode is invalid. • "SessionExpired": The WorkflowSession expired. Action: Create a new validationCode. |
InvalidWorkflowStatus | The workflow modules may have been completed successfully or finished with an error. |
ModuleError | The client encountered an error in one of the workflow modules, e.g.: |
• IdentityVerification.DocumentExpired: The client's identity document has expired. | |
• IdentityVerification.DocumentTypeInvalid: The MRZ of the identity document in the document photo is different from the document type selected by the client. | |
• IdentityVerification.DocumentTypeMismatch: The scanned document type must match the selected document type. | |
• IdentityVerification.DocumentTypeNotSupported: The client's document type isn't supported. | |
• IdentityVerification.IssuingCountryNotSupported: The issuing country of the client's identity document isn't supported. | |
• IdentityVerification.NationalityNotSupported: The client's nationality isn't supported. | |
• IdentityVerification.NoDocumentDetected: No identity document was detected in the document photos. | |
• IdentityVerification.PersonNotAdult: The client is underage. | |
Unexpected | An unexpected error occurred. Action: Immediately report this issue to Fourthline along with the message code. |
WorkflowFailure (Document, Biometrics, QES components)
The Document, Biometrics, and QES components report WorkflowFailure. Do not parse the English log text for branching.
| Field | Android | iOS | Use |
|---|---|---|---|
| Stable identity | code (WorkflowFailureCode, identifier) | code (WorkflowFailureCode, rawValue) | Branch on known constants. Keep an else / default for codes added in later SDK versions. |
| Next host step | recovery (WorkflowRecoveryAction) | recovery (WorkflowRecoveryAction) | Decide retry, wait, new workflow, complete IDV, and similar actions. |
| Log text | message | description | Logging only. Do not parse for UI or branching. |
Use recovery for control flow (what your app does next) and code for user-facing copy and reporting. Special-case user.canceled and terminal outcomes such as qes.signature_completed by code when recovery is unrecoverable.
Recovery actions
| Android | iOS | What you should do |
|---|---|---|
Retry | .retry | Keep the same WorkflowSession and call the component present(...) again. Cap retries and check connectivity first. |
NewValidationCode | .newValidationCode | The workflow is still valid but the session is dead. Create a new validation code, start a new workflow session, then launch the component again. |
NewWorkflow | .newWorkflow | This workflow cannot complete the module. Create a new workflow on your backend, then a new validation code and session. |
CompleteIdv | .completeIdv | Run identity verification before QES. Do not relaunch QES until IDV is completed. |
Wait | .wait | Fourthline is still processing. Notify the client, then rely on your webhook or backend status polling with backoff. |
Unrecoverable | .unrecoverable | Stop the component flow. Branch on code for UX; user.canceled is not an error. |
Each component tab lists module-specific failure codes (idv.*, qes.*).
Plugin errors
The error is returned as a JSON string with the following format:
{
"errorCode": Integer,
"errorDescription": String
}| Error code | Error description |
|---|---|
800 | Decoding Error There was an error while decoding the workflow input. Action: Check the errorDescription for more information. |
802 | Invalid or missing font The font wasn’t found. Action: Check the errorDescription for more information. |
803 | User canceled The client explicitly canceled the workflow. |
830 | JSON parse error We couldn’t parse the JSON provided. Action: Check the JSON provided. |
850 | Incorrect configuration The workflow wasn’t configured correctly. Action: Check your workflow configuration. |
870 | Unexpected message An unexpected error occurred. Action: Inform your Fourthline delivery manager immediately and provide the message code. |
1000 | ClientRejected The client was rejected. You can’t retry. |
1001 | InvalidSession The current WorkflowSession is invalid. • InvalidValidationCode: The validationCode is invalid. • SessionExpired: The WorkflowSession expired. Action: Create a new validationCode. |
1002 | Module error The client encountered an error in one of the workflow modules. Action: For more information, check the message. Possible module errors: • IdentityVerification.DocumentExpired: The client’s identity document has expired. • IdentityVerification.DocumentTypeInvalid: The MRZ of the identity document doesn’t match the selected document type. • IdentityVerification.DocumentTypeMismatch: The scanned document type must match the selected document type. • IdentityVerification.DocumentTypeNotSupported: The client’s document type isn’t supported. • IdentityVerification.IssuingCountryNotSupported: The issuing country isn’t supported. • IdentityVerification.NationalityNotSupported: The client’s nationality isn’t supported. • IdentityVerification.NoDocumentDetected: No identity document was detected. • IdentityVerification.PersonNotAdult: The client is underage. |
1003 | ConfigurationNotSupported The workflow configuration created using the validationCode isn’t supported. Action: Update to the latest plugin version. Action: For more information, check the message. |
1004 | InvalidWorkflowStatus The workflow status is invalid. Action: Check if the workflow module ended successfully or with an error. |
iOS configuration
To ensure the client has granted camera and location permissions, in the Info.plist file, add Privacy - Camera Usage Description and Privacy - Location When In Use Usage Description entries.
Real-time feedback
The components can send document/selfie photos to our backend as soon as they are captured, where we assess the image quality and provide the client feedback in the UI in real time. The component displays an additional screen where we perform further validations.
This ensures higher-quality photos are ultimately uploaded, reduces sendbacks, and improves the user experience.
Agree with your Fourthline delivery manager whether you want to enable real-time feedback for App Components.
UI customization
To customize each component's UI, create an OrcaFlavor object.
See App UI Customization.
Document, Biometrics, and QES Components
Use the Document Component to capture the client's identity document photos and video, based on your workflow tenant configuration (tilted capture, document video, supported countries, real-time feedback).
If AI services are enabled for your tenant, the component can show an additional screen where further document validations run before the client continues.

Document Component
Issuing country
The issuing country is required for the client's primary identity document. It is not required for Physical Proof of Address or tax documents.
| Scenario | SDK behavior | Example failure |
|---|---|---|
The documentType and issuingCountry combination is not supported by your tenant configuration. | Returns a failure before showing any UI. No bottom sheet appears. | idv.document_type_not_supported or idv.issuing_country_not_supported |
| The configuration is valid, but the scanned document does not match the expected document type or is not supported. | Shows a bottom sheet and completes with a failure. | idv.document_type_mismatch |
When you use the Document Component standalone, pass only supported documentType and issuingCountry values. Otherwise, the component can close with a failure before the client can interact with it.
Document types
The Document Component supports the following document types:
| Document type | Description |
|---|---|
driversLicense | Driving license |
dutchDriversLicense | Dutch driving license |
frenchIdCard | French ID card |
idCard | ID card |
paperId | Paper ID |
passport | Passport |
proofOfAddress | Proof of Address |
residencePermit | Residence permit |
tinReferenceDocument | TIN document |
Before you begin
- Start a workflow session (
Orca.workflowSession), then calldocumentComponentwithDocumentComponentConfig. - Before showing the SDK UI, the component validates the configuration and workflow status. If validation fails,
onProductCompletedis called with a failure, andonPresentationStarted is not called.
Success handling
If the workflow completes successfully, the component returns:
- A document payload containing the document photos, document video, and data extracted from the MRZ. The payload is returned as
documenton Android anddocumentResulton iOS. - An optional
documentAnalysisobject containing data extracted from the document photos.
data class DocumentComponentResult(
val document: WorkflowResults.Component.Document,
val documentAnalysis: WorkflowResults.Component.DocumentAnalysis? = null,
)struct DocumentComponentResult {
let documentResult: WorkflowResults.Component.Document
let documentAnalysis: WorkflowResults.Component.DocumentAnalysis?
}{
"documentResult":{
"documentType":"String",
"images":[
{
"image":"String",
"isAngled":"Boolean",
"timestamp":"String",
"fileSide":"String",
"location":{
"latitude":"String",
"longitude":"Number"
}
}
],
"mrtdMrzInfo":{
"rawMrz":"String",
"documentCode":"String",
"issuingCountry":"String",
"documentNumber":"String",
"expirationDate":"String",
"firstNames":[
"String"
],
"lastNames":[
"String"
],
"birthDate":"String",
"nationality":"String",
"gender":"String",
"validationErrors":[
"ValidationError"
]
},
"idlMrzInfo":{
"rawMrz":"String",
"documentNumber":"String",
"validationErrors":[
"ValidationError"
]
},
"videoRecording":{
"url":"String",
"duration":"String",
"location":{
"latitude":"String",
"longitude":"Number"
}
}
},
"documentAnalysis":{
"firstName":"String",
"lastName":"String",
"initials":"String",
"gender":"String",
"nationality":"String",
"issuingCountry":"String",
"issueDate":"String",
"expirationDate":"String",
"dateOfBirth":"String",
"birthPlace":"String",
"documentNumber":"String",
"documentType":"String",
"taxIdentificationNumber":"String"
}
}Plugins documentResult attributes
All attributes are optional.
| Attribute | Description | |
|---|---|---|
documentType String | The identity document type. | |
images Array of objects | Information about each document photo. | |
images.image String | The absolute filepath to the document photo. | |
images.isAngled Boolean | •True: The photo is tilted. • False: The photo is flat. | |
images.timestamp String | The timestamp for when the document photo was captured. | |
images.fileSide String | The side of the identity document. | |
images.location Object | The coordinates of the document photo. | |
images.location.latitude String | The latitude of the document photo. Format: Float between -90 and 90 Example: 45.464664 | |
images.location.longitude String | The longitude of the document photo. Format: Float between -90 and 90 Example: 45.464664 | |
mrtdMrzInfo Object | The data extracted from the MRZ of a frenchIdCard, idCard, passport, or residencePermit. | |
mrtdMrzInfo.rawMrz String | The raw data from the MRZ. | |
mrtdMrzInfo.documentCode String | [Is this document type?] | |
mrtdMrzInfo.issuingCountry String | The country that issued the identity document. | |
mrtdMrzInfo.documentNumber String | The identity document number. | |
mrtdMrzInfo.expirationDate String | The identity document expiry date. Format: Date YYYY-MM-DD | |
mrtdMrzInfo.firstNames Array of strings | The client's first name(s). Format: Alphabetical characters, spaces, hyphens, and apostrophes | |
mrtdMrzInfo.lastNames Array of strings | The client's last name(s). Format: Alphabetical characters, spaces, hyphens, and apostrophes | |
mrtdMrzInfo.birthDate String | The client's date of birth. Format: Date YYYY-MM-DD | |
mrtdMrzInfo.nationality String | The client's nationality. Format: ISO 3166-1 alpha-3 country code | |
mrtdMrzInfo.gender String | The client's sex. • Female • Male • Other: identity document contains a value other than Female or Male • Unknown: identity document contains no gender field | |
mrtdMrzInfo.validationErrors Array of strings [Or integers?] | The validation error code(s). | |
idlMrzInfo Object | The data extracted from the MRZ of a Dutch driving license. | |
idlMrzInfo.rawMrz String | The raw data from the MRZ. | |
idlMrzInfo.documentNumber String | The identity document number. | |
idlMrzInfo.validationErrors Array of strings | The validation error code(s). | |
videoRecording Object | Information about the document video. | |
videoRecording.url String | The absolute url filepath to the document video. | |
videoRecording.duration String | The length of the document video. [What unit of time? Seconds?] | |
videoRecording.location Object | The coordinates of the document video. | |
videoRecording.location.latitude String | The latitude of the document video. Format: Float between -90 and 90 Example: 45.464664 | |
videoRecording.location.longitude String | The longitude of the document video. Format: Float between -90 and 90 Example: 45.464664 |
Plugins documentAnalysis attributes
All attributes are optional.
| Attribute | Description |
|---|---|
firstName String | The client's first name. Format: Alphabetical characters, spaces, hyphens, and apostrophes |
lastName String | The client's last name. Format: Alphabetical characters, spaces, hyphens, and apostrophes |
initials String | The client's initials. Format: Alphabetical characters, spaces, hyphens, and apostrophes |
gender String | The client's sex. • Female • Male • Other: identity document contains a value other than Female or Male • Unknown: identity document contains no gender field |
nationality String | The client's nationality. Format: ISO 3166-1 alpha-3 country code |
issuingCountry String | The country that issued the identity document. |
issueDate String | The date the identity document was issued. Format: Date YYYY-MM-DD |
expirationDate String | The date the identity document expires. Format: Date YYYY-MM-DD |
dateOfBirth String | The client's date of birth. Format: Date YYYY-MM-DD |
birthPlace String | The city where the client was born. |
documentNumber String | The identity document number. |
documentType String | The identity document type. |
taxIdentificationNumber String | The client's TIN. |
On Android, when your tenant enables in-memory recording (cameraX.inMemoryRecording.enabled, API 30+), videoRecording.url in the plugin JSON may be memory://fourthline/video. The MP4 bytes are available on videoRecording.data in the native SDK model. This does not apply on iOS.
Presentation callbacks
present exposes two callbacks:
| Callback | When it is called |
|---|---|
onPresentationStarted | Preparation succeeded and the SDK is about to show UI. Hide any host loading indicator here. Not called when preparation fails. |
onProductCompleted | The component finishes once (success, user cancel, or failure). Always handle the result here, and hide the loading indicator if it is still visible. |
If your app shows a loading indicator before calling present, hide it in onPresentationStarted. If preparation fails, hide it in onProductCompleted instead.
Error handling
The Document Component completes with WorkflowFailure. Document-specific failures use the idv.* prefix. Shared preparation and transport codes (session.*, transport.*, user.canceled, and similar) also apply to Biometrics and QES. Recovery actions are listed under Configuration → Error handling → WorkflowFailure.
Use recovery for control flow and code for user-facing copy. Special-case user.canceled and document validation outcomes by code when recovery is unrecoverable.
Failure codes (idv.*)
idv.*)| Code | Description |
|---|---|
idv.pending_verification | Identity verification is waiting to be processed. |
idv.status_invalid | The IDV workflow status does not allow the component to start. |
idv.person_not_adult | The person is under the minimum required age. |
idv.nationality_not_supported | The nationality is not supported. |
idv.issuing_country_not_supported | The document issuing country is not supported. |
idv.issuing_country_mismatch | The scanned issuing country does not match the selected country. |
idv.document_expired | The document has expired. |
idv.document_type_not_supported | The document type is not supported. |
idv.document_type_invalid | The scanned document MRZ type does not match the selected type. |
idv.document_type_mismatch | The scanned document type does not match the selected type. |
idv.document_side_mismatch | The scanned document side does not match the expected side. |
idv.no_document_detected | No document was detected. |
idv.missing_country_and_type | The document type or issuing country could not be detected. |
idv.undefined_document_type | The document type is undefined. |
idv.unexpected | An unexpected identity verification error occurred. |
Testing
Start a TestMe session using any mock validation code:
import com.fourthline.networking.NetworkEnvironment
import com.fourthline.orca.Orca
import com.fourthline.orca.workflow.WorkflowConfig
import com.fourthline.orca.workflow.WorkflowFailure
import com.fourthline.orca.workflow.WorkflowSession
import com.fourthline.orca.workflow.workflowSession
fun startSession(context: Context) {
val config = WorkflowConfig(networkEnvironment = NetworkEnvironment.Mock)
Orca
.workflowSession(
context = context,
validationCode = "IDV",
)
.configure(config)
.start { result ->
result.fold(
onSuccess = { session ->
launchDocumentComponent(context, session)
},
onFailure = { workflowError ->
print("Handle error... $workflowError")
}
)
}
}
fun launchDocumentComponent(context: Context, session: WorkflowSession) {
val flavor = OrcaFlavor()
val documentConfig = DocumentComponentConfig(
type = documentType, /// See the `DocumentType` table.
issuingCountry = issuingCountry /// Format: ISO3 country code
)
session
.documentComponent(context, documentConfig)
.customize(DocumentCustomizationConfig(flavor))
.present(
onPresentationStarted = {
// Hide the host loading indicator; the SDK UI is about to be shown
},
onProductCompleted = { result ->
result.fold(
onSuccess = { documentResult ->
print("Document component completed.")
},
onFailure = { throwable ->
val failure = throwable as? WorkflowFailure
print("Handle error... ${failure?.code?.identifier} ${failure?.recovery}")
},
)
},
)
}import FourthlineSDK
override func viewDidLoad() {
super.viewDidLoad()
let customization = WorkflowConfig(
networkEnvironment: .mock
)
Orca
.workflowSession(validationCode: "IDV")
.configure(with: customization)
.start { [weak self] result in
switch result {
case let .success(session):
launchDocumentComponent(session)
case let .failure(workflowError):
print("Handle error...\(workflowError)")
}
}
}
func launchDocumentComponent(_ session: WorkflowSession) {
session
.documentComponent(with:
DocumentComponentConfig(
type: documentType, /// See the `DocumentType` table.
issuingCountry: issuingCountry /// Format: ISO3 country code
)
)
.customize(with: DocumentCustomizationConfig(flavor: orcaFlavor))
.present(
onPresentationStarted: {
// Hide the host loading indicator; the SDK UI is about to be shown
},
onProductCompleted: { result in
switch result {
case let .success(documentResult):
print("Document component completed.")
case let .failure(failure):
print("Handle error...\(failure.code.rawValue) \(failure.recovery)")
}
}
)
}function startWorkflowSession() {
var config = `{
"configuration": {
"validationCode": "IDV",
"networkEnvironment": "mock"
}
}`;
FourthlinePlugin.startWorkflowSession(
config,
function(msg) {
// The client has successfully started a workflow session.
// You can now start a workflow component.
},
function(error) {
// Extract and process information from the error.
// See Error handling.
var jsonError = JSON.parse(error.message);
}
);
}
function startWorkflowDocumentComponent() {
var config = `{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
}`;
FourthlinePlugin.startWorkflowComponentDocument(
config,
function(msg) {
// Use the componentResult to continue the user experience on your side.
},
function(error) {
// Extract and process information from the error.
// See Error handling.
var jsonError = JSON.parse(error.message);
}
);
}
final _fourthlinePlugin = Fourthline();
startWorkflowSession() async {
String config = """
{
"configuration": {
"validationCode": "IDV",
"networkEnvironment": "mock"
}
}
""";
try {
String sessionResult = await _fourthlinePlugin.startWorkflowSession(config) ?? "Could not start Workflow Session";
// The client has successfully started a workflow session.
// You can now start a workflow component.
startWorkflowComponent();
} on PlatformException catch (e) {
// Extract and process information from the error.
// See Error handling.
};
}
startWorkflowComponent() async {
String config = """
{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
}
""";
try {
String componentResult = await _fourthlinePlugin.startWorkflowComponentDocument(config) ?? "Could not start Workflow Document Component";
// Use the componentResult to continue the user experience on your side.
} on PlatformException catch (e) {
// Extract and process information from the error.
// See Error handling.
};
}function startWorkflowSession() {
var config = `
{
"configuration": {
"validationCode": "IDV",
"networkEnvironment": "mock"
}
}
`;
NativeModules.Fourthline.startWorkflowSession(config)
.then((result) => {
// The client has successfully started a workflow session.
// You can now start a workflow component.
startWorkflowComponent();
})
.catch((error) => {
// Extract and process information from the error.
// See Error handling.
});
}
startWorkflowComponent() async {
var config = `
{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
}
`;
NativeModules.Fourthline.startWorkflowComponentDocument(config)
.then((result) => {
// Use the componentResult to continue the user experience on your side.
})
.catch((error) => {
// Extract and process information from the error.
// See Error handling.
});
}Example
The following is a complete example:
import com.fourthline.networking.NetworkEnvironment
import com.fourthline.orca.Orca
import com.fourthline.orca.core.flavor.OrcaFlavor
import com.fourthline.orca.core.flavor.OrcaFonts
import com.fourthline.orca.document.DocumentCustomizationConfig
import com.fourthline.orca.workflow.DocumentComponentConfig
import com.fourthline.orca.workflow.WorkflowConfig
import com.fourthline.orca.workflow.WorkflowFailure
import com.fourthline.orca.workflow.WorkflowSession
import com.fourthline.orca.workflow.workflowSession
import java.io.File
fun startSession(context: Context) {
// Make a POST Create SDK session request: https://{{baseUrl}}/v1/workflows/{{workflowId}}/validationcode.
val validationCode = "xxxxxxxx"
// To test the workflow offline, use Mock. To test networking, use Sandbox or Production.
val config = WorkflowConfig(networkEnvironment = NetworkEnvironment.Mock)
Orca
.workflowSession(
context = context,
validationCode = validationCode,
)
.configure(config)
.start { result ->
result.fold(
onSuccess = { session ->
launchDocumentComponent(context, session)
},
onFailure = { workflowError ->
print("Handle error... $workflowError")
}
)
}
}
fun launchDocumentComponent(context: Context, session: WorkflowSession) {
val customFlavor = OrcaFlavor(
fonts = OrcaFonts(
screenHeader = OrcaFonts.Font.FromFontRes(fontRes = R.font.roboto_medium, size = 20),
primaryButton = OrcaFonts.Font.FromFile(file = File(...), size = 18
),
)
val documentConfig = DocumentComponentConfig(
type = documentType, /// See the `DocumentType` table.
issuingCountry = issuingCountry /// Format: ISO3 country code
)
session
.documentComponent(context, documentConfig)
.customize(DocumentCustomizationConfig(customFlavor))
.present(
onPresentationStarted = {
// Hide the host loading indicator; the SDK UI is about to be shown
},
onProductCompleted = { result ->
result.fold(
onSuccess = { documentResult ->
print("Document component completed.")
},
onFailure = { throwable ->
val failure = throwable as? WorkflowFailure
print("Handle error... ${failure?.code?.identifier} ${failure?.recovery}")
},
)
},
)
}import FourthlineSDK
override func viewDidLoad() {
super.viewDidLoad()
let customization = WorkflowConfig(
networkEnvironment: .mock // To test the workflow offline, use .mock. To test networking, use .sandbox or .production.
)
let validationCode = "xxxxxxxx" // Make a POST Create SDK session request: https://{{baseUrl}}/v1/workflows/{{workflowId}}/validationcode.
Orca
.workflowSession(validationCode: validationCode)
.configure(with: customization)
.start { [weak self] result in
switch result {
case let .success(session):
launchDocumentComponent(session)
case let .failure(workflowError):
print("Handle error...\(workflowError)")
}
}
}
func launchDocumentComponent(_ session: WorkflowSession) {
var orcaFlavor = OrcaFlavor()
// Configure the colors
var palette = OrcaPalette()
palette.primary = UIColor(red: 82.0 / 255.0, green: 30.0 / 255.0, blue: 135.0 / 255.0, alpha: 1)
var colors = OrcaColors(colorPalette: palette)
colors.hint.backgroundColor = UIColor(red: 221.0 / 255.0, green: 210.0 / 255.0, blue: 232.0 / 255.0, alpha: 0.5)
colors.box.borderColor = UIColor.gray
colors.screen.tableCells.cellStyle2.iconColor = UIColor(red: 221.0 / 255.0, green: 210.0 / 255.0, blue: 3.0 / 255.0, alpha: 1)
orcaFlavor.colors = colors
let documentType = .passport
let issuingCountry = "NLD"
session
.documentComponent(with:
DocumentComponentConfig(
type: documentType,
issuingCountry: issuingCountry
)
)
.customize(with: DocumentCustomizationConfig(flavor: orcaFlavor))
.present(
onPresentationStarted: {
// Hide the host loading indicator; the SDK UI is about to be shown
},
onProductCompleted: { result in
switch result {
case let .success(documentResult):
print("Document component completed.")
case let .failure(failure):
print("Handle error...\(failure.code.rawValue) \(failure.recovery)")
}
}
)
}// Call this after starting a valid WorkflowSession.
function startWorkflowDocumentComponent() {
var config = `{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
"customization": {
...
}
}`;
FourthlinePlugin.startWorkflowComponentDocument(
config,
function(msg) {
// Use the componentResult to continue the user experience on your side.
},
function(error) {
// Extract and process information from the error.
// See Error handling.
var jsonError = JSON.parse(error.message);
}
);
}
final _fourthlinePlugin = Fourthline();
// Call this after starting a valid WorkflowSession.
startWorkflowComponent() async {
String config = """
{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
"customization": {
...
}
}
""";
try {
String componentResult = await _fourthlinePlugin.startWorkflowComponentDocument(config) ?? "Could not start Workflow Document Component";
// Use the componentResult to continue the user experience on your side.
} on PlatformException catch (e) {
// Extract and process information from the error.
// See Error handling.
};
}// Call this after starting a valid WorkflowSession.
startWorkflowComponent() async {
String config = `
{
"configuration": {
"documentType": "passport",
"issuingCountry": "NLD"
},
"customization": {
"flavor": {
"colors": ${orcaColors},
"fonts": ${orcaFonts},
"localization": ${orcaLocalization},
"layouts": ${orcaLayout}
}
}
}
`;
NativeModules.Fourthline.startWorkflowComponentDocument(config)
.then((result) => {
// Use the componentResult to continue the user experience on your side.
})
.catch((error) => {
// Extract and process information from the error.
// See Error handling.
});
}Plugin helpers
Clear workflow session
To delete any workflow resources after a Document, Biometrics, or QES component finishes and clear the workflow session, use the clearWorkflowSession function.
Before launching the component, call startWorkflowSession.
Fourthline.clearWorkflowSession(
function(msg) {
...
});await _fourthlinePlugin.clearWorkflowSession()NativeModules.Fourthline.clearWorkflowSession((error, success) => {});Workflow session availability
To confirm that the workflow session is available before launching a Document, Biometrics, or QES component, use the isWorkflowSessionAvailable function.
Before launching the component, call startWorkflowSession.
Fourthline.isWorkflowSessionAvailable(
function(msg) {
if (msg == "true") {
...
} else {
...
}
)if (await _fourthlinePlugin.isWorkflowSessionAvailable() ?? false) {
...
}NativeModules.Fourthline.isWorkflowSessionAvailable((error, isAvailable) => {});Updated 6 days ago