DOT iOS Face 8.0.0

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

Migration Steps

Deployment

  • Changed minimal required iOS version to iOS 12.0.
  • Changed minimal required Xcode version to Xcode 15.1.

Face Detector component (FaceDetector)

  • FaceDetector.detect() method now returns [FaceDetector.Face] instead of [DetectedFace].
  • Use query: FaceDetectionQuery argument of the FaceDetector.detect() method in order to specify desired detection data.

Before

let faceDetector = FaceDetector()
let faceImage = try FaceImageFactory.create(image: bgrRawImage, minFaceSizeRatio: minFaceSizeRatio, maxFaceSizeRatio: maxFaceSizeRatio)
let detectedFaces = try faceDetector.detect(faceImage: faceImage, maximumFaces: 1)
let detectedFace = detectedFaces.first!
let confidence = detectedFace.confidence
let template = try detectedFace.createTemplate()
let fullFrontalImage = try detectedFace.createFullFrontalImage()
let faceQualityQuery = FaceQualityQuery(imageQuality: FaceImageQualityQuery(sharpness: true))
let faceQuality = try detectedFace.evaluateFaceQuality(faceQualityQuery: faceQualityQuery)
let passiveLiveness = try detectedFace.evaluatePassiveLiveness()

After

let faceDetector = FaceDetector()
let faceImage = try FaceImage(bgrRawImage: bgrRawImage, faceSizeRatioInterval: faceSizeRatioInterval)
let faces = try faceDetector.detect(
    faceImage: faceImage,
    query: FaceDetectionQuery(
        faceQuality: FaceQualityQuery(imageQuality: FaceImageQualityQuery(evaluateSharpness: true)),
        evaluatePassiveLiveness: true,
        createFullFrontalImage: true,
        createTemplate: true
    ),
    limit: 1
)
let face = faces.first!
let confidence = face.confidence
let faceAspects = face.faceAspects
let faceQuality = face.faceQuality
let passiveLivenessFaceAttribute = face.passiveLivenessFaceAttribute
let fullFrontalBgrRawImage = face.fullFrontalBgrRawImage
let template = face.template

All UI components use a query in their configurations

  • Use query: FaceDetectionQuery argument of the *ViewController.Configuration class in order to specify desired detection data of the result.

Before

// Example implementation of the FaceAutoCaptureViewController and FaceAutoCaptureViewControllerDelegate
let faceAutoCaptureViewController = FaceAutoCaptureViewController.create()

func faceAutoCaptureViewController(_ viewController: FaceAutoCaptureViewController, captured result: FaceAutoCaptureResult) {
    do {
        let detectedFace = result.detectedFace!
        let confidence = detectedFace.confidence
        let template = try detectedFace.createTemplate()
        let fullFrontalImage = try detectedFace.createFullFrontalImage()
        let faceQualityQuery = FaceQualityQuery(imageQuality: FaceImageQualityQuery(sharpness: true))
        let faceQuality = try detectedFace.evaluateFaceQuality(faceQualityQuery: faceQualityQuery)
        let passiveLiveness = try detectedFace.evaluatePassiveLiveness()
    } catch {
        print(error.localizedDescription)
    }
}

After

// Example implementation of the FaceAutoCaptureViewController and FaceAutoCaptureViewControllerDelegate
let configuration = FaceAutoCaptureViewController.Configuration(
    query: FaceDetectionQuery(
        faceQuality: FaceQualityQuery(imageQuality: FaceImageQualityQuery(evaluateSharpness: true)),
        evaluatePassiveLiveness: true,
        createFullFrontalImage: true,
        createTemplate: true
    )
)
let faceAutoCaptureViewController = FaceAutoCaptureViewController(configuration: configuration)

func faceAutoCaptureViewController(_ viewController: FaceAutoCaptureViewController, captured result: FaceAutoCaptureResult) {
    let face = result.face!
    let confidence = face.confidence
    let faceAspects = face.faceAspects
    let faceQuality = face.faceQuality
    let passiveLivenessFaceAttribute = face.passiveLivenessFaceAttribute
    let fullFrontalBgrRawImage = face.fullFrontalBgrRawImage
    let template = face.template
}

