SDK reference, iOS SDK / iOS Individual Modules

Face Authentication

The Face Authentication module captures a returning user's face with the device camera and matches it against the face already enrolled for that user. It then returns a pass or fail result. iOS exposes two entry points: an in-flow Face Authentication step and a standalone Face Login API.

For an overview of this module and how it works, see Face Authentication.

How you use this module depends on your integration pattern. When the app defines the steps in code, you add the module to an IncdOnboardingFlowConfiguration as shown below; when the flow is defined in Dashboard, you reference it and let the back end drive the steps. See Integration Approaches.

Availability: The -l build variant.

Add Face Authentication

Add the module with addFaceAuthentication(configuration:) on IncdOnboardingFlowConfiguration. Face Authentication runs against an existing enrolled user, so your session must identify that user. Every setting on FaceAuthenticationConfiguration has a default, so pass a default-initialized configuration for the standard behavior, or build a custom one.

// Default configuration
flowConfig.addFaceAuthentication(configuration: FaceAuthenticationConfiguration())

// Custom configuration
flowConfig.addFaceAuthentication(configuration: faceAuthConfig)

Face Authentication ships both a v1 (legacy) and a v2 capture UI; the active one is selected by the SDK based on your Incode configuration.

Example

The example below builds a FaceAuthenticationConfiguration with tutorials and occlusion checks, adds it to the flow, and listens for the result through the IncdOnboardingDelegate.

let faceAuthConfig = FaceAuthenticationConfiguration(
    showTutorials: true,
    lensesCheck: true,
    faceMaskCheck: true
)

let flowConfig = IncdOnboardingFlowConfiguration()
flowConfig.addFaceAuthentication(configuration: faceAuthConfig)

IncdOnboardingManager.shared.startOnboarding(
    sessionConfig: IncdOnboardingSessionConfiguration(token: "<SESSION_TOKEN>"),
    flowConfig: flowConfig,
    delegate: self
)
// IncdOnboardingDelegate
func onFaceAuthenticationCompleted(_ result: FaceAuthenticationResult) {
    // Face authentication completed
}

func onError(_ error: IncdFlowError) {
    // Onboarding flow was aborted due to an error
}

Configuration Options

Configure the module by passing named parameters to the FaceAuthenticationConfiguration initializer. These are write-only: set at initialization, but not readable back from an existing instance. The table below lists the most commonly used ones. Any Bool? check left nil falls back to the corresponding manager-level faceAuth* default.

Option Type Description
deepsight DeepsightConfiguration Enables liveness/Deepsight configuration. Defaults to .default. The effective behavior can be governed by your back-end Flow or Workflow configuration.
showTutorials Bool? Shows a tutorial before the scan. When nil, uses the manager's faceAuthShowTutorials.
autoCaptureTimeout Double? Sets the auto-capture timeout, in seconds.
captureAttempts Int? Sets the number of capture attempts. When nil, uses the manager's faceAuthMaxRetries.
lensesCheck Bool? Enables eyeglass detection during capture. When nil, uses the manager's faceAuthLensesCheck.
faceMaskCheck Bool? Enables face-mask detection during capture. When nil, uses the manager's faceAuthFaceMaskCheck.
closedEyesCheck Bool? Enables closed-eyes detection during capture. When nil, uses the manager's faceAuthClosedEyesCheck.
headCoverCheck Bool? Enables head-covering detection during capture. When nil, uses the manager's faceAuthHeadCoverCheck.
imageQualitySeverity ImageQualitySeverity Sets how strict the image-quality check is during capture. Defaults to .defaultValue.
occlusionCheck OcclusionCheck Enables a face occlusion check. Defaults to .disabled.

Result

Face Authentication delivers a FaceAuthenticationResult to the onFaceAuthenticationCompleted(_:) callback on IncdOnboardingDelegate.

func onFaceAuthenticationCompleted(_ result: FaceAuthenticationResult)

FaceAuthenticationResult fields:

  • success: Bool?: true if face authentication succeeded; otherwise, false.
  • customerUUID: String?: The customer UUID associated with the authenticated face; nil when unavailable.
  • image: UIImage?: The captured selfie image; nil when unavailable.
  • selfieBase64: String?: The Base64-encoded selfie image; nil when unavailable.
  • selfieEncryptedBase64: String?: The Base64-encoded encrypted selfie image; nil when unavailable.
  • error: FaceAuthenticationError?: The module-specific error when authentication did not complete successfully; otherwise, nil.
  • videoRecordingError: FaceAuthenticationError?: Set when video recording failed during capture, independent of the authentication outcome; nil when unavailable. Distinct from error; carries insufficientStorageForVideoRecording or videoRecordingFailed.

Errors

Module errors surface through result.error as a FaceAuthenticationError. Pattern-match it to react to a specific case:

if case .spoofAttemptDetected = result.error {
    // A spoof attempt was detected
}

FaceAuthenticationError cases:

  • error
  • inactiveSession
  • nonexistentCustomer
  • lensesDetected
  • faceMaskDetected
  • headCoverDetected
  • closedEyesDetected
  • faceTooDark
  • spoofAttemptDetected
  • userIsNotRecognized
  • selfieImageLowQuality
  • hintNotProvided
  • faceNotFound
  • faceCroppingFailed
  • faceTooSmall
  • faceTooBlurry
  • badPhotoQuality
  • processingError
  • badRequest
  • deniedCameraPermissions
  • userCancelled
  • selfieFaceOccluded
  • insufficientStorageForVideoRecording
  • videoRecordingFailed
  • unknown

