App Drop-in Setup

Integrations guide

This page sets out step-by-step instructions for setting up your App Drop-in.


Android and iOS SDKs

To set up your SDK, follow these steps:

Prerequisites & configuration

Prerequisites & configuration

Prerequisites

Check the following prerequisites and specifications for your operating system:

Operating systemPrerequisites
Android• Minimum API version: 23
• Language: The SDK is written in Kotlin but is also compatible with Java.
iOS• Minimum iOS version: 12
MRZ detection in the document scanner requires minimum iOS 13

Identity data

If you want to receive a copy of the identity data gathered by the App Drop-in when it's uploaded to our backend (before case processing), let your implementation manager know.

Document data

Discuss with your implementation manager what data to extract from ID document photos via optical character recognition (OCR):

Data typeDescription
MRZ dataDocument data is extracted from the MRZ only and is processed offline by the SDK.
MRZ & VIZ dataFor greater accuracy, document data is extracted from the MRZ and VIZ and processed by our AI agent in real time.

Supported devices

More information
For questions about supported devices, contact your implementation manager.

1. Add SDK to project

1. Add SDK to project

Android setup

You can add the SDK to your project using Gradle.

1. In your top-level build.gradle file, link to Fourthline's repository:

allprojects {
 repositories {
 //...
 maven {
 url "https://maven.pkg.github.com/Fourthline-com/FourthlineSDK-Android"
 credentials {
 username ""
 password getLocalProperty("github_token")
 }
 }
 }
}
allprojects {
 repositories {
 //...
 maven {
 url = URI("https://maven.pkg.github.com/Fourthline-com/FourthlineSDK-Android")
 credentials {
 username = ""
 password = getLocalProperty("github_token")
 }
 }
 }
}

2. To access Fourthline's repository, in your GitHub account, go to Settings > Account security > Enable two-factor authentication.

3. Go to Settings > Developer settings > Personal access tokens > Generate a new token.

4. Select the scope "read:packages", and then generate a new token.

5. Store the access token in a secure, but accessible location, e.g. local.properties.
Treat the token as a password. Don't add it to your version control system.
If you have to share it, use a password manager.

Example code for local.properties:

//..
github_token=YOUR_ACCESS_TOKEN

6. In your module-level build.gradle file, add a dependency to the Fourthline SDK:

dependencies {
 // ...
 def fourthlineSdkVersion = "%%LATEST_SDK_VERSION%%"
 implementation "com.fourthline:fourthline-sdk:$fourthlineSdkVersion"
}
dependencies {
 // ...
 val fourthlineSdkVersion = "%%LATEST_SDK_VERSION%%"
 implementation("com.fourthline:fourthline-sdk:$fourthlineSdkVersion")
}

iOS setup

You can add the SDK to your project using Swift Package Manager, CocoaPods, or Carthage.

SDK versionCarthage Xcode Compatible
.xcframework
Cocoa Xcode Compatible
.xcframework
Minimum iOS version
2.28.0–latest14.3 and above14.3 and aboveiOS 12
2.23.0–2.27.014.314.3iOS 12
2.15.1–2.22.014.1–14.214.1–14.2iOS 12
2.11.3–2.15.013.3.1–13.413.3.1–13.4iOS 12
2.8.0–2.11.213.0–13.113.0–13.1iOS 12
2.6.0–2.7.012.511.0–12.5iOS 12

1. To ensure clients grant camera and location permissions, in the Info.plist file, add Privacy - Camera Usage Description and Privacy - Location When In Use Usage Description entries.

2. If configuring Document NFC, add Near Field Communication Tag Reading capability to your app, containing the following values:

  • Tag-Specific Data Protocol (TAG)
  • Password Authenticated Connection Establishment (PACE)
Note
The YOUR_PROJECT_NAME.entitlements file is added to your project automatically.

Example entitlements file source code:

 <dict>
 <key>com.apple.developer.nfc.readersession.formats</key>
 <array>
 <string>TAG</string>
 <string>PACE</string>
 </array>
 </dict>

Then, to ensure clients grant NFC permissions, in the Info.plist file, add Privacy - NFC Scan Usage Description and Privacy - Location When In Use Usage Description entries.

3. In the Info.plist file, add an ISO7816 application identifiers for NFC Tag Reader Session entry containing the following 2 keys:

  • A0000002471001: Application ID for e-passport
  • A00000045645444C2D3031: Application ID for Dutch driving license

Example code:

//1. Install Carthage on your machine. See GitHub – [Carthage](https://github.com/Carthage/Carthage) <img src="https://files.readme.io/f7f4159-Open_new_tab.svg" align="left"/>.
//2. Ensure the Carthage version is at least **0.38**. If installed via HomeBrew, you can check this with the following command: `brew list --versions carthage`
//3. Add **Cartfile** to the root of your project (or extend an existing one):

github "Fourthline-com/FourthlineSDK-iOS" == version.to.integrate

