LogoLogo
Home
  • Youverify API Documentation
  • Getting Started
    • Getting your API Key
    • Getting your Public Merchant Key
    • Environment
    • Response Codes
  • Know Your Customer Services (KYC)
    • ID Document Verification (SDK)
      • Web SDK
      • iOS SDK
        • iOS Liveness SDK
        • iOS (Compat) Liveness SDK
        • iOS Document Capture SDK
      • Android SDK
        • Android Document Capture SDK
        • Android Liveness SDK
      • Document Capture Supported Countries
        • 🌏Asia
        • πŸ‡ͺπŸ‡ΊEurope
        • 🌎Latin America and the Caribbean
        • 🌍Middle East and Africa
        • 🌎North America
        • 🌏Oceania
    • ID Data Matching (eIDV)
      • 🌐Global
        • Supported Countries
      • πŸ‡ΏπŸ‡¦South Africa
        • Verify South African ID Number (SAID)
        • Verify South African Phone Number
        • Bank Account Verification
        • Proof of Address Verification
      • πŸ‡°πŸ‡ͺKenya
        • Verify International Passport
        • Verify Alien ID
        • Verify Drivers License
        • Verify Plate Number
        • Verify Collateral ID
        • Kenyan Bank Account Verification
          • Bank List
        • Credit History
        • Employment History
        • Verify Address Information
        • Verify Phone Number
        • Verify Identity Number
        • Verify Tax PIN
      • πŸ‡¬πŸ‡­Ghana
        • Verify International Passport
        • Verify Social Security and National Insurance Trust (SSNIT)
        • Verify Ghana Voters Card (GVC)
      • πŸ‡³πŸ‡¬Nigeria
        • Verify Bank Verification Number (BVN)
        • Verify Bank Verification Number (BVN Premium)
        • Verify Virtual National Identification Number (vNIN)
        • Verify National Identification Number (NIN)
        • Verify Nigerian Driver's License (Driver's License)
        • Advanced Phone Search
        • Verify Nigerian International Passport (Passport)
        • Verify Nigerian Permanent Voters Card (PVC)
        • Verify Phone Number
        • Individual Credit Report
        • Bank Account Verification
          • Basic Bank Account Verification
          • Bank List
            • Getting the list of Banks for Basic Bank Account
    • Facial Comparison
    • Retrieve an Identity
    • Identity History
  • Know Your Business Services (KYB)
    • 🌍Business Verification
    • 🌍Search for Businesses
    • Get Supported Countries and Regions
    • Retrieve Business details
    • Country-Specific KYB Services
      • πŸ‡³πŸ‡¬Nigeria
        • Tax Identification Number (TIN) Verification
      • πŸ‡ΏπŸ‡¦South Africa
        • Business Account Verification
        • Business Address Verification
  • Know Your Transaction Service (KYT)
    • Customer Management
      • Create an Individual Client
      • Create a Business Client
      • Initiate an Individual Client Assessment
      • Initiate an Business Client Assessment
      • Update a Client
      • Retrieve all Clients
      • Retrieve a Client
      • Delete a Client
    • Transaction Management
      • Create a Transaction
      • Retrieve an Evaluation
  • Risk Intelligence
    • Risk Intelligence: Initialise Risk Check
    • Retrieve Risk Intelligence Profile
    • Retrieve Risk Intelligence History
  • AML Services (Anti-Money Laundering)
    • PEP and Sanction Screening
      • Search using Name
        • Advanced Filters
      • Search using Identity
        • Advanced Filters
      • Search using Crypto
        • Advanced Filters
      • Retrieve a PEP and Sanction Screening Search
      • Screening Data Sources
      • Domestic PEP Search
    • Adverse Media Intelligence
    • Custom AML Watchlist
      • AML Watchlist (Sample list)
      • AML Watchlist Upload (Bulk Upload)
      • AML Watchlist Upload
      • Retrieve AML Watchlist
      • AML Watchlist Entity Update
      • AML Watchlist Entity Removal
  • Custom Workflow Builder (CWB)
    • CWB Webhook
    • CWB External API
      • Retrieve CWB History
      • Retrieve CWB Responses
      • Retrieve CWB Report
  • Youverify OS Error Codes
  • Webhooks
    • Know Your Customer Webhooks
      • Identity Verification
      • Address Verification
    • Know Your Transaction Webhooks
      • Customer Management Webhooks
        • Client Created
        • Client Updated
      • Alert Service Webhooks
        • Alert Created
        • Alert Triage Created
        • Alert Updated
      • Evaluation Webhooks
        • Evaluation Completed
        • Evaluation Started
        • Transaction Updated
  • Test Data
  • Our Legacy API and SDK
