NAV Navbar
  • Verifai iOS SDK (v 3.3.1)
  • Quick start guide
  • General info
  • Advanced
  • Verifai iOS SDK (v 3.3.1)

    Welcome to the Verifai App implementation documentation. If you have any questions that are unanswered you can always contact our support.

    This documentation wil 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.0.x Documentation
    3.1.x Documentation
    3.2.x Documentation

    Quick start guide

    Modules

    Verifai is modular with the following modules:

    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

    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:

    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 - - -
    NSBluetoothPeripheralUsageDescription - Yes - - -
    1. 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.
    2. [Optional] Set a configuration for the flow of Verifai to lead the user through a more specific flow suitable for your use-case.
    3. Start the desired module.
    4. 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 3.0 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.

    3. Start Verifai

    Starting Verifai

    do {
        try Verifai.start(over: self) { result in
            switch result {
            case .failure(let err): 
                print("Error: \(err)")
            case .success(let result):
                // Continue with the result
                let frontImage = result.frontImage
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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:

    1. 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.
    2. 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:

    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")
            case .success(let nfcResult):
                // Continue with result
                let photo = nfcResult.photo
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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")
            case .success(let livenessResult):
                // Continue with result
                let checksPassed = livenessResult.automaticChecksPassed
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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: \(error)")
                                                }
        }
    } catch {
        print("🚫 Licence 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: \(error)")
            case .success(let checkResult):
                // Continue with result
                let checksPassed = checkResult.passed
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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

    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.

    Example app on Github

    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:

    Plus the shared module VerifaiCommons

    To add the full SDK through Cocoapods add the following lines to your Podfile:
    pod 'Verifai', '~> 3.3'

    Additionally you can add the NFC or Liveness check modules if you so require.

    pod 'VerifaiNFC', '~> 3.3'
    pod 'VerifaiLiveness, '~> 3.3'
    pod 'VerifaiManualDataCrosscheck, '~> 3.3'
    pod 'VerifaiManualSecurityFeatureCheck, '~> 3.3'

    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

    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.

    1. Download the Verifai modules along with the required support frameworks provided by the download from the Verifai Dashboard
    2. 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 on Add
      • Alternatively you can drag the .framework files into the right folder in Xcode
    3. Make sure that the framework folder is included in Project -> Build Settings -> Search Paths -> Framework Search Paths. For example: if the frameworks reside in the Project Root/Frameworks folder, add the entry $(PROJECT_DIR)/Frameworks to the Framework Search Paths.
    4. 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)
    do {
        try Verifai.configure(with: currentConfiguration)
    } 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.

    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.

    More information about configurations for Verifai can be found here: Enabling and disabling features

    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")
            case .success(let nfcResult):
                // Continue with result
                let photo = nfcResult.photo
                // etc....
            }
        }
    } catch {
        print("🚫 Licence error: \(error)")
    }
    

    Starting the NFC module is very similar to starting the other modules by calling VerifaiNFC.start(over:[...]). There are multiple required parameters:

    There are also some additional optional parameters:

    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.

    NFC scanning with an ACS external NFC Bluetooth reader is supported on iOS 11 and above. You'll have to set the useExternalBluetoothReader property to true when calling VerifaiNFC.start.

    VerifaiLiveness

    Starting Verifai Liveness

    do {
        try VerifaiLiveness.start(over: self) { (result) in
            switch result {
            case .failure(_): 
            print("Error")
            case .success(let livenessResult):
                // Continue with result
                let checksPassed = livenessResult.automaticChecksPassed
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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
    

    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:

    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.

    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: \(error)")
                                                }
        }
    } catch {
        print("🚫 Licence 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:

    There are also some additional optional parameters:

    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: \(error)")
            case .success(let checkResult):
                // Continue with result
                let checksPassed = checkResult.passed
                // etc....
            }
        }
    } catch {
        print("🚫 Licence 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:

    There are also some additional optional parameters:

    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
    nfcReaderConnectionFailed VerifaiNFCError The connection to the external bluetooth NFC reader failed Try turning the NFC reader off and on again
    nfcReaderConnectionFailedBluetooth VerifaiNFCError The connection to the external bluetooth NFC reader failed because bluetooth is off or not authorized Ask your user to turn on the device's bluetooth connection
    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

    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 reasses 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 troughout 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: \(err)")
            case .success(let result):
                // Continue with the result
                let frontImage = result.frontImage
                // etc....
            }
        }
        } catch {
            print("🚫 Licence 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: