Skip to content

iOS - Utility Module

The Utility Module provides auxiliary services that support authentication flows. Appointment management, document signing, address verification, and corporate customer verification (KYB) processes are performed through this module.

Introduction

The Utility Module is created to access the auxiliary features of the EnQualify SDK during authentication and customer acquisition. This module includes an appointment system, address verification system, retrieval of call types, document signing, and document addition system, as well as methods used in the process of recognizing a corporate customer.

Adding the Utility Module to the Project

Using the EnQualify SDK Utility Module can be achieved by adding the relevant module and version number into the "Podfile" just like other modules.

Text Only
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
source 'ssh://git@github.com/EnquraTechnology/EnQualifyiOSPackages.git'

target 'EnQualifyPlus-SDK' do
  # Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
  pod 'EnQualify/OCR', '2.0.4.2'
  pod 'EnQualify/Face', '2.0.4.2'
  pod 'EnQualify/NFC', '2.0.4.2'
  pod 'EnQualify/VideoCall', '2.0.4.2'
  pod 'EnQualify/Utility', '2.0.4.2'
  # Pods for EnQualifyPlus-SDK
end

The Utility Module requires the Enqualify/Core module like other auxiliary modules but can be used directly without any additional dependencies.

How to Implement the Utility Module?

The Utility Module operates differently compared to other modules of the EnQualify SDK by using an @escaping closure structure instead of a delegate observation structure. Additionally, since the relevant class does not have its own observe/trigger methods, there is only a delegate structure to relay responses that come from the Core Module.

Text Only
import UtilityModule

class ViewController: UIViewController, EnQualifyUtilityDelegate {

    func someMethodInside() {
        EnQualifyUtility.setBaseModel(with: baseModel: BaseModelUtility, delegate: Any?)
    }

    func baseModelCompleted() { }
    func initializeFailed(with key: CustomNSError) { }
    func deinitializeCompleted(moduleName: String) { }
}

The function EnQualifyUtility.setBaseModel is the place where the address, authorization, and configurations necessary to access the verification platform's information while using the relevant module are defined and communicated to the Core Module. In case of a successful invocation of this function, baseModelCompleted() is triggered; if an issue occurs, initializeFailed(with key: CustomNSError) is triggered and the response within CustomNSError can be evaluated.

Text Only
// BaseModelUtility
    public var signallingCertificateList: [String]?
    public var mapiCertificateList: [String]?
    public var signallingCertificateBase64List: [String]?
    public var mapiCertificateBase64List: [String]?
    public var baseURL: String?
    public var locale: String?
    public var mobileUser: String?
    public var countryCode: String?

Here, the desired BaseModelUtility is the same as CoreBaseModel that needs to be provided in the auxiliary modules of the EnQualify SDK.

Retrieval of Call Types

The call types function is used to determine which types of call methods are available during verification and identity control processes. This information helps dynamically determine the verification options to be presented to the user. It allows you to use the specific settings you have defined for these call types.

Function

Retrieve Call Type - callTypeGet

Retrieves all call types available in the system.

Syntax

Text Only
public static func callTypeGet(
    with handler: String?, 
    completionHandler: @escaping ([String: String]?) -> ()
)

Parameters

Parameter Type Description
handler String? Optional identifier or context information for the request
completionHandler ([String: String]?) -> () Completion block returning the call types

When retrieving default KYC call types, if KYB call types are desired, the handler should be set to "KYB".

Return Value

  • [String: String]?: A dictionary containing call types

  • Key: Call type code/ID

  • Value: Call type description/name

Usage Example

Text Only
EnQualifyCore.callTypeGet(with: "CONTEXT_ID_123") { callTypes in
    guard let callTypes = callTypes else {
        print("Call types could not be retrieved")
        return
    }

    print("Available call types:")
    for (key, value) in callTypes {
        print("Code: \(key) - Description: \(value)")
    }
}

Usage of Handler Parameter

The handler parameter can be used to provide optional context information for the request:

Text Only
// Call types for a specific operation
EnQualifyUtility.callTypeGet(with: "KYB") { callTypes in
}

// Call types for general use
EnQualifyUtility.callTypeGet(with: nil) { callTypes in
}

Appointment System

What is an Appointment?

The EnQualify SDK has a two-stage (modular) verification system compliant with regulations. After the completion of the first stage, which is the Self-Service flow, if necessary, Video Call should continue. If the agents available in your system are too occupied or for other different reasons, you can create an appointment to set the time for the video call when the prospective customer cannot join at that moment. With this appointment management system, it is possible to check existing appointments, cancel an existing appointment, retrieve the date and time of new appointments, and create a new appointment.

Accessing the Appointment System

Due to the modular structure of the EnQualify SDK, the appointment system is designed to be accessible through each module. You can access all the capabilities of the appointment system via EnQualifyOCR, EnQualifyNFC, EnQualifyFace, and EnQualifyVideoCall.

Checking Existing Appointment

Before the user starts the flow, if there is an appointment previously created for them, it can be checked with the appointmentGet method.

Text Only
import UtilityModule

/// Identity Type: "T.C. Kimlik Kartı"
/// Identity No: "12345678901"
 EnQualifyUtility.appointmentGet(identityType: String?, identityNo: String?) { result in
 }

After this invocation, when you capture the result returned to you, you will access data of type [[String: AnyObject]]. This data type will present you with a structure made up of key-value pairs. To examine the returned data:

Text Only
uId: UUID?                   // A unique reference for your appointment
callType: String?            // Which callType the appointment belongs to
callTypeValue: String?       // The UI name of the respective callType on the verification platform
identityType: String?        // The type of identity for the appointment
identityNo: String?          // The identity number of the appointment
name: String?                // The name of the person making the appointment
surname: String?             // The surname of the person making the appointment
phone: String?               // The phone number of the person making the appointment
email: String?               // The email address of the person making the appointment
startDate: String?           // The date of the appointment
endDate: String?             // The last date to participate in the appointment
isPriorityCustomer: Bool?    // Indicates the priority of the appointment.

Canceling Existing Appointment

If the user wishes, they can cancel the appointment they previously created. The API provided by the EnQualify SDK for canceling a previously created appointment is the appointmentCancel API.

Text Only
import UtilityModule
/// callType : "NewCustomer"
/// identityType: "T.C. Kimlik Kartı"
/// identityNo: "12345678901"
EnQualifyUtility.appointmentCancel(callType: String, identityType: String, identityNo: String) { result in 

}

The result of this invocation will return a Bool value with information regarding the cancellation status of the appointment you wish to cancel.

Checking Available Appointments

In situations where users need to create an appointment and determine an appropriate time, they can access the dates and times of appointments predefined on the verification platform along with the specified slots. In order to reach this check, the appointmentAvailableGet API provided by the EnQualify SDK is used.

Text Only
import UtilityModule
/// callType: "NewCustomer"
/// startDate: "2025-01-23T04:56:07.000+00:00"
/// endDate: "2025-01-23T04:56:07.000+00:00"
EnQualifyUtility.appointmentAvailableGet(callType: String?, startDate: String?, endDate: String?) { result in 
}

After this call, when you capture the result returned to you, you will have access to data of type [[String: AnyObject]]. This data type will present you with a structure made up of key-value pairs. To examine the returned data:

Text Only
date: String?            // The date the appointment belongs to
startTime: String?       // The start time of the appointment
endTime: String?         // The end time of the appointment
count: String?           // The number of appointments in the time slot

Creating an Appointment

Users can create an appointment by determining a suitable date and time. To perform this operation, the appointmentSave API provided by the EnQualify SDK is used.

Text Only
import UtilityModule
/// callType: "NewCustomer"
/// date: "2025-05-09T00:00:00Z"
/// startTime: "14:45:00"
/// identityType: "T.C. Kimlik Kartı"
/// identityNo: "12345678901"
/// name: "Ahmet"
/// surname: "Yılmaz"
/// phone: "05993311920"
/// email: "example@enqura.com"
/// uId: "c18683b4-8c79-47ef-bd93-60f54c64e8de"
EnQualifyUtility.appointmentSave(callType: String?, date: String?, startTime: String?, identityType: String?, identityNo: String?, name: String?, surname: String?, phone: String?, email: String?, uId: UUID?) { result in 
}

This invocation will return a Bool type result indicating the appointment creation status for the specified date and time.