Powered by GitBook
On this page
  • Features
  • Installation
  • Usage
  • Configuration Options
  • Available Tasks
  • Liveness Data
  • Full Example
  • Credits

Was this helpful?

  1. Know Your Customer Services (KYC)
  2. ID Document Verification (SDK)
  3. iOS SDK

iOS (Compat) Liveness SDK

Our iOS SDK enables seamless integration of real-time liveness detection into your mobile applications. To get started with our SDK, follow the guide below:

PreviousiOS Liveness SDKNextiOS Document Capture SDK

Last updated 1 month ago

Was this helpful?

Youverify Liveness SDK Compat is the compatibility version of the iOS SDK, designed for integrating active liveness detection into UIKit-based applications. This SDK is tailored for apps that need to support iOS 12 and later, providing a reliable solution for older iOS versions.

Features

  • Active Liveness Detection: Requires users to perform specific actions (e.g., head movements, answering questions) to confirm liveness. Available on iOS 12+.

  • Built with UIKit, ensuring compatibility with legacy iOS applications.

Note: Passive liveness detection is not supported in this version.

Installation

Step 1: Add to Podfile

Add the following to your Podfile:

pod 'YouverifyLivenessSDKCompat'
pod 'MediaPipeTaskVision'

Step 2: Install Dependencies

Run this command in your terminal:

pod install

Step 3: Open Workspace

Open the generated .xcworkspace file in Xcode.

Project Configuration

To prevent linker errors, add the following post-install script to your application's Podfile, making sure to replace "YourAppTarget" with the correct target name for your app.

post_install do |installer| target_name = "YourAppTarget"

# Get the paths to the xcconfig files
debug_xcconfig_path = "#{installer.pods_project.project_dir}/Target Support Files/Pods-#{target_name}/Pods-#{target_name}.debug.xcconfig"
release_xcconfig_path = "#{installer.pods_project.project_dir}/Target Support Files/Pods-#{target_name}/Pods-#{target_name}.release.xcconfig"

# Modify the debug .xcconfig file if it exists
if File.exist?(debug_xcconfig_path)
  puts "Modifying debug .xcconfig file: #{debug_xcconfig_path}"

  # Read the debug .xcconfig file
  debug_xcconfig = File.read(debug_xcconfig_path)

  # Remove framework flags from OTHER_LDFLAGS
  debug_xcconfig.gsub!(/-framework\s+"MediaPipeTasksCommon"/, '')
  debug_xcconfig.gsub!(/-framework\s+"MediaPipeTasksVision"/, '')

  # Remove -force_load from OTHER_LDFLAGS for iphoneos and iphonesimulator
  debug_xcconfig.gsub!(/-force_load\s+"?[^"]*libMediaPipeTasksCommon.*\.a"?/, '')

  # Write the modified debug .xcconfig file
  File.write(debug_xcconfig_path, debug_xcconfig)
  puts "Modified debug .xcconfig file."
else
  puts "Debug .xcconfig file not found at #{debug_xcconfig_path}"
end

# Modify the release .xcconfig file if it exists
if File.exist?(release_xcconfig_path)
  puts "Modifying release .xcconfig file: #{release_xcconfig_path}"

  # Read the release .xcconfig file
  release_xcconfig = File.read(release_xcconfig_path)

  # Remove framework flags from OTHER_LDFLAGS
  release_xcconfig.gsub!(/-framework\s+"MediaPipeTasksCommon"/, '')
  release_xcconfig.gsub!(/-framework\s+"MediaPipeTasksVision"/, '')

  # Remove -force_load from OTHER_LDFLAGS for iphoneos and iphonesimulator
  release_xcconfig.gsub!(/-force_load\s+"?[^"]*libMediaPipeTasksCommon.*\.a"?/, '')

  # Write the modified release .xcconfig file
  File.write(release_xcconfig_path, release_xcconfig)
  puts "Modified release .xcconfig file."