//4. Open a terminal and in your project root folder, run `carthage update --platform iOS --use-xcframeworks`. 
//5. Authenticate in Fourthline's SDK repository using the credentials provided by your implementation manager.
//6. Go to the `Carthage/Build/iOS` folder, and then drag all the frameworks into the `Frameworks, libraries, and embedded content` section in Xcode. 
//7. Set the `Embed` value to `Embed & sign`.
//1. Install CocoaPods on your machine. See CocoaPods – [Installation](https://guides.cocoapods.org/using/getting-started.html) <img src="https://files.readme.io/f7f4159-Open_new_tab.svg" align="left"/>.
//2. Add **Podfile** to the root of your project (or extend an existing one):

source 'https://github.com/Fourthline-com/FourthlineSDK-iOS-Specs.git' # to add our private pod
source 'https://github.com/CocoaPods/Specs.git' # to add other public pods

$version = 'version.to.integrate'
use_frameworks!
platform :ios, '12.0'
target 'YourTargetName' do
 pod 'FourthlineSDK', $version
end
// Minimum version: v2.30.0
//1. In Xcode, go to **File** > **Add packages**.
//2. Enter the following URL: `https://github.com/Fourthline-com/FourthlineSDK-iOS`
//3. Select and import the following frameworks: `FourthlineCore`, `FourthlineVision`, `FourthlineNFC`, `FourthlineKYC`, `FourthlineSDK`.
2. Set up analytics

2. Set up Fourthline Analytics

The FourthlineCore module collects and processes Android and iOS SDK metrics.

By default, analytics data collection is disabled, so no data is collected or shared with Fourthline without your consent.

To enable analytics data collection and sharing:

1. Initialize FourthlineAnalytics with the tenantId provided by Fourthline.

Note
Note
If you get an invalidTenantId error, ensure you are using the correct ID provided by Fourthline.

2. Set TrackingConsent to one of the following values:

ValueDescription
.pending
(default)
The SDK starts collecting and batching the data but doesn't send it to Fourthline.
It waits for a new tracking consent value to decide what to do with the batched data.
.grantedThe SDK collects data and sends it to Fourthline.
Any already batched data is sent to Fourthline.
.notGrantedThe SDK doesn't collect any data and events aren't sent to Fourthline.
Any batched data is wiped.
Debug modeThe SDK doesn't collect or send any data when running attached to the debugger.

Note
Note
To change the TrackingConsent value, after the SDK is initialized, make a FourthlineAnalytics.setTrackingConsent API request.

Example code:

// Initialize analytics by calling `FourthlineAnalytics.initialize(TENANT_ID, context)` when suitable, usually in `Application.onCreate()` using the `tenantId` provided by Fourthline.
try {
    FourthlineAnalytics.initialize(tenantId = "<tenantId provided by Fourthline>", context = applicationContext)
} catch (e: AnalyticsError) {
    when (e) {
        is AnalyticsError.DatadogNotImported -> TODO()
        is AnalyticsError.InvalidTenantId -> TODO()
    }
}

FourthlineAnalytics.setTrackingConsent(consent = TrackingConsent.GRANTED)
import FourthlineCore

// Initialize `FourthlineAnalytics` inside `application(_:didFinishLaunchingWithOptions:)` with the `tenantId` provided by Fourthline.

do {
  try FourthlineAnalytics.initialize(tenantId: "<tenantId provided by Fourthline>")
} catch let error as AnalyticsError {
  // Handle AnalyticsError
} catch {
  // Handle Error
}
 
// Set `TrackingConsent` to `.granted`
 FourthlineAnalytics.setTrackingConsent(consent: .granted)

Set up analytics observer

You can set up an analytics observer for the SDK to forward Fourthline events to.
Events are only forwarded when you initialize FourthlineAnalytics by calling FourthlineAnalytics.initialize(...) with TrackingConsent set to granted.

To set the observer, call FourthlineAnalytics.setObserver(...).

To remove the observer, call FourthlineAnalytics.removeObserver().

Example code:

import com.fourthline.analytics.AnalyticsObserver
import com.fourthline.analytics.FourthlineAnalytics

val observer = object : AnalyticsObserver {
    override fun log(event: String, attributes: Map<String, Any?>) {
        // Log the Fourthline event
    }
}

FourthlineAnalytics.setObserver(observer)
import FourthlineCore

let observer = AnalyticsManager()
FourthlineAnalytics.setObserver(observer) 

class AnalyticsManager: AnalyticsObserver {
  func log(event: String, attributes: [String: Codable]?) {
    // Log the Fourthline event
  }
}
3. Add data delegate

3. Add data delegate

To receive notifications for each data group that the SDK uploads to Fourthline and a copy of the data itself, add a data delegate.

Example code:

import com.fourthline.orca.Orca
import com.fourthline.orca.workflow.WorkflowResults.*
import com.fourthline.orca.workflow.workflow

Orca.workflow(context, validationCode)
  .configure(config)
  .customize(customisationConfig)
  .addDelegate { results ->
    when(results){
      is IDV.Address -> TODO()
      is IDV.DeviceMetadata -> TODO()
      is IDV.Document -> TODO()
      is IDV.DocumentVideo -> TODO()
      is IDV.Nfc -> TODO()
      is IDV.Person -> TODO()
      is IDV.Selfie -> TODO()
      is IDV.SelfieVideo -> TODO()
    }
  }
  .present { result -> }
import FourthlineSDK

