This Framework will help you to build a verification process for your project, the goal is to build easy steps which you can run and get the result to your system or in your application. It is built on top of standard Apple Libraries. This part of our SDK's contains common logic for other frameworks and it helps to run the verification process.
The whole process is going synchronously from the first to the last step. During the process, data will be sent to our or your backend. The process will stop if any of the steps will return an error.


SDK can be configured via config property on the shared instance. Config has one configuration variable:
  • configuration, this is enum where you can configure how data will be transfered to the servers.
public enum Configuration {
/// All data will process by cloud backend
case cloud
/// The step data will not move outside of the device
case local
/// Custom Host Configuration
case custom(config: CustomHostConfiguration)
public struct CustomHostConfiguration {
/// HTTPS Host to which data will be sent.
/// Example: https://example.com
public var host: String
/// Path to which data will be sent.
/// Example: /api/sdk/workplace/verification
public var mainPath: String
/// Optional, if you support custom auth in standart format for SDK, then you can use this property.
/// Example: /api/sdk/auth/signIn
public var authPath: String?
/// Turn on/off data encryption,
public var encryptData: Bool
/// Optional. If set then SDK will validate signature
public var rssigSalt: String?
/// Optional. If set then SDK will use this token for authorization
public var accessToken: String?
  • isInDebug, bool variable, if true then you will see additional logs, false by default
  • faceSDKLocalizationHandler, to change existing localization you can utilize the localization hook localizationHandler provided by Face SDK. This closure is called every time a string is requested. By returning nil we fallback to the default localization provided by SDK.
"hint.fit" = "Fit your face in the oval";
"hint.lookStraight" = "Look straight";
"hint.moveAway" = "Move away";
"hint.moveCloser" = "Move closer";
"hint.stayStill" = "Hold steady";
"livenessProcessing.title.processing" = "Processing...";
"livenessRetry.action.retry" = "Retry";
"livenessRetry.text.guidelines" = "But please follow these guidelines:";
"livenessRetry.text.noGlare" = "No glare or extreme lighting";
"livenessRetry.text.noSmiling" = "Neutral expression, no smiling";
"livenessRetry.title.tryAgain" = "Let’s try that again";
"noCameraPermission.action.ok" = "OK";
"noCameraPermission.action.settings" = "Settings";
"noCameraPermission.text.changeSettings" = "The application doesn't have permission to use the camera, please change the privacy settings";
"noCameraPermission.title.unavailable" = "Camera unavailable";
CustomHostConfiguration is a struct where you can configure your custom host. This struct has a bunch of rules and properties, they intersect with each other, so I will describe them in detail.
The main difference is how SDK connects to a host where it saves data.
  • authPath - You can set this path if your host will implement the same authorization system like Elkyc cloud has.
  • accessToken - You can set your custom Bearer token, instead of having authPath. BUT authPath has a higher priority.
  • encryptData - right now working ONLY if authPath is set. Will encrypt JSON data with AES-256-CTR standard.
  • rssigSalt - If you set this value then JSON data will be validated with Bcrypt standard.

ElkycStep Protocol

All our frameworks contain many predefined steps which you can configure. Usually, you should not implement your step but you can, probably you will need this if you want to add your custom UI to the verification process. In this section, you can find a way how to do that, as well as what basic operations on steps you can perform.
public protocol ElkycStep: AnyObject {
associatedtype Output
var stepId: ElkycStepId { get set}
func start(from viewController: UIViewController, completion: @escaping ((Result<Output, Error>) -> Void))
public struct ElkycStepId {
public var id: String = UUID().uuidString
public var stepType: StepType

Basic Operations

All basic operations help you transform and connect all steps into one chain - flow. Below you can find the quick explanation about each function with an example.
  • next - A function that transforms output from step into a new step.
func next<Second: ElkycStep>(_ next: @escaping (Output) -> Second) -> AnyElkycStep<Second.Output>
DocumentScan(documentMask: .empty).next { docResult -> DocumentConfirm in
return DocumentConfirm(docImage: docResult.mainDocumentImage())
  • combine - A function that combines two steps result into one.
func combine<Second: ElkycStep>(_ zipped: @escaping (Output) -> Second) -> AnyElkycStep<(Self.Output, Second.Output)>
DocumentScan(documentMask: .empty).combine { docResult -> DocumentConfirm in
return DocumentConfirm(docImage: docResult.mainDocumentImage())
  • retry - A function that attempts to recreate its step when closure returns true.
func retry(when: @escaping (Self.Output) -> Bool) -> AnyElkycStep<Self.Output>
DocumentConfirm(docImage: UIImage()).retry { result -> Bool in
switch result {
case .retry:
return true
case .next:
return false
  • map - A function that transforms output from the step with a provided closure.
func map<NewOutput>(_ map: @escaping (Self.Output) -> NewOutput) -> AnyElkycStep<NewOutput>
AcceptTerms().map { return "Success" }
  • eraseToAnyStep - Wraps the step with a type eraser.
func eraseToAnyStep() -> AnyElkycStep<Self.Output>
AcceptTerms().map { return "Success" }.eraseToAnyStep()
  • just - Constructor which helps to create just a step with a value inside
AnyElkycStep.just("Hello World!")


If you want to create your step this is not something hard, you should just implement ElkycStep protocol with custom id. Here is an example.
public class Custom: ElkycStep {
public let stepId: ElkycStepId = .custom
public func start(from viewController: UIViewController, completion: @escaping ((Result<Void, Error>) -> Void)) {
let customViewController: CustomViewController = CustomViewController()
customViewController.completion = completion
setCurrent(step: customViewController, from: viewController)


You can use this step as a step after selfie with doc photo.
  • config
public var title: String
public var docImage: UIImage?
public var mainBtnBackgroundColor: UIColor
public var mainBtnTintColor: UIColor
public var mainBtnTitle: String
public var retryBtnBackgroundColor: UIColor
public var retryBtnTintColor: UIColor
public var retryBtnTitle: String
public var isRetryBtnHidden: Bool
public var hints: [DocumentConfirmHintViewModel]?
As output, you will receive a StepResult enum. Which lets you understand what action was chosen by the user. This step has two action buttons - retry and next
enum StepResult {
case retry
case next