Document Signing

5.2.7. Document Signing

Secure Document Signing from Mobile

Our document signing process carried out via mobile devices has a secure structure that guarantees both the user's approval and the integrity of the signed content. When a user wants to sign a document, a special key is sent to their mobile device. This key allows a specific hash of the document to be taken to create a signature unique to that user.

This signature is then recorded in our system, which always makes it possible to prove that the signed document has not been altered and has indeed been approved by that user.

Text Only
EnQualifyUtility.signingSet(data: Data, reference: String? = nil) { (status: Bool) in 
}

When the document is successfully signed, the status parameter will return true. Within this closure, if no further document signing is to be done, the function EnQualifyUtility.signingFinish() can be invoked.

If the document signing process fails, the status parameter will return false. This value can be evaluated according to the workflow to either proceed to other operations or show an error message to the user.

When the document signing is completed, the captured Bool value for status in the invocation of EnQualifyUtility.signingFinish() will indicate the successful completion of the signing process, signaling that the Customer API has been triggered. A false result indicates that the process could not be appropriately communicated to the verification platform due to an error encountered at this stage.

Text Only
EnQualifyUtility.signingFinish(reference: String? = nil)

Address Verification

The address verification system is used to check whether the identity information on users' identity documents corresponds with the information contained in the barcode address verification document. This process is carried out with two main functions:

  1. Barcode Reading (barcodeRead)
  2. Address Verification (addressVerify)

Functions

1. Barcode Reading - barcodeRead

This function is used to read information from the barcode on the residence document and parse it.

Text Only
public static func barcodeRead(
    content: String?, 
    isWithAddress: AnyObject?, 
    identityNo: String?, 
    completionHandler: @escaping (String?, String?, String?, Bool?) -> ()
)

Parameters

Parameter Type Description
content String? Raw data content read from the barcode
isWithAddress AnyObject? Optional parameter indicating whether to include address information
identityNo String? T.C. identity number
completionHandler (String?, String?, String?, Bool?) -> () Completion block to be called once the operation is completed

Completion Handler Return Values

The completion handler returns the following parameters:

  • barcode (String?): Processed barcode data
  • expireDate (String?): Expiration date of the document
  • address (String?): Address information contained in the document
  • isSameIdentity (Bool?): Whether the identity number matches

Usage Example

Text Only
import UtilityModule

EnQualifyUtilty.barcodeRead(
    content: "base64DataSample",
    isWithAddress: true,
    identityNo: "12345678901",
    completionHandler: { barcode, expireDate, address, isSameIdentity in
        guard let barcode = barcode,
              let address = address,
              let isSameIdentity = isSameIdentity,
              isSameIdentity else {
            print("Barcode reading failed")
            return
        }

        print("Barcode: \(barcode)")
        print("Expiration Date: \(expireDate ?? "Not Specified")")
        print("Address: \(address)")
    }
)

2. Address Verification - addressVerify

This function is used to connect with the Population and Citizenship Affairs system along with the address information on the residence document to verify the accuracy of the information contained in the relevant document.

Text Only
public static func addressVerify(
    identityNo: String, 
    barcode: String, 
    completionHandler: @escaping (Bool) -> ()
)

Parameters

Parameter Type Description
identityNo String T.C. identity number
barcode String Barcode data to be verified
completionHandler (Bool) -> () Completion block to be called once the operation is completed

Completion Handler Return Value

  • Bool: Returns true if address verification is successful, otherwise returns false
Text Only
import UtilityModule

EnQualifyUtilty.addressVerify(
    identityNo: "12345678901",
    barcode: "barcode_string",
    completionHandler: { isVerified in
        if isVerified {
            print("Address verification successful")
            // Successful verification operations
        } else {
            print("Address verification failed")
            // Error handling operations
        }
    }
)

Corporate Customer Processes (KYB - Know Your Business)

Overview

The business verification system is utilized to introduce corporate customers into the system prior to identity verification procedures. This process consists of stages such as recording business information, employee management, and collecting necessary documents.

