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.
# 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.
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.
// 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
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
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:
// 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.
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:
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.
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.
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:
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.
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.
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.
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:
- Barcode Reading (
barcodeRead) - 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.
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 dataexpireDate(String?): Expiration date of the documentaddress(String?): Address information contained in the documentisSameIdentity(Bool?): Whether the identity number matches
Usage Example
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.
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: Returnstrueif address verification is successful, otherwise returnsfalse
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¶
- Business Check (
callBusinessCheck) - Checks for any previous registration - Business Addition (
callBusinessAdd) - New business is added to the system - Employee Management (
callBusinessStaffAdd/Check) - Employees of the business are added or checked if they exist. - Document Management (
callBusinessDocumentAdd) - Required documents are uploaded - Update (
callBusinessUpdate) - Updates the processing status
Functions¶
1. Business Check - callBusinessCheck¶
Checks whether a business is already registered with the given tax number.
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
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
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.
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
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.
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
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
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
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
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
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.
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
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
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.
public static func getDocumentKYBCategoryList(
completionHandler: @escaping ([VerifyInfoDocumentKYBCategoryArrayWrapper]?) -> ()
)
Return Model - VerifyInfoDocumentKYBCategoryArrayWrapper
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
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
ConfirmedQuestiongroup → displayed as ⅓, ⅔, 3/3 - Then it proceeds to the
ConfirmationTextgroup, numbering starts from 1 DisplayCount— how many questions from the group will be displayedIsRandom— 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
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
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
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¶
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
m4aformat, converted to base64 by the SDK and sent to the backend - Video files are recorded in
mp4format, 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.