class MyClass {
  func launchOrca() {
    let configuration = WorkflowConfig(networkEnvironment: .mock)
    let validationCode = "xxxxxxxx"
    Orca.workflow(validationCode: validationCode)
      .configure(with: configuration)
      .addDelegate(self)
      .present { [weak self] result in
        switch result {
        case let .failure(error):
          self?.handleError(error)
        case .success:
          // User has successfully finished the workflow.
          break
        }
      }
  }
}

// MARK: - WorkflowDataDelegate
extension MyClass: WorkflowDataDelegate {
  func didUploadData(_ data: FourthlineSDK.WorkflowResults) {
    switch data {
    case let .idv(value: idvPart):
      switch idvPart {
      case let .document(document):
        print("Did upload Document")
      case let .documentVideo(video):
        print("Did upload Document Video")
      case let .selfie(selfie):
        print("Did upload Selfie")
      case let .selfieVideo(video):
        print("Did upload Selfie Video")
      case let .nfc(nfc):
        print("Did upload Nfc")
      case let .address(address):
        print("Did upload Address")
      case let .person(person):
        print("Did upload Person")
      case let .deviceMetadata(deviceMetadata):
        print("Did upload Device Metadata")
      }
    default:
      print("Handle Workflow data...")
    }
  }
}
4. Delete temporary files

4. Delete temporary files

The SDKs store some data collected during workflows (e.g. selfie and document videos) in the tmp/fourthline folder in the client's device filesystem. This is because the videos must remain available until collected, packaged into a zipfile, and uploaded to our backend.

You must delete the temporary files when they are no longer needed, e.g. after the SDK has uploaded all data to Fourthline or immediately before the app is terminated in:

  • Android: onDestroy()
  • iOS: applicationWillTerminate

Example code:

context.deleteFourthlineFiles()
FourthlineFileManager.deleteFourthlineFiles(context);
FileManager.default.deleteFourthlineFiles()
5. Handle errors

5. Handle errors

You need to handle the following error values:

NameDescription
invalidValidationCodeThe validation code for the SDK session is invalid.
Action: Get a new validation code.
clientRejectedThe client isn't eligible for the Identity Verification workflow.
You can't retry.
canceledThe client canceled the workflow.
unexpectedAn unexpected error occurred.
Action: Contact your implementation manager immediately.
configurationNotSupportedThe workflow created with the validation code isn't supported.
Action: Consider updating to the latest SDK version.
moduleErrorThe client encountered an error in a workflow module.
Identity Verification:
PersonNotAdult: The client is underage.
NationalityNotSupported: The client's nationality isn't supported.
IssuingCountryNotSupported: The ID document issuing country isn't supported.
DocumentExpired: The ID document has expired.
DocumentTypeNotSupported: The ID document type isn't supported.
Bank Account Verification:
Failed: An unexpected generic error occurred.
KycRequired: The client must first pass Identity Verification.
Qualified Electronic Signature:
TooManyResendOtpAttempts: The one-time passcode was resent to the client too many times.
TooManyAuthorizationAttempts: The client tried to approve the documents to sign too many times.
KycRequired: The client must first pass Identity Verification.
7. Configure workflow modules

7. Configure Bank Account Verification

If your workflow includes Bank Account Verification, this module redirects to the Web SDK.

To redirect the client back to your app after completing the module in the web browser, you need to register a URL scheme.

For instructions, see Apple – Register your URL scheme.


Cross-platform plugins

To set up your plugin, follow these steps:

1. Check prerequisites

Cordova prerequisites

Android prerequisites

Minimum supported Android API level: 23

The plugin contains the following:

ContentDescription
Source file Fourthline.ktSubclasses the mobile Cordova plugin object (CordovaPlugin) that bridges the Cordova web environment and the fourthline-scanners framework
fourthline-scanners Android libraryContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Document, Biometrics, and NFC scanners
• Location provider
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with fourthline-scanners
Android frameworksProvide functionalities for fourthline-scanners:
fourthline-core: Orchestration and analytics functionality
fourthline-vision: Document and Biometrics scanners
fourthline-nfc: NFC scanner
fourthline-nfc-assets: NFC chip processing functionality
fourthline-kyc: Identity data management functionality
fourthline-sdk
Lottie: Animations functionality

To resolve the dependencies on Fourthline's Android SDK, declare and authenticate in our Maven repository:

1. Add your fourthlineGithubToken as a Gradle Property for your environment.

Note
Note
It is good practice to prevent committing tokens with your source code.
Consider configuring the token from your Gradle Home directory or providing it via the command line.

2. To support Kotlin and Androidx, make sure you have [email protected] platform.

3. As Kotlin 1.9 doesn't use the kotlin-android-extensions plugin generated by the Cordova framework, remove the apply plugin: 'kotlin-android-extensions' line from the /platforms/android/app/build.gradle file.

Note
Note
Data is transferred between Cordova and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.

iOS prerequisites

  • Minimum XCode version: 14.3
  • Minimum iOS deployment target: 12.0

The plugin contains the following:

ContentDescription
Source file Fourthline.swiftSubclasses the Cordova plugin object (CordovaPlugin) that bridges the Cordova web environment and the FourthlineScanners framework
FourthlineScanners iOS frameworkContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Document, Biometrics, and NFC scanners
• Location provider
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with FourthlineScanners
iOS frameworksProvide functionalities for FourthlineScanners:
FourthlineCore: Orchestration and analytics functionality
FourthlineVision: Document and Biometrics scanners
FourthlineNFC: NFC scanner
FourthlineKYC: Identity data management functionality
FourthlineSDK