Basic Workflow

  1. Business Check (callBusinessCheck) - Checks for any previous registration
  2. Business Addition (callBusinessAdd) - New business is added to the system
  3. Employee Management (callBusinessStaffAdd/Check) - Employees of the business are added or checked if they exist.
  4. Document Management (callBusinessDocumentAdd) - Required documents are uploaded
  5. Update (callBusinessUpdate) - Updates the processing status

Functions

1. Business Check - callBusinessCheck

Checks whether a business is already registered with the given tax number.

Text Only
public static func callBusinessCheck(
    taxNumber: String,
    reference: String? = nil,
    completionHandler: @escaping (VerifyCallBusinessCheckModelWrapper?) -> ()
)

Parameters

Parameter Type Description
taxNumber String Business tax number
reference String? Transaction reference information (optional)
completionHandler (VerifyCallBusinessCheckModelWrapper?) -> () Completion block to be called once the operation is completed

Return Model - VerifyCallBusinessCheckModelWrapper

Text Only
public var checkRecord: AnyObject?      // Is there a previous registration?
public var callBusinessUId: String?     // Business ID pertaining to this transaction
public var type: String?               // Business type (limited/sole proprietorship)

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.callBusinessCheck(
    taxNumber: "1234567890",
    reference: "REF123",
    completionHandler: { result in
        guard let result = result else {
            print("Business check failed")
            return
        }

        if result.checkRecord != nil {
            print("The business has been registered before")
            print("Business ID: \(result.callBusinessUId ?? "Not Specified")")
            print("Type: \(result.type ?? "Not Specified")")
        } else {
            print("New business registration is required")
        }
    }
)

2. Business Addition - callBusinessAdd

Adds a new business to the system.

Text Only
public static func callBusinessAdd(
    taxNumber: String,
    name: String,
    shortName: String? = nil,
    data: String? = nil,
    type: String? = nil,
    reference: String? = nil,
    completionHandler: @escaping (String?) -> ()
)

Parameters

Parameter Type Description
taxNumber String Business tax number
name String Full name of the business
shortName String? Short name of the business (optional)
data String? Additional information for dashboard view on the verification platform
type String? Business type ("limited" or "sole proprietorship")
reference String? Transaction reference information
completionHandler (String?) -> () Returns the business ID after the operation

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.callBusinessAdd(
    taxNumber: "1234567890",
    name: "Örnek Şirket A.Ş.",
    shortName: "Örnek Şirket",
    data: "Additional information for Dashboard", // will be sent in JSON format.
    type: "limited",
    reference: "REF123",
    completionHandler: { businessId in
        if let businessId = businessId {
            print("Business successfully added. Business ID: \(businessId)")
        } else {
            print("Business addition failed")
        }
    }
)

3. Employee Addition - callBusinessStaffAdd

Adds a new employee to the business.

Text Only
public static func callBusinessStaffAdd(
    callBusinessUID: String?,
    sessionUId: String?,
    name: String,
    surname: String,
    identityNo: String,
    birthDate: String,
    phone: String,
    completionHandler: @escaping (AnyObject?) -> ()
)

Parameters

Parameter Type Description
callBusinessUID String? Unique business ID
sessionUId String? Session ID
name String Employee's name
surname String Employee's surname
identityNo String T.C. identity number
birthDate String Birth date
phone String Phone number
completionHandler (AnyObject?) -> () Result of the operation

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.callBusinessStaffAdd(
    callBusinessUID: "BUSINESS_123",
    sessionUId: "SESSION_456",
    name: "Ahmet",
    surname: "Yılmaz",
    identityNo: "12345678901",
    birthDate: "1990-01-15",
    phone: "+905551234567",
    completionHandler: { result in
        if result != nil {
            print("Employee successfully added")
        } else {
            print("Employee addition failed")
        }
    }
)

4. Employee Check - callBusinessStaffCheck

Checks if an employee of the business is registered.

Syntax

Text Only
public static func callBusinessStaffCheck(
    identityNo: String,
    callBusinessUID: String?,
    completionHandler: @escaping (AnyObject?) -> ()
)

Parameters

Parameter Type Description
identityNo String T.C. identity number of the employee to be checked
callBusinessUID String? Unique business ID
completionHandler (AnyObject?) -> () Check result (should be cast to Bool).

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.callBusinessStaffCheck(
    identityNo: "12345678901",
    callBusinessUID: "BUSINESS_123",
    completionHandler: { result in
        if result != nil {
            print("Employee exists")
        } else {
            print("Employee not found")
        }
    }
)

