DOT iOS Face 9.0.0

This guide describes how to migrate DOT iOS Face version 8.x to version 9.0. Only the most important changes are highlighted in this guide. For more details, see the iOS Samples.

Migration Steps

Compatibility with DIS

When utilizing DIS for server-side evaluation, ensure compatibility between your DIS version and the corresponding SDK version. Refer to the DIS vs SDKs compatibility table for detailed compatibility information.

Deployment

Changed minimal required iOS version to iOS 13.0. Changed minimal required Xcode version to Xcode 16.1.

SDK initialization

The way DOT SDK libraries are configured has changed.

  • Replace DotSdkConfiguration with DotSdk.Configuration class.
  • Update libraries property of DotSdk.Configuration class.
  • Update the modules property of the DotFaceLibraryConfiguration class. Instead of a list of modules, it now accepts DotFaceLibraryConfiguration.Modules, which provides an explicit configuration property for each face module.

Before

Libraries were provided as a list of DotLibrary instances and face modules were provided as list of DotFaceModule.

let dotFaceLibraryConfiguration = DotFaceLibraryConfiguration(            
    modules: [
        DotFaceDetectionFastModule.shared,
        DotFaceExpressionNeutralModule.shared,
        DotFaceEyeGazeLivenessModule.shared,
        DotFacePassiveLivenessModule.shared,
        DotFaceVerificationModule.shared
    ],
    faceDetectionConfidenceThreshold = 0.06
)

let dotSdkConfiguration = DotSdkConfiguration(
    license: Data,
    libraries: [DotFaceLibrary(configuration: dotFaceLibraryConfiguration)]
)

try DotSdk.shared.initialize(configuration: dotSdkConfiguration)

After

Libraries are now configured via a single Libraries object, with explicit configuration for each DOT SDK library. Face modules are configured via DotFaceLibraryConfiguration.Modules, which provides an explicit configuration property for each module instead of a list. Specifying a module configuration activates the module. If a module is not specified or is set to null, it will not be activated.

let dotFaceLibraryConfiguration = DotFaceLibraryConfiguration(
    modules: .init(
        detection: DotFaceDetectionModuleConfiguration.Fast(),
        expressionNeutral: DotFaceExpressionNeutralModuleConfiguration(),
        eyeGazeLiveness: DotFaceEyeGazeLivenessModuleConfiguration(),
        passiveLiveness: DotFacePassiveLivenessModuleConfiguration(),
        verification: DotFaceVerificationModuleConfiguration()
    ),
    faceDetectionConfidenceThreshold = 0.06
)

let dotSdkConfiguration = DotSdk.Configuration(
    licenseBytes: license,
    libraries: .init(
        face: dotFaceLibraryConfiguration
    )
)

try DotSdk.shared.initialize(configuration: dotSdkConfiguration)

UI Face Auto Capture component

The FaceAutoCaptureViewController class’s API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Update configuration.
  • Replace the method stopAsync(...) with the new method stop().
  • Remove the FaceAutoCaptureViewControllerDelegate.faceAutoCaptureViewController(:processed:) callback and implement faceAutoCaptureViewController.uiStateUpdated(:uiState:) instead. UiState is an enum, and its case UiState.Running replaces the data previously delivered via the onProcessed() callback.
  • Replace FaceAutoCaptureViewControllerDelegate.faceAutoCaptureViewController(:captured:) callback with faceAutoCaptureViewController(:finished:) callback.

Before

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    faceQuality: .init(
        imageQuality: .init(//...),
        //...
    )
)

let configuration = try FaceAutoCaptureViewController.Configuration(
    sessionToken: sessionToken,
    qualityAttributeThresholds: FaceAutoCaptureViewController.Configuration.QualityAttributeThresholdPresets.standard.build(),
    minValidFramesInRowToStartCandidateSelection: 2,
    candidateSelectionDurationMillis: 2000,
    query: .init(),
    faceSizeRatioInterval: .init(min: 0.1, max: 0.3),
    captureMode: .autoCapture,
    isPlaceholderVisible: true,
    isDetectionLayerVisible: false,
    isTorchEnabled: false,
    isVideoCaptureEnabled: false,
    cameraFacing: .front,
    cameraPreviewScaleType: .fit,
    isCameraPreviewVisible: true
)