Before you set up the plugin, make the following preparations:

1. In the Info.plist file, add the following keys required to access the camera and NFC functionalities:

<key>NSCameraUsageDescription</key>
<string>To verify your identity, please allow us to access your camera once only.</string>

2. To enable NFC functionality, in the XCode Signing & Capabilities tab, enable the Near Field Communication Tag Reading capability, containing the following values:

  • Tag-Specific Data Protocol (TAG)
  • Password Authenticated Connection Establishment (PACE)

Note
Note
The YOUR_PROJECT_NAME.entitlements file is added to your project automatically.

Entitlements file source code:

 <dict>
 <key>com.apple.developer.nfc.readersession.formats</key>
 <array>
 <string>TAG</string>
 <string>PACE</string>
 </array>
 </dict>

3. To access the NFC functionality, in the Info.plist file, add the following keys:

<key>NFCReaderUsageDescription</key>
<string>Please enable NFC in order to read the chip from your document</string>

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
 <string>A0000002471001</string>
 <string>A00000045645444C2D3031</string>
</array>

4. Optionally, to access the microphone functionality to record audio in the document and selfie videos, in the Info.plist file, add the following key:

<key>NSMicrophoneUsageDescription</key>
<string>To verify your identity, please allow access to the microphone</string>

5. Optionally, to access the client's device geolocation, in the Info.plist file, add the following keys:

<key>NSLocationWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dictionary>
	<key>FourthlineFullAuthorizationPurposeKey</key>
 <string>To verify your identity, your exact location is shared with us once only.</string>
</dictionary>

6. If customizing the fonts in the UI, add the font files to your project and to the projects' Info.plist file:

<key>UIAppFonts</key>
	<array>
		<string>Your-Font-Medium.ttf</string>
		<string>Your-Font-Regular.ttf</string>
	</array>

Note
Notes
• Data is transferred between Cordova and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.
• Fourthline's scanners are designed to be implemented and tested on a real mobile device. Launching them on the iOS simulator throws a scanner error.

Flutter prerequisites

Android prerequisites

Minimum supported API level: 23

The plugin contains the following:

ContentDescription
Source file FourthlinePlugin.ktSubclasses the Flutter plugin object (FlutterPlugin) that bridges the Flutter environment and the fourthline-scanners framework
fourthline-scanners Android libraryContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with fourthline-scanners

This plugin depends on Fourthline's Android SDK. To resolve the dependencies, declare and authenticate in Fourthline's Maven repository:

1. Add your fourthlineGithubToken as a Gradle property for your environment.

2. In your top level build.gradle file, link to Fourthline's repository:

allprojects {
 repositories {
 //...
 maven {
 url = URI("https://maven.pkg.github.com/Fourthline-com/FourthlineSDK-Android")
 credentials {
 username = ""
 password = property("fourthlineGithubToken").toString()
 }
 }
 }
}
Note
Notes
Data is transferred between Flutter and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.
For more information, see Flutter – Serializing JSON manually using dart:convert.

iOS prerequisites

  • Minimum XCode version: 14.3
  • Minimum iOS deployment target: 12.0

The plugin contains the following:

ContentDescription
Source file FourthlinePlugin.swiftSubclasses the mobile Flutter plugin object (FlutterPlugin) that bridges the Flutter environment and the FourthlineScanners framework
FourthlineScanners iOS frameworkContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with FourthlineScanners
iOS frameworksProvide functionalities for FourthlineScanners:
FourthlineCore: Orchestration and analytics functionality
FourthlineVision: Document and Biometrics scanners
FourthlineNFC: NFC scanner
FourthlineKYC: Identity data management functionality
FourthlineSDK
Datadog

Before you set up the plugin, make the following preparations:

1. In the Info.plist file, add the keys required to access the camera and NFC functionalities:

<key>NSCameraUsageDescription</key>
<string>To verify your identity, please allow us to access your camera once only.</string>

2. Optionally, for the NFC flow, add to the Info.plist file the keys required to access the NFC functionality:

<key>NFCReaderUsageDescription</key>
<string>Please enable NFC in order to read the chip from your document</string>

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
 <string>A0000002471001</string>
 <string>A00000045645444C2D3031</string>
</array>

3. Optionally, to record audio in the document and selfie videos, add to the Info.plist file the key required to access the microphone functionality:

<key>NSMicrophoneUsageDescription</key>
<string>To verify your identity, please allow access to the microphone</string>

4. Optionally, for the Location module, add to the Info.plist file the keys required to access the location functionality:

<key>NSLocationWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dictionary>
	<key>FourthlineFullAuthorizationPurposeKey</key>
 <string>To verify your identity, your exact location is shared with us once only.</string>
</dictionary>

5. In the XCode Signing & capabilities tab, enable the Near Field Communication Tag Reading capability.

6. If customizing the fonts in the UI, add the font files to your project and to the projects' Info.plist:

<key>UIAppFonts</key>
	<array>
		<string>Your-Font-Medium.ttf</string>
		<string>Your-Font-Regular.ttf</string>
	</array>