Flow-level failures also arrive through the delegate's onError(_:).

Standalone: Face Login (-l variant)

Basic Usage

Use startFaceLogin to authenticate a returning user outside a flow. Before you call it, set IncdOnboardingManager.shared.presentingViewController to the view controller that presents the capture UI.

For 1:1 verification, pass the user's customerUUID. For 1:N identification, pass nil for customerUUID.

Use faceAuthMode to select where matching happens:

  • .server for server-side matching.
  • .local for on-device matching. .local requires the -l variant.

Only one Face Login can run at a time. If you call startFaceLogin while another Face Login is in progress, the SDK ignores the new call and never calls its completion handler.

IncdOnboardingManager.shared.startFaceLogin(
    customerUUID: nil,          // nil → 1:N; set → 1:1
    faceAuthMode: .server,      // .server or .local (.local needs -l)
    faceAuthModeFallback: true,
    lensesCheck: true,
    faceMaskCheck: true
) { result in
    // SelfieScanResult (see the Selfie module)
}

Full Signature

The call above uses the most common parameters; every parameter has a default, so pass only the ones you need. The complete signature is:

func startFaceLogin(
    showTutorials: Bool? = nil,
    customerUUID: String? = nil,
    faceAuthMode: FaceAuthMode? = nil,
    faceAuthModeFallback: Bool? = nil,
    lensesCheck: Bool? = nil,
    faceMaskCheck: Bool? = nil,
    localLivenessCheck: Bool? = nil,
    localAgeEstimation: Bool? = nil,
    forceThemeBackground: Bool = false,
    logAuthenticationEnabled: Bool? = nil,
    customLogo: UIImage? = nil,
    uxMode: FaceLoginUXMode? = nil,
    streamFramesToken: String? = nil,
    completion: @escaping (_ result: SelfieScanResult) -> Void
)
Parameter Default Description
localLivenessCheck true Set to false to skip the on-device liveness check in .local logins. .server logins always check liveness on the server.
localAgeEstimation false Set to true to estimate the user's age on device and return it in FaceLoginResult.estimatedAge. Requires the -l variant.
uxMode .standard Sets the capture experience. See FaceLoginUXMode in Supporting Types.

Additional optional parameters include:

  • showTutorials, which shows a tutorial before the scan
  • forceThemeBackground
  • logAuthenticationEnabled
  • customLogo
  • streamFramesToken

Face Login Result

The completion closure receives a SelfieScanResult. For Face Login, read the outcome from its faceLoginResult property. Use spoofAttempt and error to tell a failed match apart from a liveness failure or an error.

IncdOnboardingManager.shared.startFaceLogin { result in
    guard let loginResult = result.faceLoginResult else {
        // An error occurred; inspect result.error
        return
    }

    if loginResult.success == true {
        let customerUUID = loginResult.customerUUID
        let token = loginResult.token
        let interviewId = loginResult.interviewId
    } else if result.spoofAttempt == true {
        // Liveness check failed
    } else {
        // The user's face was not recognized
    }
}
FaceLoginResult Property Type Description
success Bool? true if Face Login succeeded, false if it failed, or nil if an error occurred.
customerUUID String? The matched user's customer UUID, or nil if no user was matched.
token String? The matched user's customer token.
interviewId String? The ID of the onboarding session interview in which the user was approved.
interviewToken String? The token of the onboarding session interview in which the user was approved.
transactionId String? The transaction ID of the Face Login attempt.
estimatedAge Float? The user's estimated age. Returned only when localAgeEstimation is true and the login completes.

On the enclosing SelfieScanResult, spoofAttempt is true when the attempt was detected as a spoof, and error carries a SelfieScanError when Face Login did not complete.

Manage the Local Face Database

When matching on device, manage the local face database directly.

IncdOnboardingManager.shared.addFace(FaceInfo(faceTemplate: "…", customerUUID: "…", templateId: "…"))
IncdOnboardingManager.shared.removeFace(customerUUID: "…")
IncdOnboardingManager.shared.setFaces([FaceInfo(faceTemplate: "…", customerUUID: "…", templateId: "…")])
let faces = IncdOnboardingManager.shared.getFaces()
IncdOnboardingManager.shared.syncFaceLoginAttempts(delegate: nil) { ok, error in /* ok: Bool?, error: IncdLoginError? */ }

Supporting Types

  • The cases of FaceAuthMode are:
    • .server: Checks liveness and matches the face on the server.
    • .local: Checks liveness and matches the face on device. Requires the -l variant.
  • The properties of FaceInfo are faceTemplate, customerUUID, and templateId.
  • The cases of FaceLoginUXMode are:
    • .standard: The default capture experience.
    • .fast: Shows the camera immediately, skips the "Get ready" step, and accepts a face that is farther away, off-center, or at a greater angle than .standard allows.
    • .ultraFast: Shows no capture screen or tutorial, only a small progress indicator at the top of your app's UI. Captures the same way as .fast. It requires camera permission to already be granted. Otherwise, it behaves like .fast. If no face is captured within a few seconds, the login ends with SelfieScanError.userNotFound.

Was this page helpful?