5. Business Update - callBusinessUpdate

Updates the status of the business record.

Syntax

Text Only
public static func callBusinessUpdate(
    callBusinessUID: String?,
    reference: String?,
    isInProgress: AnyObject?,
    type: String?,
    completionHandler: @escaping (AnyObject?) -> ()
)

Parameters

Parameter Type Description
callBusinessUID String? Unique business ID
reference String? Transaction reference information
isInProgress AnyObject? Whether the process is ongoing (true/false)
type String? Business type
completionHandler (AnyObject?) -> () Update result (should be cast to Bool).

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.callBusinessUpdate(
    callBusinessUID: "BUSINESS_123",
    reference: "REF123",
    isInProgress: true,
    type: "limited",
    completionHandler: { result in
        if result != nil {
            print("Business status updated")
        } else {
            print("Update failed")
        }
    }
)

6. Document Addition - callBusinessDocumentAdd

Uploads documents related to the business to the system.

Text Only
public static func callBusinessDocumentAdd(
    category: String?,
    reference: String?,
    callBusinessUId: String?,
    document: [VerifyMobileCallBusinessDocumentArrayWrapper]?,
    completionHandler: @escaping (AnyObject?) -> ()
)

Parameters

Parameter Type Description
category String? Document category
reference String? Transaction reference information
callBusinessUId String? Unique business ID
document [VerifyMobileCallBusinessDocumentArrayWrapper]? Array of documents to be uploaded
completionHandler (AnyObject?) -> () Loading result (should be cast to Bool).

Document Model - VerifyMobileCallBusinessDocumentArrayWrapper

Text Only
public var extension: String?      // File extension (pdf, jpg, png, etc.)
public var content: String?        // File content (in Base64 format)
public var contentHash: String?    // File hash value

Usage Example

Text Only
import UtilityModule

let document = VerifyMobileCallBusinessDocumentArrayWrapper()
document.extension = "pdf"
document.content = "Base64EncodedFileContent"
document.contentHash = "SHA256HashValue"

EnQualifyUtility.callBusinessDocumentAdd(
    category: "TICARET_SICIL_GAZETESI",
    reference: "REF123",
    callBusinessUId: "BUSINESS_123",
    document: [document],
    completionHandler: { result in
        if result != nil {
            print("Document successfully uploaded")
        } else {
            print("Document upload failed")
        }
    }
)

7. KYB Document Category List - getDocumentKYBCategoryList

Retrieves the categories of the documents to be added in the KYB flow.

Text Only
public static func getDocumentKYBCategoryList(
    completionHandler: @escaping ([VerifyInfoDocumentKYBCategoryArrayWrapper]?) -> ()
)

Return Model - VerifyInfoDocumentKYBCategoryArrayWrapper

Text Only
public var category: String?       // Category code
public var name: String?           // Category name (in Turkish)
public var nameEn: String?         // Category name (in English)
public var isRequired: AnyObject?  // Is it required?
public var sequence: NSNumber?     // Ordering
public var secondPhase: AnyObject? // Is it needed in the second phase?

Usage Example

Text Only
import UtilityModule

EnQualifyUtility.getDocumentKYBCategoryList { categories in
    guard let categories = categories else {
        print("Category list could not be retrieved")
        return
    }

    for category in categories {
        print("Category: \(category.category ?? "Not Specified")")
        print("Name: \(category.name ?? "Not Specified")")
        print("Required: \(category.isRequired ?? false)")
        print("---")
    }
}

Voice Verification

1. Product Description

The EnQualify Voice Verification SDK is a mobile integration solution that adds a voice and video layer to identity verification processes. Your customers respond to questions on the screen with their voice; the system analyzes these responses to perform identity confirmation.

What is it Useful For?

  • Fully digital identity verification without a customer representative
  • Two-layer verification with voice response + video recording
  • Flexible scenario construction through groups of questions (verified questions, confirmation text, unverified questions)
  • Responses are processed with STT (speech-to-text) and matched on the backend side

2. User Flow