Note
Notes
• Data is transferred between Flutter and our plugin API via JSON formatted Strings, both as input configuration options and payload responses. For more information, see Flutter – Serializing JSON manually using dart:convert.
• Fourthline scanners are designed to be implemented and tested on a real mobile device. Launching them on the iOS simulator throws a scanner error.

React Native prerequisites

Android prerequisites

  • Minimum React Native version: 0.69.9
  • Minimum supported Android API level: 23
  • Minimum Kotlin version: 1.7.20
  • Minimum Gradle build tools version: 7.1.3

The plugin contains the following:

ContentDescription
Source file Fourthline.ktBridges the React Native environment and the fourthline-scanners framework
fourthline-scanners Android libraryContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Document, Biometrics, and NFC scanners
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with fourthline-scanners
Android frameworksProvide functionalities for fourthline-scanners:
fourthline-core: Orchestration and analytics functionality
fourthline-vision: Document and Biometrics scanners
fourthline-nfc: NFC scanner
fourthline-nfc-assets: NFC chip processing functionality
fourthline-kyc: Identity data management functionality
fourthline-sdk
Lottie: Animations functionality

To upgrade your Gradle build tools version:

1. Search build.gradle files for entries like classpath 'com.android.tools.build:gradle: and replace version with 7.1.3.

2. Search for the gradle folder, and in the file gradle/wrapper/gradle-wrapper.properties, change the property URL distributionUrl to Gradle version 7.4, or later, e.g.: distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

3. This plugin depends on Fourthline's Android SDK. To resolve the dependencies, declare and authenticate in Fourthline's Maven repository:

3.1 Add your fourthlineGithubToken as a Gradle Property for your environment.

Note
Notes
It is good practice to prevent committing tokens with your source code.
Consider configuring the token from your Gradle Home directory or providing it via the command line.

3.2 In your top level build.gradle file, link to Fourthline's repository:

allprojects {
 repositories {
 //...
 maven {
 url = URI("https://maven.pkg.github.com/Fourthline-com/FourthlineSDK-Android")
 credentials {
 username = ""
 password = property("fourthlineGithubToken").toString()
 }
 }
 }
}

Note
Note
Data is transferred between React Native and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.

iOS prerequisites

  • Minimum XCode version: 14.3
  • Minimum iOS deployment target: 12.4

The plugin contains the following:

ContentDescription
Source files Fourthline.swift
and Fourthline.m
Bridge the React Native environment and the FourthlineScanners framework
FourthlineScanners iOS frameworkContains the following drop-in modules:
• Identity Verification flow
• Workflows API
• Document, Biometrics, and NFC scanners
• Location provider
• Identity data validator and zipper
fourthline-adapters-json Android libraryProvides JSON interfacing with FourthlineScanners
iOS frameworksProvide functionalities for FourthlineScanners:
FourthlineCore: Orchestration and analytics functionality
FourthlineVision: Document and Biometrics scanners
FourthlineNFC: NFC scanner
FourthlineKYC: Identity data management functionality
FourthlineSDK

Before you set up the plugin, make the following preparations:

1. In the main project's General > Frameworks, libraries, and embedded content section, add libswiftVision.tbd.

2. In the Info.plist file, add the keys required to access the camera and NFC functionalities:

<key>NSCameraUsageDescription</key>
<string>To verify your identity, please allow us to access your camera once only.</string>

3. Optionally, for the NFC flow, add to the Info.plist file the keys required to access the NFC functionality:

<key>NFCReaderUsageDescription</key>
<string>Please enable NFC in order to read the chip from your document</string>

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
 <string>A0000002471001</string>
 <string>A00000045645444C2D3031</string>
</array>

4. In the XCode Signing & capabilities tab, enable the Near Field Communication Tag Reading capability.

5. Optionally, to record audio in the document and selfie videos, add to the Info.plist file the key required to access the microphone functionality:

<key>NSMicrophoneUsageDescription</key>
<string>To verify your identity, please allow access to the microphone</string>

6. Optionally, for the Location module, add to the Info.plist file the keys required to access the location functionality:

<key>NSLocationWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>To verify your identity, please allow access to your location.</string>

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dictionary>
	<key>FourthlineFullAuthorizationPurposeKey</key>
 <string>To verify your identity, your exact location is shared with us once only.</string>
</dictionary>

7. If customizing the fonts in the UI, add the font files to your project and to the projects' Info.plist file:

<key>UIAppFonts</key>
	<array>
		<string>Your-Font-Medium.ttf</string>
		<string>Your-Font-Regular.ttf</string>
	</array>

Note
Notes
• Data is transferred between React Native and our plugin API via JSON formatted Strings, both as input configuration options and payload responses.
• Fourthline's scanners are designed to be implemented and tested on a real mobile device. Launching them on the iOS simulator throws a scanner error.

2. Set up plugin

Cordova setup

Cordova setup

To setup the plugin, add com-fourthline-plugin-cordova to package.json using the following command:

cordova plugin add https://github.com/Fourthline-com/Fourthline-Cordova
Flutter setup

Flutter setup

To setup the plugin, follow these steps:

