The Face Match module compares the user's selfie against their ID photo, their NFC chip photo, or both in a 3-way match. It then returns a match decision and confidence score. Matching is performed on the server. The module can also report whether the face already belongs to an existing user.
For an overview of this module and how it works, see Face Match.
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 by ID. See Integration Approaches.
Availability: All variants.
Add Face Match
- Add an ID Capture or QR Scan module, and a Selfie module, before Face Match. Face Match depends on these earlier capture steps so there are two faces to compare.
- Add the module with
addFaceMatch(). Every parameter has a default, so a bare call uses the module defaults.// Default configuration flowConfig.addFaceMatch() // Custom configuration flowConfig.addFaceMatch( matchType: .idSelfie, // .idSelfie (default), .nfcSelfie, .nfc3Way uiFlavor: .full, // .full (default) or .compact idCategory: .primary, // variadic; .primary and/or .secondary showUserExists: nil, // defaults to true showLivenessStatus: nil // defaults to true on v1, false on v2 )
Face Match ships both a v1 (UIKit View) and a v2 (SwiftUI-style) UI.
Example
The example below adds ID Capture and Selfie before Face Match, configures an ID-vs-selfie comparison, starts the flow, and reads the result in onFaceMatchCompleted(_:).
let flow = IncdOnboardingFlowConfiguration()
flow.addIdScan(scanStep: .both)
flow.addSelfieScan()
flow.addFaceMatch(matchType: .idSelfie, idCategory: .primary)
IncdOnboardingManager.shared.startOnboarding(
sessionConfig: IncdOnboardingSessionConfiguration(token: "<SESSION_TOKEN>"),
flowConfig: flow,
delegate: self
)
// In your IncdOnboardingDelegate:
func onFaceMatchCompleted(_ result: FaceMatchResult) {
// Face match completed — inspect result.faceMatched, result.confidence, etc.
}
Configuration Options
Configure the module with addFaceMatch().
| Option | Type | Description |
|---|---|---|
matchType |
FaceMatchType? |
Selects what to compare: .idSelfie (default), .nfcSelfie, or .nfc3Way. The NFC match types require captured NFC chip data. |
uiFlavor |
UIFlavor? |
.full (default) or .compact. .compact is the reduced UI that disables the face-match animation. |
idCategory |
IDCategory... |
Sets one or more IDs to match against: .primary (default), .secondary, or both. |
showUserExists |
Bool? |
Shows or hides the label indicating the user already exists. Default is true. |
showLivenessStatus |
Bool? |
Shows or hides the liveness result label. Default is true on UI v1 and false on UI v2. |
The match type and the thresholds used to decide a pass or fail also depend on your Incode Flow or Workflow configuration, not just these options.
Result
Face Match delivers a FaceMatchResult to the onFaceMatchCompleted(_:) callback on IncdOnboardingDelegate:
func onFaceMatchCompleted(_ result: FaceMatchResult)
FaceMatchResult fields:
faceMatched: Bool?: If the faces matched.confidence: Float?: Recognition confidence between the selfie and the front ID photo.nilwhen no front ID was uploaded.secondIdConfidence: Float?: Recognition confidence against the second ID photo.nfcSelfieConfidence: Float?: Recognition confidence between the selfie and the NFC chip photo.nfcIdConfidence: Float?: Recognition confidence between the front ID photo and the NFC chip photo.nameMatched: Bool?:trueif the existing user's name matches the current user's name (use together withexistingUser); otherwise,false.existingUser: Bool?:trueif the user already exists in the database; otherwise,false.existingInterviewId: String?: The interview ID of the existing user, if one exists; otherwise,nil.idCategories: Set<IDCategory>: The list ofIDCategoryvalues used in the face matching process.error: IncdError?: Set when the module produced an error; otherwise,nil.
Headless
The headless entry point takes the same options as the module. idCategory is variadic; pass zero or more IDCategory values. interviewId is optional; pass a value to target a specific user session, or omit it to use the default.
public func faceMatch(
matchType: FaceMatchType? = nil,
idCategory: IDCategory...,
interviewId: String? = nil,
completion: @escaping (_ result: FaceMatchResult) -> Void
)
// interviewId is optional and omitted here; idCategory is variadic
IncdOnboardingManager.shared.faceMatch(matchType: .idSelfie, idCategory: .primary) { result in
// FaceMatchResult
}
Requires an active session.