Eye Gaze Liveness UI component (EyeGazeLivenessViewController)

  • Replace usage of EyeGazeLivenessViewController. More details are in the integration manual and the API reference. The following points are the minimum changes required in order to migrate to version 8.0.0.
  • Add callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewController(_:processed:).
  • Add callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerCriticalFacePresenceLost(_:). Before the component started again after the face presence was lost. Since version 8.0.0 there is an option to handle this kind of event via this callback. E.g. you can start over (as prior to version 8.0.0) by calling eyeGazeLivenessViewController.start() method.
  • Replace EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewController(_:finished:segmentImages:) with EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewController(_:finished:). The new callback returns a new result class. Score of the liveness check is present in the EyeGazeLivenessResult only if this feature is enabled by the license. The score is nil otherwise.
  • Replace EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerNoMoreSegments(_:) with EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerAllCornersUsed(_:).
  • Remove callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewController(_:stateChanged:). Since version 8.0.0 there is a new callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewController(_:processed:) for handling the current state of the process.
  • Remove callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerEyesNotDetected(_:). Callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerCriticalFacePresenceLost(_:) is used for this event (eyes are not clearly visible in the first corner).
  • Remove callback EyeGazeLivenessViewControllerDelegate.eyeGazeLivenessViewControllerFaceTrackingFailed(_:). This callback was not used in real use cases.

Before

func eyeGazeLivenessViewController(_ viewController: EyeGazeLivenessViewController, stateChanged state: EyeGazeLivenessState) {
    // Handle callback
}

func eyeGazeLivenessViewController(_ viewController: EyeGazeLivenessViewController, finished score: Float, with segmentImages: [SegmentImage]) {
    // Handle callback
}

func eyeGazeLivenessViewControllerNoMoreSegments(_ viewController: EyeGazeLivenessViewController) {
    // Handle callback
}

func eyeGazeLivenessViewControllerEyesNotDetected(_ viewController: EyeGazeLivenessViewController) {
    // Handle callback
}

func eyeGazeLivenessViewControllerFaceTrackingFailed(_ viewController: EyeGazeLivenessViewController) {
    // Handle callback
}

After

func eyeGazeLivenessViewController(_ viewController: EyeGazeLivenessViewController, processed detection: FaceAutoCaptureDetection) {
    // Handle callback
}

func eyeGazeLivenessViewController(_ viewController: EyeGazeLivenessViewController, finished result: EyeGazeLivenessResult) {
    // Handle callback
}

func eyeGazeLivenessViewControllerAllCornersUsed(_ viewController: EyeGazeLivenessViewController) {
    // Handle callback
}

func eyeGazeLivenessViewControllerCriticalFacePresenceLost(_ viewController: EyeGazeLivenessViewController) {
    // Handle callback
}

Eye Gaze Liveness configuration (EyeGazeLivenessViewController.Configuration)

  • Replace class EyeGazeLivenessConfiguration with EyeGazeLivenessViewController.Configuration.
  • Replace implementation RandomSegmentsGenerator with RandomEyeGazeLivenessCornersGenerator.
  • Replace property Segment.durationMillis with EyeGazeLivenessViewController.Configuration.transitionDurationMillis.

Before

let segmentCount = 8
let segmentDurationMillis = 800
let segments = RandomSegmentsGenerator().generate(segmentCount: segmentCount, segmentDurationMillis: segmentDurationMillis)
let configuration = try EyeGazeLivenessConfiguration(transitionType: .move, segments: segments, minFaceSizeRatio: 0.1, maxFaceSizeRatio: 0.3)

After

let cornersGenerator = RandomEyeGazeLivenessCornersGenerator()
let configuration = try EyeGazeLivenessViewController.Configuration(
    faceSizeRatioInterval: try IntervalDouble(min: 0.1, max: 0.3),
    transitionDurationMillis: 800,
    transitionType: .move,
    corners: cornersGenerator.generate(count: 8)
)