1. Set up SSH authentication using your GitHub account with permissions for Fourthline's plugin.
For instructions, see GitHub – Connecting to GitHub with SSH .

2. In your pubspec.yaml file, add a dependency on this file: [email protected]:fourthline-com/fourthline_flutter.git

dependencies:
 ...
 fourthline_plugin:
 git:
 url: [email protected]:fourthline-com/fourthline_flutter.git
 version: ^1.0.0
React Native setup

React Native setup

To setup the plugin, follow these steps:

1. In your React Native project root, execute the following command:

npm install https://github.com/Fourthline-com/Fourthline-React-Native

2. Go to the iOS folder, and then execute the following command:

pod install

3. In the source files that will use our plugin, add the following import:

import { NativeModules } from 'react-native';

3. Complete setup

Set up analytics

Set up analytics

The FourthlineCore module collects and processes metrics.

By default, analytics data collection is disabled, so no data is collected or shared with Fourthline without your consent.

To enable analytics data collection and sharing:

1. Initialize FourthlineAnalytics with the tenantId provided by Fourthline.

Note
Note
If you get an invalidTenantId error, ensure you are using the correct ID provided by Fourthline.

2. Set TrackingConsent using the following JSON format:

{
  "trackingConsent": string
}

The following values are possible:

ValueDescription
.pending
(default)
The SDK starts collecting and batching the data but doesn't send it to Fourthline.
It waits for a new tracking consent value to decide what to do with the batched data.
.grantedThe SDK collects data and sends it to Fourthline.
Any already batched data is sent to Fourthline.
.notGrantedThe SDK doesn't collect any data and events aren't sent to Fourthline.
Any batched data is wiped.
Debug modeThe SDK doesn't collect or send any data when running attached to the debugger.

If setting analytics tracking consent is:

  • Successful, the callback function doesn't receive any arguments.
  • Unsuccessful, the following JSON string is returned:
{
  "errorCode": number,
  "errorDescription": string
}

Note
Note
You can get a 2: Invalid JSON configuration error.

3. To change the TrackingConsent value after the SDK is initialized, make a FourthlineAnalytics.setTrackingConsent API request.

4. Set 3 JavaScript method parameters in the following order:

  1. JSON configuration as string
  2. Function to be executed on success
  3. Function to be executed on failure

The configuration passed to initialize analytics has the following JSON format:

{
  "tenantId": string
}

If analytics initialization is:

  • Successful, the callback function doesn't receive any arguments.
  • Unsuccessful, the following JSON string is returned:
{
  "errorCode": number,
  "errorDescription": string
}

The following error codes are possible:

Error codeDescriptionAction
0Invalid tenantIdEnsure you use the id provided by Fourthline.
1Datadog not imported
Android only
Ensure the Datadog import is enabled in plugin.xml.
2Datadog already initialized
Android only
10Invalid JSON configurationCorrect the JSON configuration.

Example code:

var config = `{
 "tenantId": "fl-xxxxxxxx"
 }`;

Fourthline.initializeAnalytics(
    config,
    function() {
        // Analytics successfully initialized
        // No further action required
    },
    function(error) {
        // Extract and process the information received in JSON error string format
        var jsonError = JSON.parse(error);
        // ...
    }
);

var trackingConsentConfig = `{
 "trackingConsent": "granted"
 }`;

Fourthline.setTrackingConsent(
   trackingConsentConfig,
    function() {
        // Tracking consent successfully updated
        // No further action required
    },
    function(error) {
        // Extract and process the information received in JSON error string format
        var jsonError = JSON.parse(error);
        // ...
    }
);
try {
  String config = '{"tenantId": "Ten-xxxxxxxFL"}';
  await _fourthlinePlugin.initializeAnalytics(config) ??
          "Could not initialize analytics";
  // Analytics successfully initialized
  // No further action required
} on PlatformException catch (e) {
	String? message = e.message;
 	 switch (e.code) {
    case "0":
      print('Error invalid tenant Id: $message');
      break;
  	}
};

try {
  String config = '{"trackingConsent": "granted"}';
  await _fourthlinePlugin.setTrackingConsent(config) ??
          "Could not set tracking consent";
  // Tracking consent successfully updated
  // No further action required
} on PlatformException catch (e) {
  // Extract and process the information from the error
};

// Instance variable defined in your Dart class
final _fourthlinePlugin = Fourthline();
import { NativeModules } from 'react-native'

var config = `{
 "tenantId": "fl-xxxxxxxx"
 }`;

NativeModules.Fourthline.initializeAnalytics(config)
    .then(() => {
        // Analytics successfully initialized
        // No further action required
    })
    .catch((error) => {
        // Extract and process the information received in JSON error string format
        var jsonError = JSON.parse(error.message);
        // ...
    });
    
var trackingConsentConfig = `{
 "trackingConsent": "granted"
 }`;
 
NativeModules.Fourthline.setTrackingConsent(trackingConsentConfig)
    .then(() => {
        // Tracking consent successfully updated
        // No further action required
    })
    .catch((error) => {
        // Extract and process the information received in JSON error string format
        var jsonError = JSON.parse(error.message);
        // ...
    });
    

Analytics observer

You can set up an analytics observer for the SDK to forward Fourthline events to.
Events are only forwarded when you initialize FourthlineAnalytics by calling FourthlineAnalytics.initialize(...) and TrackingConsent is set to granted.

