iOS 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:

Get your Public Merchant Key

Youverify Liveness SDK is the recommended iOS SDK for integrating real-time liveness detection into your SwiftUI-based applications. It supports both passive and active liveness detection, offering a modern and secure way to verify user presence. This SDK is ideal for developers targeting iOS 13 and later, with additional features available on iOS 15 and above.

Features

  • Passive Liveness Detection: Analyzes facial features (e.g., blinking, skin texture) to confirm liveness without user interaction. Available on iOS 15+.

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

  • Built with SwiftUI, aligning with modern iOS development practices.

Installation

Get started with the SDK in just a few steps:

  1. Add to Your Podfile Open your projectโ€™s Podfile and include:

    pod 'YouverifyLivenessSDK'
    pod 'MediaPipeTaskVision'
  2. Install Dependencies Run this command in your terminal:

    pod install
  3. Open Your Project Launch 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 Package

To use the SDK in your SwiftUI view, import it at the top of your file:

import YVLivenessSDK

2. Initialize an Instance

Create an instance of the SDK as a private variable within your SwiftUI view. Pass in the necessary configuration options during initialization:

private var yvSDK = YVLiveness(
    publicKey: "YOUR_PUBLIC_KEY",
    user: SDKUser(firstName: "Ugochukwu"),
    onSuccess: { data in print("The data returned is \(data.faceImage)") },
    branding: Branding(color: "#4287f5")
)
  • The publicKey can be retrieved dynamically (e.g., from an environment variable), as shown in the working code with Environment.shared.value(forKey: "API_KEY") ?? "".

  • Optional parameters like onFailure, lastName, and email can be included if needed (see Configuration Options).

3. Start the Liveness Process

Trigger the liveness detection process by calling startSDK() on your SDK instance. Pass an array of tasks to specify the liveness checks to perform:

Complete the Circle

yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.completeTheCircle(CompleteTheCircleTask(difficulty: .medium)))])

Yes or No

yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.yesOrNo(YesOrNoTask(questions: [
    YesOrNoQuestion(question: "Is Nigeria a country?", answer: true, errorMessage: "That's the wrong answer")
])))])

Motions

yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.motions(MotionsTaskClass(maxNods: 5, maxBlinks: 5)))])

Passive Liveness

yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.passive)])

See the Tasks section for detailed task options.

4. Add the SDK View

Include the SDKโ€™s view in your SwiftUI view hierarchy to display the liveness detection interface:

YVLivenessView(sdk: yvSDK)

Unlike the previous version, this view should always be present in the view hierarchy (not conditionally rendered). The SDK internally manages when to show the liveness interface based on startSDK() calls.

Configuration Options

The following options can be passed during initialization of YVLiveness:

Option

Type

Required

Description

Default Value

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

Boolean

No

Toggle sandbox mode for testing

true

true, false

tasks

Array

No

Define liveness tasks for initialization

nil

See Tasks

branding

Class

No

Customize SDK appearance (e.g., color)

nil

color

Tasks

Tasks are interactive challenges or passive checks to confirm liveness. Specify them when calling startSDK(). Below are the available tasks:

Complete The Circle

Users trace a circle with head movements.

Option

Type

Required

Description

Default

Possible Values

difficulty

TaskDifficulty

No

Task difficulty

.medium

.easy, .medium, .hard

timeout

Number

No

Time (ms) before task fails

nil

Any milliseconds

Example:

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

Yes or No

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

Option

Type

Required

Description

Default

Possible 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: YVTask.yesOrNo(YesOrNoTask(questions: [
    YesOrNoQuestion(question: "Is Nigeria a country?", answer: true, errorMessage: "That's the wrong answer")
])))

Motions

Users perform nods, blinks, or mouth movements.

Option

Type

Required

Description

Default

Possible 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: YVTask.motions(MotionsTaskClass(maxNods: 5, maxBlinks: 5)))

Passive Liveness

Analyzes facial features without user interaction (no additional parameters required).

Example:

TaskProperties(task: YVTask.passive)

Liveness Data

The onSuccess callback returns the following data:

Field

Type

Description

faceImage

String

Userโ€™s face image

livenessClip

String

Video of liveness check (if applicable)

passed

Bool

True if passed, false if failed

metadata

Any

Metadata from initialization

The onFailure callback (if provided) returns error details as a string or object.

Full Example

Hereโ€™s the complete SwiftUI view from the working code, demonstrating the SDK integration:

import SwiftUI
import YVLivenessSDK

struct ContentView: View {
    private var yvSDK = YVLiveness(
        publicKey: Environment.shared.value(forKey: "API_KEY") ?? "",
        user: SDKUser(firstName: "Ugochukwu"),
        onSuccess: { data in
            print("The data returned is \(data.faceImage)")
        },
        branding: Branding(color: "#4287f5")
    )
    let TIMEOUT = 20.0
    
    var body: some View {
        ZStack {
            VStack(spacing: 10) {
                Button(action: {
                    yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.completeTheCircle(CompleteTheCircleTask(difficulty: .medium)))])
                }, label: {
                    Text("Complete the Circle")
                })
                
                Button(action: {
                    yvSDK.startSDK(tasks: [TaskProperties(task:
                        YVTask.yesOrNo(YesOrNoTask(questions: [
                            YesOrNoQuestion(question: "Is Nigeria a country?", answer: true, errorMessage: "That's the wrong answer")
                        ])))
                    ])
                }, label: {
                    Text("Yes or No")
                })
                
                Button(action: {
                    yvSDK.startSDK(tasks: [TaskProperties(task:
                        YVTask.motions(MotionsTaskClass(maxNods: 5, maxBlinks: 5)))
                    ])
                }, label: {
                    Text("Motions")
                })
                
                Button(action: {
                    yvSDK.startSDK(tasks: [TaskProperties(task: YVTask.passive)])
                }, label: {
                    Text("Passive Liveness")
                })
            }
            .padding()
            
            YVLivenessView(
                sdk: yvSDK
            )
        }
    }
}

Credits

This SDK is developed and maintained solely by Youverify

Last updated

Was this helpful?