let viewController = FaceAutoCaptureViewController(configuration: configuration)

extension SampleViewController: FaceAutoCaptureViewControllerDelegate {
    func faceAutoCaptureViewController(:processed:) {
        //...
    }

    func faceAutoCaptureViewController(:captured:) {
        //...
    }
}

After

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    quality: .init(//...),
    //...
)

let configuration = try FaceAutoCaptureViewController(
    configuration: .init(
        baseConfiguration: .init(
            common: .init(sessionToken: ""),
            camera: .init(
                facing: .front,
                previewScaleType: .fit,
                isTorchEnabled: false,
                isVideoCaptureEnabled: false,
                isPreviewVisible: true
            ),
            autoCapture: .init(minValidSamplesInRowToStartCandidateSelection: 2, candidateSelectionDurationMillis: 2000),
            faceLibraryComponent: .init(faceSizeRatioInterval: .init(min: 0.1, max: 0.3), query: faceDetectionQuery),
            qualityAttributeThresholds: FaceAutoCaptureQualityAttributeThresholds.Presets.standard.build(),
            captureMode: .autoCapture
        ),
        isDetectionLayerVisible: false,
        placeholder: .Visible()
    )
)


let viewController = FaceAutoCaptureViewController(configuration: configuration)

extension SampleViewController: FaceAutoCaptureViewControllerDelegate {
    func faceAutoCaptureViewController(:uiStateUpdated:) {
        //...
    }

    func faceAutoCaptureViewController(:finished:) {
        //...
    }
}

UI Smile Liveness component

The SmileLivenessViewController class’s API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Update configuration.
  • Replace the method stopAsync(...) with the new method stop().
//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    faceQuality: .init(
        imageQuality: .init(//...),
        //...
    )
)

let configuration = try SmileLivenessViewController.Configuration(
    sessionToken: sessionToken,
    faceSizeRatioInterval: .init(min: 0.1, max: 0.3),
    query: faceDetectionQuery,
    isDetectionLayerVisible: false,
    isTorchEnabled: false,
    isVideoCaptureEnabled: false,
    cameraFacing: .front,
    cameraPreviewScaleType: .fit,
    isCameraPreviewVisible: true
)

let viewController = SmileLivenessViewController(configuration: configuration)

After

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    quality: .init(//...),
    //...
)

let configuration = try SmileLivenessViewController(
    configuration: .init(
        common: .init(sessionToken: ""),
        camera: .init(
            facing: .front,
            previewScaleType: .fit,
            isTorchEnabled: false,
            isVideoCaptureEnabled: false,
            isPreviewVisible: true
        ),
        faceLibraryComponent: .init(faceSizeRatioInterval: .init(min: 0.1, max: 0.3), query: faceDetectionQuery),
        isDetectionLayerVisible: false
    )
)


let viewController = SmileLivenessViewController(configuration: configuration)

UI Multi-Range Liveness component

The MultiRangeLivenessViewController class’s API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Update configuration.
  • Replace the method stopAsync(...) with the new method stop().
//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    faceQuality: .init(
        imageQuality: .init(//...),
        //...
    )
)

let configuration = try MultiRangeLivenessViewController.Configuration(
    sessionToken: sessionToken,
    challengeSequence: [], // obtain challenge from DIS (Digital Identity Service)
    query: faceDetectionQuery,
    isDetectionLayerVisible: false,
    isTorchEnabled: false,
    isVideoCaptureEnabled: false,
    cameraFacing: .front,
    cameraPreviewScaleType: .fit,
    isCameraPreviewVisible: true
)

let viewController = MultiRangeLivenessViewController(configuration: configuration)

After

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    quality: .init(//...),
    //...
)