To set the observer, call FourthlineAnalytics.setObserver(...).

To remove the observer, call FourthlineAnalytics.removeObserver().

Example code:

Fourthline.setAnalyticsObserver(
    function(eventData) {
        // Handle eventData
    }
);
import 'package:flutter/services.dart';
import 'package:fourthline/fourthline.dart';

class _ExampleWidgetState extends State<ExampleWidget> {
  StreamSubscription<dynamic>? _eventSubscription;

  @override
  void initState() {
    super.initState();

    // Start observing analytics events
    await _fourthlinePlugin.setAnalyticsObserver() ?? "Could not set analytics observer";
    
    // Start listening to the event channel
    _eventSubscription = Fourthline.analyticsEventChannel
        .receiveBroadcastStream()
        .listen(_handleAnalyticsEvent, onError: null);

  }

  @override
  void dispose() {
    // Clean up the listener when the widget is disposed
    _eventSubscription?.cancel();

    // Stop observing analytics events
    await _fourthlinePlugin.removeAnalyticsObserver() ?? "Could not remove analytics observer";

    super.dispose();
  }

  void _handleAnalyticsEvent(dynamic data) {
    // Handle the custom event
    print('Received event: $data');
  }

  // ... rest of your widget
}
import { NativeEventEmitter, NativeModules } from 'react-native'

const analyticsManagerEmitter = new NativeEventEmitter(NativeModules.Fourthline);

// Subscribe
analyticsEventListener = analyticsManagerEmitter.addListener(
      'fourthlineAnalytics',
       (eventJson) => {
         // Handle the Fourthline event
    });

// Unsubscribe
analyticsEventListener.remove();
NativeModules.Fourthline.removeListener('fourthlineAnalytics');

Example code for tracked event:

{
  "event": string,
  "attributes": Object
}
Configure workflow

Configure workflow

Pass the following JSON configuration to the workflow:

{
 "configuration": WorkflowConfiguration,
 "customization": WorkflowCustomization
}

WorkflowConfiguration has the following format:

{
 "networkEnvironment": NetworkEnvironment, // To test a workflow locally use .mock, and to test workflow networking use .sandbox
 "validationCode": string, // Returned in the Create SDK session response
}

NetworkEnvironment can have the following values:

ValueDescription
productionLive environment
sandboxRemote testing environment
mockLocal testing environment with stubbed data

To get the ValidationCode, make a Create SDK session request.

WorkflowCustomization is an optional field.
To customize the look and feel of the UI, see App Drop-in UI Customization.
It has the following format:

{
 "flavor": string
}

Example code:

var config = `{
 "configuration": {
 "validationCode": "123456",
 "networkEnvironment": "sandbox"
 },
 "customization": {
 "flavor": {
 "colors": ${orcaColors},
 "fonts": ${orcaFonts},
 "localization": ${orcaLocalization},
 "layouts": ${orcaLayout}
 }
 }
}`;

Fourthline.startWorkflow(config,
 function(msg) {
 // Client has successfully completed the workflow
 // No further action required
 },
 function(error) {
 // Extract and process the information received in JSON error string format
 var jsonError = JSON.parse(error.message);
 }
);
String config = """{
 "configuration": {
 "validationCode": "123456",
 "networkEnvironment": "sandbox"
 },
 "customization": {
 "flavor": {
 "colors": $orcaColors,
 "fonts": $orcaFonts,
 "localization": $orcaLocalization,
 "layouts": $orcaLayout
 }
 }
}
""";

try {
 String result = await _fourthlinePlugin.startWorkflow(config) ?? "";
 // Client has successfully completed the workflow
 } on Exception catch (e) {
 // Extract and process the information from the error
 String? message = e.message;
 switch (e.code) {
 case "803":
 print('User canceled $message');
 break;
 case "1000":
 print('Client rejected');
 break;
 }
 };
);
var config = `{
 "configuration": {
 "validationCode": "123456",
 "networkEnvironment": "sandbox"
 },
 "customization": {
 "flavor": {
 "colors": ${orcaColors},
 "fonts": ${orcaFonts},
 "localization": ${orcaLocalization},
 "layouts": ${orcaLayout}
 }
 }
}`;

NativeModules.Fourthline.startWorkflow(config)
	.then((msg) => {
 // Client has successfully completed the workflow
 // No further action required
	})
	.catch((error) => {
		// Extract and process the information received in JSON error string format
		var jsonError = JSON.parse(error.message);
	});

If the workflow is:

  • Successful, all results are already processed and no additional response is returned
  • Unsuccessful, the following JSON string is returned:
{
 "errorCode": number,
 "errorDescription": string
}

The following error codes are possible:

Error codeDescriptionAction
800Decoding errorCheck the errorDescription for more information.
802Invalid or missing fontCheck the errorDescription for more information.
803User canceledThe client explicitly canceled the workflow.
830JSON parse errorCheck the JSON provided.
850Incorrect configurationEnsure the workflow is configured correctly.
870Unexpected + messageInform your implementation manager immediately.
1000ClientRejectedThe client isn't eligible for the workflow.
You cannot retry.
1001InvalidValidationCodeMake a new Create SDK session request.
1002Module error + messageThe client encountered an error in one of the workflow modules.
Check the message for more information.
1003ConfigurationNotSupported + messageThe workflow created using the validationCode isn't supported.
Consider updating to the latest plugin version.
1004InvalidWorkflowStatusCheck if the workflow module is already completed successfully or with an error.
Add data observer

