Verifai iOS SDK (v 4.0.1)
Welcome to the Verifai App implementation documentation. If you have any questions that are unanswered you can always contact our support.
This documentation will continue to expand as we add extra services.
Older versions
If you're looking for documentation for previous versions of Verifai then check below:
Version | Link |
---|---|
3.4.x |
Documentation |
Quick start guide
Modules
Verifai is modular with the following modules:
- Verifai
- VerifaiNFC
- VerifaiLiveness
- VerifaiManualDataCrosscheck
- VerifaiManualSecurityFeatureCheck
iOS has split up the package into these modules, plus another VerifaiCommons
module.
This module contains shared models and functionality that the different modules require.
From an implementation standpoint, though, there are the following relevant portions:
- Setting a shared licence for all modules
- Attaching to the Verifai logger
Setting a shared licence
Verifai requires a licence to be used in all modules.
In order to make this easier and less error-prone we have moved all licencing calls to the VerifaiCommons
module, such that all other modules (i.e. Verifai
, VerifaiNFC
etc.) can request the licence from this shared module.
Attaching to the Verifai logger
NOTE: this is for debugging purposes only.
You can attach a VerifaiLogger
to the VerifaiCommons
module to read the log output from all the different Verifai modules.
This includes four levels of severity, listed in increasing severity:
- Debug
- Info
- Warning
- Error
Required keys in Info.plist
In order to use Verifai there are multiple required keys in Info.plist
:
key | Verifai | VerifaiNFC | VerifaiLiveness | VerifaiManualDataCrosscheck | VerifaiManualSecurityFeatureCheck |
---|---|---|---|---|---|
NSCameraUsageDescription | Yes | - | Yes | - | - |
NSMicrophoneUsageDescription | - | - | Yes | - | - |
NSSpeechRecognitionUsageDescription | - | - | Yes | - | - |
NFCReaderUsageDescription | - | Yes | - | - | - |
com.apple.developer.nfc.readersession.iso7816.select-identifiers | - | Yes | - | - | - |
- Import the right module for your project and set the licence in the shared
VerifaiCommons
module to allow every module to use this licence without having to individually set any licences. - [Optional] Set a configuration for the flow of
Verifai
to lead the user through a more specific flow suitable for your use-case. - Start the desired module.
- Receive the result from this flow and utilize it further in your own application.
These four steps are further described in the following sections.
1. Import and setting the licence
Check out the table below for a reference of which modules you need depending on the functionality you need.
Feature | 4.x import |
---|---|
Document scanning (Automatic & manual scanning) | Verifai and VerifaiCommons |
Document scanning + NFC scanning | Verifai and VerifaiCommons + VerifaiNFC |
Document scanning + Liveness check | Verifai and VerifaiCommons + VerifaiLiveness |
Document scanning + NFC scanning + Liveness check | Verifai and VerifaiCommons + VerifaiNFC + VerifaiLiveness |
Document scanning + VIZ check | Verifai and VerifaiCommons + VerifaiManualDataCrosscheck |
Document scanning + Security checks | Verifai and VerifaiCommons + VerifaiManualSecurityFeatureCheck |
// Top of file
import VerifaiCommons
// Further on, i.e. application:didFinishLaunchingWithOptions:
let licenceString = "=== Verifai Licence file V2 ===[...]"
switch VerifaiCommons.setLicence(licenceString) {
case .success(_):
print("Successfully configured Verifai")
case .failure(let error):
print("π« Licence error: \(error)")
}
Setting the licence is as easy as supplying a raw String
to the VerifaiCommons
module. Please note that the === Verifai Licence file V2 ===
licence header should always be included in the licence.
2. Configuration
We think that every company is unique and requires changes to accommodate the use-case in the SDKs. You can change quite a lot, ranging from the colors to the internal workings by making your own validators and enabling of disabling certain features.
Check out our configuration options to see how you can configure the flow in the SDK.
For iOS specific configuration check out the Advanced configuration section.
3. Start Verifai
Starting Verifai
do {
try Verifai.start(over: self) { result in
switch result {
case .failure(let err):
print("Error or cancellation: \(err)")
// Or look for a specific error
if case VerifaiFlowCancelError.flowCancelled = error {
handleVerifaiCancellation()
}
case .success(let result):
// Continue with the result
let frontImage = result.frontImage
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
You can start Verifai by calling the start(over:)
method.
This start Verifai and presents itself over the viewController: UIViewController
that was supplied.
This starts the entire flow which, when finished, automatically dismisses the presented view controller and calls the resultBlock
block.
This has multiple implications:
- It is no longer possible to include the Verifai flow in a horizontal (navigation stack only) navigation flow. There are plans to include this in subsequent releases.
- If you want the user to be able to cancel Verifai you have to supply the possibility to do so yourself. All the calls to start modally return a
UINavigationController
, which you can then use to supply a cancel button.
This general pattern is also applicable for the other Verifai modules:
VerifaiNFC
VerifaiLiveness
VerifaiManualDataCrosscheck
VerifaiManualSecurityFeatureCheck
Start VerifaiNFC
Starting Verifai NFC
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
do {
try VerifaiNFC.start(over: self, documentData: result, retrieveImage: true) { nfcResult in
switch nfcResult {
case .failure(_):
print("Error or cancellation")
// Or look for a specific error
if case VerifaiNFCError.nfcNotAvailable = error {
handleVerifaiError()
}
case .success(let nfcResult):
// Continue with result
let photo = nfcResult.photo
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Consult the code example on the right side to for an example of how to start and handle results from VerifaiNFC
.
Also make sure you have added the required values to your Info.plist file. For more in check out the Project setup for NFC section.
Start VerifaiLiveness
Starting Verifai Liveness
do {
try VerifaiLiveness.start(over: self) { result in
switch result {
case .failure(_):
print("Error or cancellation")
case .success(let livenessResult):
// Continue with result
let checksPassed = livenessResult.automaticChecksPassed
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Consult the code example on the right side to for an example of how to start and handle results from VerifaiLiveness
Start VerifaiManualDataCrosscheck
Starting Verifai Manual Data Crosscheck
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
// Optional, adds an extra check if the photo area is unblocked
let nfcResult: VerifaiNFCResult?
do {
try VerifaiManualDataCrosscheck.start(over: self,
documentData: result,
nfcImage: nfcResult?.photo) { mdcsResult in
// Handle result
switch mdcsResult {
case .success(let checkResult):
// Continue with result
let allChecksPassed = checkResult.passedAll
// etc....
case .failure(let error):
print("Error or cancellation: \(error)")
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Consult the code example on the right side to for an example of how to start and handle results from VerifaiManualDataCrosscheck
Start VerifaiManualSecurityFeatureCheck
Starting Verifai Manual Security Feature check
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
do {
try VerifaiManualSecurityFeatureCheck.start(over: self, documentData: result) { result in
switch result {
case .failure(let error):
print("Error or cancellation: \(error)")
case .success(let checkResult):
// Continue with result
let checksPassed = checkResult.passed
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Consult the code example on the right side to for an example of how to start and handle results from VerifaiManualSecurityFeatureCheck
4. Process the result
Check out our result processing guide for more info on the results you can get from Verifai.
General info
Prerequisites
- A valid Verifai Licence
- iOS 10 or later - a note on iOS 10
- Xcode 11 or later
- A physical iOS device to test the integration (SDK does not run on Simulator)
Example project
All the concepts documented so far have also been included in the example app that you can download to see a working example of Verifai.
Supported orientations
We've built the SDK to be as flexible as possible on many types of screens. Keeping this in mind we don't force any orientation programmatically. Currently the SDK is tested and is supported to run in portrait mode for phone sized devices. For tablet sized devices we support both portrait and landscape orientations.
Installation
There are multiple ways to install the Verifai SDK in your app. You can install automatically through CocoaPods or Carthage (recommended), or manually.
CocoaPods
CocoaPods is a dependency manager for iOS projects.
Verifai is modular with the following modules:
Verifai
VerifaiNFC
VerifaiLiveness
VerifaiManualDataCrosscheck
VerifaiManualSecurityFeatureCheck
.
Plus the shared module VerifaiCommons
To add the full SDK through Cocoapods add the following lines to your Podfile
:
pod 'Verifai', '~> 4.0.1'
Additionally you can add the NFC or Liveness check modules if you so require.
pod 'VerifaiNFC', '~> 4.0.1'
pod 'VerifaiLiveness', '~> 4.0.1'
pod 'VerifaiManualDataCrosscheck', '~>4.0.1'
pod 'VerifaiManualSecurityFeatureCheck', '~> 4.0.1'
Carthage
Carthage is a simple, decentralized dependency manager.
If you're using Carthage you'll have to update your Cartfile to load the new versions of the framework. Because each module is now separate they all have to be loaded separately. Place the following lines in your Cartfile
Core is always required:
binary "https://dashboard.verifai.com/downloads/sdk/core/carthage.json"
Optional components:
binary "https://dashboard.verifai.com/downloads/sdk/nfc/carthage.json"
binary "https://dashboard.verifai.com/downloads/sdk/liveness-check/carthage.json"
binary "https://dashboard.verifai.com/downloads/sdk/manual-data-crosscheck/carthage.json"
binary "https://dashboard.verifai.com/downloads/sdk/manual-security-features-check/carthage.json"
Manually
Finally, it is also possible to manually install the framework.
- Download the Verifai modules along with the required support frameworks provided by the download from the Verifai Dashboard
- Add the frameworks you downloaded from our backend into you project:
- In Xcode right click on the folder where you want the framework files and choose
Add files to "Folder_Name"
- Select the frameworks (i.e.
Verifai.framework
) you want to add and press onAdd
- Alternatively you can drag the
.framework
files into the right folder in Xcode
- In Xcode right click on the folder where you want the framework files and choose
- Make sure that the framework folder is included in
Project -> Build Settings -> Search Paths -> Framework Search Paths
. For example: if the frameworks reside in theProject Root/Frameworks
folder, add the entry$(PROJECT_DIR)/Frameworks
to theFramework Search Paths
. - One final note on manually adding frameworks: when publishing your app to the App Store Apple will only accept an archive which contains iOS device binaries (so no simulator binaries).
Since universal binaries are delivered (both simulator and device) the frameworks contain both architectures. As such, you may need to strip the provided framework binaries to get rid of the simulator architectures (x86 and i386). Dependency managers like CocoaPods and Carthage do this automatically for you.
When debugging on your device Xcode also automatically does this for you, but it doesn't when Archiving. There are a multitude of tools and automatic scripts to find which fix this for you, but it is also possible to use the provided script from Carthage (
/usr/local/bin/carthage copy-frameworks
). Make sure to provide the proper paths to the framework binaries (e.g.$(PROJECT_DIR)/Frameworks
) to the input files, resulting in e.g.$(PROJECT_DIR)/Frameworks/Verifai.framework
. Also make sure to put in the right output files to e.g.$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Verifai.framework
.
More info here
Advanced
Set a configuration for Verifai
Setting up the configuration
let config = VerifaiConfiguration(enableAutomatic: false,
requireDocumentCopy: true,
enablePostCropping: false,
requireNFCWhenAvailable: true)
// Extra configuration
config.showInstructionScreens = true
config.scanDuration = 2.0
do {
try Verifai.configure(with: config)
} catch VerifaiConfigurationError.invalidConfiguration(let description) {
print("π« Invalid configuration: " + description)
} catch {
print("π« An error occurred while setting the configuration: \(error)")
}
In order to set a custom configuration for Verifai
you have to supply a VerifaiConfiguration
.
This configuration can then be set using Verifai.configure(with:)
, during which the configuration will be checked for errors.
Extra configuration options:
Configuration option | Description | Default value |
---|---|---|
validators |
Array of validators that will be run after the automatic or manual scans | empty VerifaiValidator array |
documentFilters |
Array of document filters that determine which documents a user can select in the manual flow | empty VerifaiDocumentFilter array |
documentFiltersAutoCreateValidators |
Whether setting document filters automatically creates validators for the automatic scan views | true |
countryCode |
Alpha 2 country code, used to customize the ai network scan, determined by your phone's region code (currently only "NL" is available) | none |
customDismissButtonTitle |
Dismiss button string value | nil |
scanDuration |
Scan length in seconds | 3.0 |
showInstructionScreens |
Whether we should show the instruction screens before key events in the flow | true |
Note on the Dismiss button
On iOS it's also possible to configure the dismiss bar button item title for the modally presented Verifai view. To do this set the value of customDismissButtonTitle
inside the VerifaiConfiguration
. It is your responsibility to provide the string with the right translation. If no string is provided then Verifai will default to using Cancel
. In this case Verifai will also take care of translating this string.
Note on Instruction screens
There are 5 Instruction screens provided by the SDK that will get displayed before the following key events:
When | What does it explain |
---|---|
Before an AI scan | How to take an image of a document |
Before an OCR scan | Asks the user if the document has an MRZ and explains how it looks like, then explains how to scan that MRZ |
More information about flow configurations for Verifai can be found here: Enabling and disabling features
Verifai Document Filters
Example document filter setup, in this example only Dutch passports and drivers licences options are shown to the user when he needs to manually select a document
let configuration = VerifaiConfiguration()
configuration.documentFilters = [
VerifaiDocumentTypeWhiteListFilter(validDocumentTypes: [.passport, .driversLicence]),
VerifaiDocumentWhiteListFilter(countryCodes: ["NL"])
]
Document filters allow you to control the documents and countries shown to the user in the document selection screen (shown above). There are currently 3 types of document filters:
Filter | Description |
---|---|
VerifaiDocumentTypeWhiteListFilter |
Only document types provided in this filter will be shown. If no filter is set, all document types are shown. |
VerifaiDocumentWhiteListFilter |
Only countries provided to this filter's Alpha 2 country list will be shown to the user in the country selection step. |
VerifaiDocumentBlackListFilter |
Countries provided to this filter's Alpha 2 country list will be removed from the complete list in the country selection step. |
You can set these filters in the documentFilters
property of the VerifaiConfiguration
object. On the right you can see an example and how these filter can be set.
Document filters and validators
Document filters and validators work differently from each other. A document filter acts on the selection steps of the Verifai flow. While the validators check if what was selected or scanned (in the automatic flow) is allowed.
We understand that these two items often have a relationship with each other. For example if you add a document filter to only show Dutch documents ("NL") then you probably also want a validator that checks that the document that was scanned is a Dutch document.
To facilitate this behaviour we added the documentFiltersAutoCreateValidators
flag to the VerifaiConfiguration
object. Its default is true
and it will automatically create and add validators that match the document filters set.
Of course you are always free to set this flag to false
and set your own validators and or filters. In this way you can for example create a flow where you only show passports and id cards in the document selection but also allows drivers licences to be valid scan results.
If your business needs require you to change the document filters on a per scan basis please keep in mind that having the documentFiltersAutoCreateValidators
flag set to true will keep adding validators to your validators list. In this case you might want to manually clear the validators
array in the VerifaiConfiguration
object before adding or removing document filters.
VerifaiResult
As briefly described in Result processing iOS also provide a VerifaiResultFlowInformation
object in the VerifaiResult
object. This object provides info about the flow the user followed when trying to scan a document and ending up in the full manual flow. This allows you to get some possible clues of what the user was trying to scan. If a user succesfully followed the automatic flow or OCR assisted flow then the value of the VerifaiResultFlowInformation
object wil be nil.
A description of the object can be found below.
Value | Description | Type |
---|---|---|
selectedCountryCode |
The country a user selected in the country selection screen | String? |
selectedDocumentType |
The document type a user selected in the document type selector screen | VerifaiDocumentType? |
selectedCountryCode |
The document size a user elected when starting the manual flow. | VerifaiDocumentDisplaySize? |
And some info on the VerifaiDocumentDisplaySize
object:
Value | Description |
---|---|
passport |
The document has the size format of a passport |
creditcard |
The document has the size format of a credit card |
VerifaiNFC
Starting Verifai NFC
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
do {
try VerifaiNFC.start(over: self, documentData: result, retrieveImage: true) { nfcResult in
switch nfcResult {
case .failure(_):
print("Error or cancellation")
case .success(let nfcResult):
// Continue with result
let photo = nfcResult.photo
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Starting the NFC module is very similar to starting the other modules by calling VerifaiNFC.start(over:[...])
.
There are multiple required parameters:
documentData: VerifaiResult
: This is the result that was obtained withVerifai
, including the required NFC key for accessing NFC data on the chip.retrieveImage: Bool
: Whether or not to retrieve the photo from the document. This is a lengthy process which can take up to 30 seconds, so it might not be necessary for many use-cases.
There are also some additional optional parameters:
showDismissButton: Bool = true
: Whether the dismiss button on the presented modal view should be showncustomDismissButtonTitle: String? = nil
: A custom title for the dismiss button of the modally presented view. Defaults to"Cancel"
.showInstructionScreens: Bool = true
: Whether the NFC instruction screen is displayed before the process starts
The NFC instruction screen
If the NFC instruction screen setting is true then an instructional screen with a video will be shown to the user before scanning an NFC document. This screen explains what the user can expect and how to hold the device to the document to correctly scan the NFC.
Project setup for NFC
Before being able to use the NFC module you need to add the plist keys on the right to your Info.plist file.
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
<string>A00000045645444C2D3031</string>
</array>
You also need to add a string with a message that tells the user why the app is requesting access to the deviceβs NFC hardware. Add it to your project's Info.plist file (NFCReaderUsageDescription key on the right).
<key>NFCReaderUsageDescription</key>
<string>NFC permission here!</string>
Lastly you need to add the NFC capability to your app. Select your project in Xcode and go to the Signing and Capabilities
tab (Next to General
). Press the +
button on the top left and a window will pop up where you can search for capabilities.
Search for Near Field Communication Tag Reading
and add it to your project. More info here.
NFC Availability
Check NFC Availability
guard VerifaiNFC.nfcAvailable() else {
print("NFC not available")
return
}
On device NFC scanning of documents is available starting on iOS 13. Not all supported iOS 13 devices have the right NFC hardware to perform an NFC scan.
If you try starting a scan on a device that doesn't support NFC scanning a VerifaiNFCError.nfcNotAvailable
error will be thrown when calling VerifaiNFC.start
.
Before starting the NFC module you should check if you're device supports it. We've added a function to check this. You can find an example on the right.
VerifaiLiveness
Starting Verifai Liveness
do {
try VerifaiLiveness.start(over: self) { (result) in
switch result {
case .failure(_):
print("Error or cancellation")
case .success(let livenessResult):
// Continue with result
let checksPassed = livenessResult.automaticChecksPassed
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
The most basic way to start the liveness checks is to just call VerifaiLiveness.start(over:)
.
This only offers a small amount of functionality, so in order to take full advantage of the provided checks you have to supply VerifaiLiveness with more parameters.
The full signature can be viewed on the right side.
Full signature
public static func start(over viewController: UIViewController,
requirements: [VerifaiLivenessCheck]? = nil,
videoLocation: URL? = nil,
showDismissButton: Bool = true,
customDismissButtonTitle: String? = nil,
resultBlock: @escaping VerifaiResultBlock<VerifaiLivenessCheckResults>) throws -> UINavigationController
Example of using some custom checks
static func performLivenessCheck(presenter: UIViewController) {
// Setup where the checks will be saved (like in the documents folder)
guard let documentsPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
print("Unable to find documents folder")
return
}
// Setup the checks
let selfieCheck = VerifaiSelfieLivenessCheck(instruction: "Your custom instruction message for the
check or nil if you want to use the default one")
guard let headTiltCheck = VerifaiTiltLivenessCheck(faceAngle: 20.0,
instruction: "Your custom instruction message for the check or
nil if you want to use the default one") else {
print("Invalid check setup, we validate some tests before accepting them")
return
}
// Define requirements
let checkRequirements = [
selfieCheck,
headTiltCheck
]
do {
try VerifaiLiveness.start(over: presenter,
requirements: checkRequirements,
videoLocation: documentsPathURL,
showDismissButton: true,
customDismissButtonTitle: nil,
resultBlock: { checkResult in
switch checkResult {
case .failure:
print("Error or cancellation")
case .success(let livenessResult):
// Continue with result
let checksPassed = livenessResult.automaticChecksPassed
dump(checksPassed) // If all checks passed
// You'll see 2 result objects after the next dump,
// in the recordingUrl for one you'll find an mp4 for one check and a jpg for the other
dump(livenessResult.resultList)
}
})
} catch {
print("π« Unhandled error: \(error)")
}
}
You can also set the Liveness check to use a more custom set of checks that you can setup yourself. On the example on the right we run the liveness check only with a selfie check and a head tilt check. You can also use custom initializers that we provided to use the default instruction. These initializers can be found further below at the Requirements part of this document.
Video location
If desired the recordings can be saved to a location on the device. Set the videoLocation
URL to indicate where the recordings will be saved. The exact url for each result gets returned in the result object. If you leave this empty then the checks will still be performed but nothing will be recorded. In that case all the result url's in the result object will be nil.
Dismiss button
The following parameters can be set while starting the liveness check to configure if and how the dismiss button is shown:
showDismissButton: Bool = true
: Whether the dismiss button on the presented modal view should be showncustomDismissButtonTitle: String? = nil
: A custom title for the dismiss button of the modally presented view. Defaults to"Cancel"
.
Requirements
The liveness check consists of a series of checks that the user has to proceed through.
A default list of five checks is already provided by the VerifaiLiveness.defaultRequirements()
function, which are also used as a default in the start method.
These requirements are all available requirements, but randomly shuffled.
If you want to have control over which checks are displayed and in what order you can supply your own list of requirements. The following requirements are available:
Requirement | How to create |
---|---|
Speech | VerifaiSpeechLivenessCheck(speechRequirement:locale:) |
Left tilt | VerifaiTiltLivenessCheck.leftTiltLivenessCheck(faceAngle:) |
Right tilt | VerifaiTiltLivenessCheck.leftTiltLivenessCheck(faceAngle:) |
Close eyes | VerifaiEyesLivenessCheck(duration:) |
Selfie | VerifaiSelfieLivenessCheck() |
These are the only requirements allowed.
Subclassing VerifaiLivenessCheck
is not supported and will result in a failure with error VerifaiLCError.undefinedLivenessCheck
.
All these requirements provide a default localized instruction for the user, but you can also supply your own custom instruction string. An example of this can be seen on the right at the start of this segment.
Example:
let closeEyesCheck = VerifaiEyesLivenessCheck(duration: 2)
let tiltLeft = VerifaiTiltLivenessCheck.leftTiltLivenessCheck()
let tiltRight = VerifaiTiltLivenessCheck.rightTiltLivenessCheck()
let speech = VerifaiSpeechLivenessCheck(speechRequirement: "apple banana pizza",
locale: Locale(identifier: "en-US"))
let selfie = VerifaiSelfieLivenessCheck()
let requirements: [VerifaiLivenessCheck?] = [selfie,
tiltLeft,
speech,
closeEyesCheck,
tiltRight]
// Shuffle and filter out nil requirements
let filteredRequirements = requirements.shuffled().compactMap { $0 }
Check results
In order to see the actual results of the Liveness checks you have to supply a location where Verifai can save media of recordings or photos of the checks.
This location videoLocation: URL?
is nil
by default, indicating no recordings will be saved at all.
Links to the final recordings are provided in VerifaiLivenessCheckResult.recordingUrl: URL?
.
VerifaiManualDataCrosscheck
Starting Verifai Manual Data Crosscheck
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
// Optional, adds an extra check if the photo area is unblocked
let nfcResult: VerifaiNFCResult?
do {
try VerifaiManualDataCrosscheck.start(over: self,
documentData: result,
nfcImage: nfcResult?.photo) { mdcsResult in
// Handle result
switch mdcsResult {
case .success(let checkResult):
// Continue with result
let allChecksPassed = checkResult.passedAll
// etc....
case .failure(let error):
print("Error or cancellation: \(error)")
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Starting the Manual Data Crosscheck module is very similar to starting the other modules by calling VerifaiManualDataCrosscheck.start(over:[...])
.
There are multiple required parameters:
documentData: VerifaiResult
: This is the result that was obtained withVerifai
, including the required id model with info on the zones for the manual data crosscheck.
There are also some additional optional parameters:
nfcImage: UIImage? = nil
: Optional image from the NFC module. If this image is provided and the photo zone on the card isn't blocked then a Photo check might be added to the rest of the checks.numberOfChecks: Int = 3
: The number of checks that should be performed. If the amount of checks cannot be performed because areas are blocked then an error will be thrown.showDismissButton: Bool = true
: Whether the dismiss button on the presented modal view should be showncustomDismissButtonTitle: String? = nil
: A custom title for the dismiss button of the modally presented view. Defaults to"Cancel"
.
VerifaiManualSecurityFeatureCheck
Starting Verifai Manual Security Feature check
// Use result obtained earlier with `Verifai.start`
let result: VerifaiResult
do {
try VerifaiManualSecurityFeatureCheck.start(over: self, documentData: result) { result in
switch result {
case .failure(let error):
print("Error or cancellation: \(error)")
case .success(let checkResult):
// Continue with result
let checksPassed = checkResult.passed
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
Starting the Manual Data Crosscheck module is very similar to starting the other modules by calling VerifaiManualDataCrosscheck.start(over:[...])
.
There are multiple required parameters:
documentData: VerifaiResult
: This is the result that was obtained withVerifai
, including the required id model with info on the zones for the manual data crosscheck.
There are also some additional optional parameters:
scoreThreshold: Float = 1.0
: The core that should be reached for a successful check (0.0 - 1.0)showDismissButton: Bool = true
: Whether the dismiss button on the presented modal view should be showncustomDismissButtonTitle: String? = nil
: A custom title for the dismiss button of the modally presented view. Defaults to"Cancel"
.
Errors
What follows is an overview of the errors Verifai can return with a description of what causes them.
Verifai
Error | Type | Description | Possible solutions |
---|---|---|---|
flowCancelled |
VerifaiFlowCancelError |
The user cancelled out of the flow | Show an error condition or ask the user to retry |
neuralNetworkLoadingFailed |
VerifaiFlowCancelError |
Something went wrong loading the neural network | Make sure an internet connection is active and retry |
invalidConfiguration(_ description: String) |
VerifaiConfigurationError |
The configuration provided in Verifai.configure(with: is invalid. |
Check the description in the error, fix your configuration and retry. |
permissionDenied |
VerifaiCameraError |
The user denied the camera permission request | Request your user to go to your app's setting and enable the camera permission |
slowNetwork(_ timeout: TimeInterval) |
VerifaiNetworkError |
A timeout on the network has been detected | Check your internet connection and retry |
invalidRequest(_ underlyingError: Error?) |
VerifaiNetworkError |
And invalid request was triggered by the OS | Check the underlying iOS error for more info |
downloadFailed(_ underlyingError: Error?) |
VerifaiNetworkError |
A download operation failed | Check the underlying iOS error for more info |
VerifaiNFC
Error | Type | Description | Possible solutions |
---|---|---|---|
nfcReadError |
VerifaiNFCError |
Reading the NFC chip failed (you can retry) | Ask your user to hold the document firmly and retry |
nfcCancelled |
VerifaiNFCError |
The user cancelled the NFC reading operation | Show an error condition or ask the user to retry |
nfcNotAvailable |
VerifaiNFCError |
The current device does not support NFC scanning | Show an error condition |
nfcReadTimedOut |
VerifaiNFCError |
The NFC operation timed out | Show an error condition |
VerifaiLiveness
Error | Type | Description | Possible solutions |
---|---|---|---|
undefinedLivenessCheck |
VerifaiLCError |
Undefined liveness check submitted | Ensure you're using one of the provided liveness check types as subclassing is not allowed |
lowSpaceForOperation |
VerifaiLCError |
Low space detected on the device to save the liveness check data | Ask your user to free up space on the device and retry |
internalAVError |
VerifaiLCError |
An internal AV error occurred | An internal error occurred during recording, please try again |
cancelledLivenessChecks |
VerifaiLCError |
The user cancelled the liveness check operation | Show an error condition or ask the user to retry |
VerifaiManualDataCrosscheck
Error | Type | Description | Possible solutions |
---|---|---|---|
dataInvalid |
VerifaiManualDataCrosscheckError |
The manual data cross check could not be performed because the structure of the data appears to be invalid | Ensure the scanning data from Verifai has an idModel object to perform the check |
insufficientData |
VerifaiManualDataCrosscheckError |
The manual data cross check could not be performed because there aren't enough unblocked zones available | Either lower the amount of required checks or reassess your blocked zones on the Verifai Dashboard |
manualDataCrosscheckCancelled |
VerifaiManualDataCrosscheckError |
The manual data cross check was cancelled | Show an error condition or ask the user to retry |
VerifaiManualSecurityFeatureCheck
Error | Type | Description | Possible solutions |
---|---|---|---|
manualSecurityFeaturesDownloadFailed |
VerifaiManualSecurityFeatureError |
Downloading the document's security features failed | Ensure there's an active internet connection |
noSecurityFeaturesFound |
VerifaiManualSecurityFeatureError |
No security features found for this document | Please contact us and we'll look together at a solution for this |
manualSecurityfeatureCheckCancelled |
VerifaiManualSecurityFeatureError |
The manual security feature check was cancelled | Show an error condition or ask the user to retry |
Theming and colors
Setting custom colors for Verifai components
## NavBarBackgroundColor
UIColor.Verifai.navBarBackgroundColor = UIColor.red
## ScanHighlightTextColor
UIColor.Verifai.scanHighlightTextColor = UIColor.blue
## BottomBoxTitleTextColor
UIColor.Verifai.bottomBoxTitleTextColor = UIColor.green
As described in our theming and styling section Verifai allows you to customize certain colors throughout the framework. All the colors described in the styling and theming section can be found under Verifai's UIColor
extension. On the right there are a few examples of how to change certain colors.
A note on iOS 10
Ensure iOS 11 or later is running before running Verifai
if #available(iOS 11.0, *) {
do {
try Verifai.start(over: self) { result in
switch result {
case .failure(let err):
print("Error or cancellation: \(err)")
case .success(let result):
// Continue with the result
let frontImage = result.frontImage
// etc....
}
}
} catch {
print("π« Unhandled error: \(error)")
}
} else {
print("π« Verifai requires iOS 11 or later")
}
We understand that many developers want to support as many devices as possible to give their customers the best possible user experience. This might mean supporting older iOS versions like iOS 10.
Verifai uses technologies that require iOS 11 or later. We still want you to be able to give the best possible user experience to your users, so starting in Verifai 3.2 we have added to ability to compile on iOS 10. This means you won't be required to update your deployment target to (at least) iOS 11 to compile your app with Verifai.
Sadly the SDK cannot run on iOS 10 and you'll notice this if you still support iOS 10 because the Verifai.start
method will throw an error indicating this. It's up to you to ensure the user is running iOS 11 or later before using Verifai (code example of this on the right). Furthermore this allows you to implement your own screen or flow informing the user that their iOS version is too low to run this feature.
The same is true for other Verifai components:
VerifaiLiveness
VerifaiNFC
VerifaiManualDataCrosscheck
VerifaiManualSecurityFeatureCheck