Step Screen and Process
1 — Preparation An information screen is displayed. Microphone and camera permission are requested. The user presses the "Start" button; question configuration is fetched from the service in the background.
2 — Voice Response For each question, the user records their answer by pressing the microphone button. Recording can be paused, replayed, and deleted. When the send button is pressed, audio and video are transmitted to the backend; the STT result is returned in real time.
3 — Confirmation All responses are listed on a summary screen. If the user finds an answer incorrect, they can re-record that question. When the "I approve" button is pressed, the final validation service is called.

Successful — Summary screen is shown, flow is directed to the next step.
Failed — User can restart with "Try Again".
⚠️ Technical Error — User is directed to a video call.


3. Question Configuration

ContentType Description
ConfirmedQuestion Questions that verify the user's identity information (e.g., father's name, serial number). Responses are matched with stored data on the backend.
ConfirmationText Texts that the user must confirm verbally (e.g., contract clauses, product information).
UnconfirmedQuestion Open-ended response questions. No matching of responses is performed; audio recording is taken.
  • If there are 3 questions in the ConfirmedQuestion group → displayed as ⅓, ⅔, 3/3
  • Then it proceeds to the ConfirmationText group, numbering starts from 1
  • DisplayCount — how many questions from the group will be displayed
  • IsRandom — whether or not the questions will be displayed in random order

4. Technical Integration

The SDK operates through three services. The integration order is as follows:

4.1 Requirements

  • iOS 14+
  • Swift 5.7+
  • EnQualifyUtility framework (UtilityModule)
  • Info.plist: NSMicrophoneUsageDescription, NSCameraUsageDescription

4.2 Step 1 — Initialize the SDK and Retrieve Questions

A session is started with conversationalValidationLaunch. After a successful connection, a delegate callback is triggered, and the question list is received through this callback.

swift

Text Only
EnQualifyUtility.conversationalValidationLaunch(
    baseModel: baseModel,
    sessionModel: sessionModel,
    delegate: self
)

// Delegate callback — questions come through this method
func conversationalValidationConfigGetCompleted(
    config: [VerifyVoiceVerificationMobileListWrapper]?
) {
    // config includes questions, content types,
    // displayCount, isRandom, and expectedAnswers
}

SessionModelUtility parameters:

Parameter Description
callType Call type (e.g., "NewCustomer")
name / surname User's name and surname
identityNo TC identity number
reference Unique transaction reference (UUID)

4.3 Step 2 — Send Audio and Video for Each Question

After the user answers each question, callVoiceVerificationAdd is called. The SDK automatically processes and sends the audio and video files to the backend. The STT result is returned in the answer field.

swift

Text Only
EnQualifyUtility.callVoiceVerificationAdd(
    videoContentURL: videoFileURL,       // mp4 recorded from camera
    soundContentURL: audioFileURL,       // m4a recorded from microphone
    voiceVerificationContentUId: contentUId  // Which question it relates to
) { response in
    let answer = response?.answer ?? ""
    // answer filled   → STT successful, proceed to the next question
    // empty answer    → STT failed, show error to the user
    // response nil    → technical error
}

The contentUId value comes from the question configuration (VerifyVoiceVerificationMobileListWrapper.contentUId) and is unique for each question.

4.4 Step 3 — Get Confirmation When All Questions Are Completed

After the user has approved all responses, callVoiceVerificationApproved is called.

swift

Text Only
EnQualifyUtility.callVoiceVerificationApproved { isApproved in
    if isApproved {
        // Verification successful → proceed to the next step
    } else {
        // Verification failed → show error to the user
    }
}

4.5 Service Flow Summary

Text Only
conversationalValidationLaunch()
conversationalValidationConfigGetCompleted (delegate)
[ For each question ]
callVoiceVerificationAdd(video, sound, contentUId)
        ↓  response.answer
[ All questions completed ]
callVoiceVerificationApproved()
        ↓  true / false

5. Security and Data Flow

  • Audio files are recorded in m4a format, converted to base64 by the SDK and sent to the backend
  • Video files are recorded in mp4 format, without audio track
  • Audio and video for each question are sent separately (matched with contentUId)
  • STT processing occurs on the backend side; no text analysis is performed on the mobile device.