Add data observer

To receive notifications for each data group that the SDK uploads to Fourthline and a copy of the data itself, add a data observer.

Example code:

Fourthline.setWorkflowDataObserver(
 function(dataJson) {
 // Handle dataJson
 }
);

// Remove observer
Fourthline.removeWorkflowDataObserver();
import 'package:flutter/services.dart';
import 'package:fourthline/fourthline.dart';

class _ExampleWidgetState extends State<ExampleWidget> {
 StreamSubscription<dynamic>? _workflowDataSubscription;

 @override
 void initState() {
 super.initState();

 // Start listening to the event channel
 _workflowDataSubscription = Fourthline.workflowDataEventChannel
 .receiveBroadcastStream()
 .listen(_handleWorkflowDataEvent, onError: null);

	// Start a workflow
 }

 @override
 void dispose() {
 // Clean up the listener when the widget is disposed
 _workflowDataSubscription?.cancel();

 super.dispose();
 }
 
 void _startWorkflow() {
 String config = """{
 "configuration": {
 "validationCode": "IDV",
 "networkEnvironment": "mock"
 }
 }
 """;
 try {
 String result = await _fourthlinePlugin.startWorkflow(config) ?? "";
 } on Exception catch (e) {
 showAlertDialog("Error", e.toString());
 };
 }

 void _handleWorkflowDataEvent(dynamic data) {
 // Handle the data upload event
 print('Uploaded data: $data');
 }
}
import { NativeEventEmitter, NativeModules } from 'react-native'
const eventManagerEmitter = new NativeEventEmitter(NativeModules.Fourthline);
// Subscribe
workflowDataListener = eventManagerEmitter(
      ‘fourthlineWorkflowData’,
       (dataJson) => {
         // handle the workflow data...
    });
// Unsubscribe
workflowDataListener.remove();
NativeModules.Fourthline.removeListener('fourthlineWorkflowData');

The notifications per data type have the following JSON structure:

"idv":{
  "document":{
    "type":"string",
    "number":"string",
    "issueDate":"string", // Optional, format YYYY-MM-DD
    "expirationDate":"string", // Optional, format YYYY-MM-DD
    "images":[
      {
        "image":"string",
        "fileSide":"string",
        "isAngled":"boolean",
        "timestamp":"string", // Optional, format "YYYY-MM-dd'T'HH:mm:ssZZZZZ"
        "location":{
          "latitude":"number",
          "longitude":"number"
        }
      }
    ]
  }
}
"idv":{
  "documentVideo":{
    "url":"string",
    "duration":"string", // Default / extended
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}
"idv":{
  "selfie":{
    "image":"string",
    "timestamp":"string", // Optional
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}
"idv":{
  "selfieVideo":{
    "url":"string",
    "duration":"string", // Default / extended
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}

"idv":{
  "nfc":{
    "image":"string", // Optional
    "timestamp":"string",
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    },
    "mrz":"string",
    "dataGroups":[ // Optional
      {
        "groupNumber":"Int",
        "data":"string"
      }
    ]
  }
}
"idv":{
  "address":{
    "street":"string",
    "streetNumber":"Int",
    "streetNumberSuffix":"string", // Optional
    "postalCode":"string",
    "city":"string",
    "countryCode":"string",
    "region":"string" // Optional
  }
}
"idv":{
  "person":{
    "firstName":"string",
    "middleName":"string", // Optional
    "lastName":"string",
    "gender":"string",
    "nationalityCode":"string",
    "birthCountryCode":"string", // Optional
    "birthPlace":"string", // Optional
    "birthDate":"string" // Format YYYY-MM-DD
  }
}
"idv":{
  "deviceMetadata":{
    "model":"string",
    "sdkVersion":"string",
    "osVersion":"string",
    "language":"string",
    "osCompromised":"string",
    "location":{ // Optional
      "latitude":"number",
      "longitude":"number"
    }
  }
}
Delete temporary files

Delete temporary files

The plugins store some data collected during workflows (e.g. selfie and document videos) in the tmp/fourthline folder in the client's device filesystem. This is because the videos must remain available until collected, packaged into the case zipfile, and uploaded to our backend.

You must delete the temporary files when they are no longer needed, e.g. after the SDK has uploaded all data to Fourthline or immediately before the app is terminated in:

  • Android: onDestroy()
  • iOS: applicationWillTerminate

Example code:

Fourthline.deleteFourthlineFiles(
 function() {
 // Fourthline files deleted
 }
);
await _fourthlinePlugin.deleteFourthlineFiles();

// Instance variable defined in your Dart class
final _fourthlinePlugin = Fourthline();
import { NativeModules } from 'react-native'

NativeModules.Fourthline.deleteFourthlineFiles().then(() => {
 	// Fourthline files deleted
 });

Success
Success
You have configured and set up your App Drop-in!
To integrate your solutions, see the Integration Guides.

Top of page

Accordion in HTML5