let configuration = try MultiRangeLivenessViewController(
    configuration: .init(
        baseConfiguration: .init(
            common: .init(sessionToken: ""),
            camera: .init(
                facing: .front,
                previewScaleType: .fit,
                isTorchEnabled: false,
                isVideoCaptureEnabled: false,
                isPreviewVisible: true
            ),
            faceLibraryComponent: .init(faceSizeRatioInterval: .init(min: 0.1, max: 0.4), query: faceDetectionQuery),
        ),
        challengeSequence: [], // obtain challenge from DIS (Digital Identity Service)
        isDetectionLayerVisible: false
    )
)


let viewController = MultiRangeLivenessViewController(configuration: configuration)

UI Eye Gaze Liveness component

WARNING: This component is deprecated in favour of UI Multi-Range Liveness.

The EyeGazeLivenessViewController class’s API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Update configuration.
  • Replace the method stopAsync(...) with the new method stop().
//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    faceQuality: .init(
        imageQuality: .init(//...),
        //...
    )
)

let configuration = try EyeGazeLivenessViewController.Configuration(
    sessionToken: sessionToken,
    faceSizeRatioInterval: .init(min: 0.1, max: 0.3),
    isTorchEnabled: false,
    isVideoCaptureEnabled: false,
    cameraFacing: .front,
    transitionDurationMillis: 800,
    transitionType: .move,
    corners: [//...],
    minValidSamplesCount: 4,
    query: faceDetectionQuery
)

let viewController = EyeGazeLivenessViewController(configuration: configuration)

After

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    quality: .init(//...),
    //...
)

let configuration = try EyeGazeLivenessViewController(
    configuration: .init(
        common: .init(sessionToken: ""),
        camera: .init(
            facing: .front,
            previewScaleType: .fit,
            isTorchEnabled: false,
            isVideoCaptureEnabled: false,
            isPreviewVisible: true
        ),
        faceLibraryComponent: .init(
            faceSizeRatioInterval: .init(min: 0.1, max: 0.3), 
            query: faceDetectionQuery
        ),
        transitionDurationMillis: 800,
        transitionType: .move,
        corners: [//...],
        minValidSamplesCount: 4,
    )
)


let viewController = EyeGazeLivenessViewController(configuration: configuration)

UI MagnifEye Liveness component

WARNING: This component is deprecated in favour of UI Multi-Range Liveness.

The MagnifEyeLivenessViewController class’s API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Update configuration.
  • Replace the method stopAsync(...) with the new method stop().
//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    faceQuality: .init(
        imageQuality: .init(//...),
        //...
    )
)

let configuration = try MagnifEyeLivenessViewController.Configuration(
    sessionToken: sessionToken,
    faceSizeRatioInterval: .init(min: 0.1, max: 0.3),
    query: faceDetectionQuery,
    isDetectionLayerVisible: false,
    isTorchEnabled: false,
    isVideoCaptureEnabled: false,
    cameraFacing: .front,
    cameraPreviewScaleType: .fit,
    isCameraPreviewVisible: true
)

let viewController = MagnifEyeLivenessViewController(configuration: configuration)

After

//...
import DotFaceCore
//...

let faceDetectionQuery = FaceDetectionQuery(
    quality: .init(//...),
    //...
)

let configuration = try MagnifEyeLivenessViewController(
    configuration: .init(
        common: .init(sessionToken: ""),
        camera: .init(
            facing: .front,
            previewScaleType: .fit,
            isTorchEnabled: false,
            isVideoCaptureEnabled: false,
            isPreviewVisible: true
        ),
        faceLibraryComponent: .init(faceSizeRatioInterval: .init(min: 0.1, max: 0.3), query: faceDetectionQuery),
        isDetectionLayerVisible: false
    )
)


let viewController = MagnifEyeLivenessViewController(configuration: configuration)

Image

Several changes were applied to image-related functionality.

  • BgrRawImage has been replaced by the Image class.
  • BgrRawImageFactory has been replaced by ImageFactory.

Before

var image: BgrRawImage = BgrRawImageFactory.create(cgImage:)
var image: BgrRawImage = BgrRawImageFactory.create(ciImage:ciContext:)

After

var image: Image = ImageFactory.createBgrRawImage(cgImage:)
var image: Image = ImageFactory.createBgrRawImage(ciImage:ciContext:)