else
  puts "Release .xcconfig file not found at #{release_xcconfig_path}"
end

end


Usage

1. Import the SDK

In your Swift file:

import YouverifyLivenessSDK

2. Initialize the SDK

Create an instance of YVLiveness with your configuration:

private var yvLiveness = YVLiveness(
    publicKey: Environment.shared.value(forKey: "API_KEY") ?? "",
    user: YVLivenessUser(firstName: "Ugochukwu"),
    onSuccess: { data in
        print("The success data is \(data)")
    },
    onFailure: { errorData in
        print("The error data is \(errorData)")
    },
    sandboxEnvironment: false
)
  • The publicKey is dynamically retrieved from an environment variable (Environment.shared.value(forKey: "API_KEY") ?? "") in the working code. Replace this with your actual API key or retrieval logic.

  • The user parameter requires a firstName, while optional fields like lastName and email can be added if needed (see Configuration Options).

3. Start Liveness Detection

Launch the SDK with a list of tasks:

yvLiveness.startSDK(tasks: tasks)
DispatchQueue.main.async {
    self.addLivenessViewController()
}

4. Manage the Liveness View Controller

Add these methods to handle the liveness UI:

private var livenessViewController: YVLivenessViewController?

private func addLivenessViewController() {
    guard livenessViewController == nil else { return }
    let vc = YVLivenessViewController(sdk: yvLiveness)
    vc.delegate = self
    addChild(vc)
    view.addSubview(vc.view)
    vc.didMove(toParent: self)
    livenessViewController = vc
}

private func removeLivenessViewController() {
    guard let vc = livenessViewController else { return }
    vc.willMove(toParent: nil)
    vc.view.removeFromSuperview()
    vc.removeFromParent()
    livenessViewController = nil
}
  • The guard statement in addLivenessViewController() prevents duplicate additions of the view controller.

5. Handle Modal Closing

Implement the delegate to close the liveness UI:

extension MainViewController: YVLivenessViewDelegate {
    func closeModal() {
        DispatchQueue.main.async {
            self.removeLivenessViewController()
        }
    }
}

Configuration Options

Option
Type
Required
Description
Default
Possible Values

publicKey

String

Yes

Your API key for authentication

-

Any string

user

Class

Yes

User details (requires firstName)

-

See below

user.firstName

String

Yes

User’s first name

-

Any string

user.lastName

String

No

User’s last name

nil

Any string

user.email

String

No

User’s email

nil

Any string

onSuccess

Function

No

Callback on success with liveness data

nil

Any function

onFailure

Function

No

Callback on failure with error data

nil

Any function

sandboxEnvironment

Bool

No

Toggle sandbox mode for testing

true

true, false


Available Tasks

Tasks verify liveness through user interactions. Below are the supported options:

Complete The Circle

Users trace a circle with head movements.

Option
Type
Required
Description
Default
Values

difficulty

TaskDifficulty

No

Task difficulty

.medium

.easy, .medium, .hard

timeout

Number

No

Time (ms) before task fails

nil

Any milliseconds

Example:

TaskProperties(task: .completeTheCircle(CompleteTheCircleTask(difficulty: .medium)))

Yes or No

Users answer questions by tilting their head (right = yes, left = no).

Option
Type
Required
Description
Default
Values

difficulty

TaskDifficulty

No

Task difficulty

.medium

.easy, .medium, .hard

timeout

Number

No

Time (ms) before task fails

nil

Any milliseconds

questions

Array

Yes

List of yes/no questions

-

See below

questions.question

String

Yes

Yes/no question

-

Any string

questions.answer

Bool

Yes

Correct answer

-

true, false

questions.errorMessage

String

No

Message on wrong answer

nil

Any string

Example:

TaskProperties(task: .yesOrNo(YesOrNoTask(questions: [YesOrNoQuestion(question: "Is 2 + 2 = 7?", answer: false)])))

Motions

Users perform nods, blinks, or mouth movements.

Option
Type
Required
Description
Default
Values

difficulty

TaskDifficulty

No

Task difficulty

.medium

.easy, .medium, .hard

timeout

Number

No

Time (ms) before task fails

nil

Any milliseconds

maxNods

Int

No

Max nods to perform

5

Any number

maxBlinks

Int

No

Max blinks to perform

5

Any number

Example:

TaskProperties(task: .motions(MotionsTaskClass(difficulty: .medium)))

Liveness Data

The onSuccess callback returns:

Field
Type
Description

faceImage

String

User’s face image

livenessClip

String

Video of liveness check

passed

Bool

True if passed, false if failed

metadata

Any

Metadata from initialization

The onFailure callback returns error details as a string or object, depending on the issue.


Full Example

Here’s the complete implementation from the working code:

import UIKit
import YouverifyLivenessSDK

class MainViewController: UIViewController {
    private var yvLiveness = YVLiveness(
        publicKey: Environment.shared.value(forKey: "API_KEY") ?? "",
        user: YVLivenessUser(firstName: "Ugochukwu"),
        onSuccess: { data in
            print("The success data is \(data)")
        },
        onFailure: { errorData in
            print("The error data is \(errorData)")
        },
        sandboxEnvironment: false
    )
    
    private var livenessViewController: YVLivenessViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create a vertical stack view
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 10
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        // Create buttons
        let completeCircleButton = createButton(title: "Complete the Circle", action: #selector(completeTheCircleTapped))
        let yesOrNoButton = createButton(title: "Yes or No", action: #selector(yesOrNoTapped))
        let motionsButton = createButton(title: "Motions", action: #selector(motionsTapped))
        let passiveLivenessButton = createButton(title: "Passive Liveness", action: #selector(passiveLivenessTapped))
        
        // Add buttons to stack view
        stackView.addArrangedSubview(completeCircleButton)
        stackView.addArrangedSubview(yesOrNoButton)
        stackView.addArrangedSubview(motionsButton)
        stackView.addArrangedSubview(passiveLivenessButton)
        
        // Add stack view to the main view
        view.addSubview(stackView)
        
        // Set Auto Layout constraints
        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)
        ])
    }
    
    private func addLivenessViewController() {
        guard livenessViewController == nil else { return } // Prevent duplicate adds
        let vc = YVLivenessViewController(sdk: yvLiveness)
        vc.delegate = self
        
        addChild(vc)
        
        view.addSubview(vc.view)
        vc.didMove(toParent: self)
        livenessViewController = vc
    }

    private func removeLivenessViewController() {
        guard let vc = livenessViewController else { return }
        vc.willMove(toParent: nil)
        vc.view.removeFromSuperview()
        vc.removeFromParent()
        livenessViewController = nil
    }
    
    // Helper function to create buttons with actions
    private func createButton(title: String, action: Selector) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.addTarget(self, action: action, for: .touchUpInside)
        return button
    }
    
    // MARK: - Button Actions
    
    private func startLiveness(with tasks: [TaskProperties]) {
        yvLiveness.startSDK(tasks: tasks)
        DispatchQueue.main.async {
            self.addLivenessViewController()
        }
    }
    
    @objc private func completeTheCircleTapped() {
        startLiveness(with: [
            TaskProperties(task: .completeTheCircle(CompleteTheCircleTask(difficulty: .medium)))
        ])
    }
    
    @objc private func yesOrNoTapped() {
        startLiveness(with: [TaskProperties(
            task: .yesOrNo(YesOrNoTask(questions: [YesOrNoQuestion(question: "Is 2 + 2 = 7?", answer: false)]))
        )])
    }
    
    @objc private func motionsTapped() {
        startLiveness(with: [TaskProperties(
            task: .motions(MotionsTaskClass(difficulty: .medium))
        )])
    }
    
}

extension MainViewController: YVLivenessViewDelegate {
    func closeModal() {
        DispatchQueue.main.async {
            self.removeLivenessViewController()
        }
    }
}

Credits

This SDK is developed and maintained solely by

Get your Public Merchant Key
Youverify