autentikar
Customization

Core

Configure Core colors, typography, loading UI, and custom iOS instruction screens for Autentikar SDK.

Shared visual theme

AutentikarCoreCustomization defines the base visual language used by the primary SDK flows. Its component configurations cover:

  • Title
  • Text
  • Caption
  • FooterText
  • Button
  • Confirm
  • Instructions
  • LoadingView

Apply this configuration once through AutentikarManager; modules that inherit Core styling then use the same visual foundation.

iOS

Apply the customization

AutentikarConfiguration.swift
let custom = AutentikarCoreCustomization()
custom.backgroundColor = .black
custom.title.color = .white
custom.button.activeColor = .blue

AutentikarManager.shared.setCustomization(custom)

Configure the object before starting an Autentikar flow. You can change only the properties required by your design; every other property keeps its default value.

Property reference

General appearance and content

PropertyTypeDefaultPurpose
backgroundColorUIColor.whiteBackground shared by the Core screens.
animationColor[UIColor][#082C4C]Colors used by the processing animation.
logoNameString"Autentikar"Name of the logo asset loaded from the configured bundle.
showLogoBooltrueShows or hides the logo on general Core screens. The consent screen uses confirm.showLogo.
showFooterClaimsBooltrueShows or hides the rotating footer messages.
loadingViewAutentikarLoadingProvider?nilReplaces the standard loading UI.

Typography

PropertyTypeDefaultPurpose
title.fontUIFontPlus Jakarta Sans SemiBold, 18 ptFont used for screen titles.
title.colorUIColor#3A3A3CTitle color.
text.fontUIFontPlus Jakarta Sans Regular, 16 ptFont used for body text.
text.fontBoldUIFontPlus Jakarta Sans SemiBold, 16 ptBold font used in attributed body text.
text.colorUIColor#3A3A3CBody text color.
caption.fontUIFontPlus Jakarta Sans Light, 16 ptFont used for captions.
caption.colorUIColor#3A3A3CCaption color.
footerText.fontUIFontPlus Jakarta Sans Regular, 16 ptFont used for rotating footer messages.
footerText.colorUIColor#3A3A3CFooter message color.
footerText.claims[String]Five localized Core messagesMessages displayed in rotation in the footer.

Buttons

PropertyTypeDefaultPurpose
button.fontUIFontPlus Jakarta Sans Regular, 16 ptButton title font.
button.activeTextColorUIColor.whiteText color for enabled primary buttons.
button.activeColorUIColor#082C4CBackground color for enabled primary buttons.
button.disableTextColorUIColor.whiteText color for disabled buttons.
button.disabledColorUIColor#5F6368Background color for disabled buttons.
button.cornerRadiusCGFloat10Corner radius of standard buttons in points.
button.outlineColorUIColor#082C4CBorder and text color for outlined buttons.

Confirmation controls

PropertyTypeDefaultPurpose
confirm.toggleColorOnUIColor#082C4CToggle color in the enabled state.
confirm.toggleColorOffUIColor#5F6368Toggle color in the disabled state.
confirm.linkTextColorUIColor#082C4CColor used by links in the confirmation content.
confirm.showLogoBooltrueShows or hides the logo only on the consent screen. Available starting with Core 1.0.15.
When migrating to 1.0.15, if you previously used showLogo = false to hide the logo throughout the flow, also set confirm.showLogo = false.

Standard instruction screens

These colors apply to the standard document and liveness instruction screens. Starting with Core 1.0.15, those screens no longer display a close button. The provider properties replace those screens completely and are described in Custom instruction screens.

PropertyTypeDefaultPurpose
instructions.iconColorUIColor#082C4CColor of the instruction item icons.
instructions.closeIconColorUIColor#082C4CRetained for compatibility; standard screens no longer display the close icon starting with 1.0.15.
instructions.photoIDScanViewProviderAutentikarInstructionViewProvider?nilReplaces the document instruction screen.
instructions.livenessCheckViewProviderAutentikarInstructionViewProvider?nilReplaces the liveness instruction screen.

Remote image on iOS instruction screens

Starting with Core 1.0.15, the standard document and liveness instruction screens can display the remote image supplied by the active step through header_image. This setting comes from the server; you do not need to assign it in AutentikarCoreCustomization.

Step response
{
  "header_image": {
    "alt": "header",
    "src": "https://example.com/instructions.png",
    "type": "image/png"
  }
}

When alt is header and src contains a valid image, the image replaces the standard title, description, and instruction list. The continue button remains visible. If the image is unavailable or cannot be loaded, the SDK automatically restores the standard content.

A configured photoIDScanViewProvider or livenessCheckViewProvider takes precedence and replaces the entire standard screen. Core does not insert header_image into a custom view; the application controls its content completely.

Complete visual example

CoreCustomization.swift
import AutentikarCore
import UIKit

let custom = AutentikarCoreCustomization()

custom.backgroundColor = .systemBackground
custom.animationColor = [.systemCyan, .systemBlue]
custom.logoName = "CompanyLogo"
custom.showLogo = true
custom.showFooterClaims = true

custom.title.font = .boldSystemFont(ofSize: 20)
custom.title.color = .label
custom.text.font = .systemFont(ofSize: 16)
custom.text.fontBold = .boldSystemFont(ofSize: 16)
custom.text.color = .label
custom.caption.font = .systemFont(ofSize: 14)
custom.caption.color = .secondaryLabel

custom.footerText.font = .systemFont(ofSize: 14)
custom.footerText.color = .secondaryLabel
custom.footerText.claims = [
    "Your information is protected.",
    "This process will only take a moment."
]

custom.button.font = .boldSystemFont(ofSize: 16)
custom.button.activeTextColor = .white
custom.button.activeColor = .systemBlue
custom.button.disableTextColor = .tertiaryLabel
custom.button.disabledColor = .systemGray5
custom.button.cornerRadius = 24
custom.button.outlineColor = .systemBlue

custom.confirm.toggleColorOn = .systemBlue
custom.confirm.toggleColorOff = .systemGray
custom.confirm.linkTextColor = .systemBlue
custom.confirm.showLogo = true

custom.instructions.iconColor = .systemBlue

AutentikarManager.shared.setCustomization(custom)

Custom loading view

Starting with Core 1.0.11, loadingView accepts either a SwiftUI or UIKit provider.

AutentikarConfiguration.swift
// SwiftUI
let custom = AutentikarCoreCustomization()
custom.loadingView = AutentikarSwiftUILoadingProvider {
    ProgressView()
        .tint(.blue)
        .scaleEffect(2)
}

AutentikarManager.shared.setCustomization(custom)
AutentikarConfiguration.swift
// UIKit
let custom = AutentikarCoreCustomization()
let spinner = UIActivityIndicatorView(style: .large)
spinner.startAnimating()
spinner.color = .red

custom.loadingView = AutentikarUIKitLoadingProvider(view: spinner)
AutentikarManager.shared.setCustomization(custom)

Custom instruction screens

Starting with Core 1.0.14, you can completely replace the instruction screen shown before document capture or liveness verification. The SDK supports SwiftUI, UIView, UIViewController, and Objective-C implementations.

ScreenConfiguration property
Document capturecustom.instructions.photoIDScanViewProvider
Liveness verificationcustom.instructions.livenessCheckViewProvider

Each provider receives an AutentikarInstructionActions object. Connect your UI controls to these actions so the SDK can keep control of the flow:

  • actions.agree() closes the instructions and starts the corresponding capture step.
  • actions.dismiss() closes the instructions without starting the capture step.
The provider factory runs every time the instruction screen is presented. Always return a new view or view controller. If a provider is nil, the SDK displays its standard instruction screen, so each screen can be customized independently.

Select the implementation that matches your application's UI technology:

import AutentikarCore
import SwiftUI

struct BrandedInstructionView: View {
    let title: String
    let actions: AutentikarInstructionActions

    var body: some View {
        VStack(spacing: 24) {
            Text(title)
                .font(.title.bold())

            Text("Follow the instructions shown by your organization.")
                .multilineTextAlignment(.center)

            Button("Continue") {
                actions.agree()
            }
            .buttonStyle(.borderedProminent)

            Button("Cancel", role: .cancel) {
                actions.dismiss()
            }
        }
        .padding(32)
    }
}

let custom = AutentikarCoreCustomization()

custom.instructions.photoIDScanViewProvider =
    AutentikarSwiftUIInstructionViewProvider { actions in
        BrandedInstructionView(
            title: "Photograph your ID",
            actions: actions
        )
    }

custom.instructions.livenessCheckViewProvider =
    AutentikarSwiftUIInstructionViewProvider { actions in
        BrandedInstructionView(
            title: "Center your face",
            actions: actions
        )
    }

AutentikarManager.shared.setCustomization(custom)

AutentikarSwiftUIInstructionViewProvider accepts any SwiftUI View. For UIKit, use AutentikarUIKitInstructionViewProvider with a view or AutentikarInstructionControllerProvider when the SDK needs to integrate a UIViewController lifecycle.

Objective-C

The UIKit providers and action methods are exposed to Objective-C. Import the framework's generated interface and configure the provider before starting the Autentikar flow.

@import AutentikarCore;
@import UIKit;

AutentikarCoreCustomization *custom =
    [[AutentikarCoreCustomization alloc] init];

custom.instructions.photoIDScanViewProvider =
    [[AutentikarUIKitInstructionViewProvider alloc]
        initWithViewBuilder:^UIView *(
            AutentikarInstructionActions *actions
        ) {
            UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
            [button setTitle:@"Continue" forState:UIControlStateNormal];
            [button addAction:[UIAction actionWithHandler:^(__kindof UIAction *action) {
                [actions agree];
            }] forControlEvents:UIControlEventTouchUpInside];

            UIButton *cancel = [UIButton buttonWithType:UIButtonTypeSystem];
            [cancel setTitle:@"Cancel" forState:UIControlStateNormal];
            [cancel addAction:[UIAction actionWithHandler:^(__kindof UIAction *action) {
                [actions dismiss];
            }] forControlEvents:UIControlEventTouchUpInside];

            UIStackView *stack = [[UIStackView alloc]
                initWithArrangedSubviews:@[button, cancel]];
            stack.axis = UILayoutConstraintAxisVertical;
            stack.spacing = 16;

            UIView *view = [[UIView alloc] init];
            view.backgroundColor = UIColor.systemBackgroundColor;
            stack.translatesAutoresizingMaskIntoConstraints = NO;
            [view addSubview:stack];
            [NSLayoutConstraint activateConstraints:@[
                [stack.leadingAnchor constraintEqualToAnchor:view.leadingAnchor
                                                    constant:32],
                [stack.trailingAnchor constraintEqualToAnchor:view.trailingAnchor
                                                     constant:-32],
                [stack.centerYAnchor constraintEqualToAnchor:view.centerYAnchor]
            ]];
            return view;
        }];

[[AutentikarManager shared] setCustomization:custom];

In the UIViewController tab, MyInstructionViewController must create a new instance and connect its controls to the received actions.

Keep the actions object in your custom view or controller for as long as its buttons need it. Do not present the capture module yourself: calling agree() lets Autentikar continue with the correct document or liveness step.

Android

Apply the customization

MainActivity.kt
import androidx.core.graphics.toColorInt

val custom = AutentikarCoreCustomization()
custom.backgroundColor = "#E84E1A".toColorInt()
custom.title.color = "#E84E1A".toColorInt()
custom.button.activeColor = "#E84E1A".toColorInt()

AutentikarManager.setCustomization(custom)

Configure the object before starting an Autentikar flow. Android colors are @ColorInt values, not resource IDs. Resolve a color resource with ContextCompat.getColor(...), or convert a hexadecimal color with toColorInt().

Property reference

General appearance

PropertyTypeDefaultPurpose
backgroundColorInt (@ColorInt)#FFFFFFBackground shared by the Core screens.
animationColorList<Int>[#082C4C, #082C4C]Colors used by the loading animation.
logoNameInt (@DrawableRes)R.drawable.autentikarDrawable resource displayed as the logo.
showLogoBooleantrueShows or hides the logo on general Core screens. The consent screen uses confirm.showLogo.
loadingViewView?nullReplaces the standard loading animation.

Typography

PropertyTypeDefaultPurpose
title.typefaceTypeface?nullTypeface for titles; Core uses its bundled semibold font when unset.
title.colorInt (@ColorInt)#3A3A3CTitle color.
text.typefaceTypeface?nullTypeface for body text; Core uses its bundled regular font when unset.
text.colorInt (@ColorInt)#3A3A3CBody text color.
caption.typefaceTypeface?nullTypeface for captions; Core uses its bundled light font when unset.
caption.colorInt (@ColorInt)Color.GRAYCaption color.
footerText.typefaceTypeface?nullTypeface for rotating footer messages.
footerText.colorInt (@ColorInt)#3A3A3CFooter message color.

Buttons

PropertyTypeDefaultPurpose
button.typefaceTypeface?nullButton title typeface; Core uses its bundled regular font when unset.
button.activeTextColorInt (@ColorInt)#FFFFFFText color for enabled primary buttons.
button.activeColorInt (@ColorInt)#082C4CBackground color for enabled primary buttons.
button.disabledTextColorInt (@ColorInt)#FFFFFFText color for disabled buttons.
button.disabledColorInt (@ColorInt)#5F6368Background color for disabled buttons.
button.cornerRadiusFloat20FButton corner radius in pixels.
button.outlineColorInt (@ColorInt)#082C4CText color used by outlined buttons.

Confirmation controls

PropertyTypeDefaultPurpose
confirm.checkBoxColorInt (@ColorInt)#082C4CTint applied to the consent checkbox.
confirm.linkTextColorInt (@ColorInt)#082C4CColor used by links in consent content.
confirm.showLogoBooleantrueShows or hides the logo only on the consent screen. Available starting with Core 1.0.20.
When migrating to 1.0.20, if you previously used showLogo = false to hide the logo throughout the flow, also set confirm.showLogo = false.

Standard instruction screens

The color properties style the standard XML instruction layouts. Starting with Core 1.0.20, those layouts no longer display a close button. The provider properties replace those layouts completely and are described in Custom instruction screens.

PropertyTypeDefaultPurpose
instructions.iconColorInt (@ColorInt)#082C4CTint applied to instruction item icons.
instructions.closeIconColorInt (@ColorInt)#082C4CRetained for compatibility; standard screens no longer display the close icon starting with 1.0.20.
instructions.photoIDScanViewProviderAutentikarInstructionViewProvider?nullReplaces the document instruction screen.
instructions.livenessCheckViewProviderAutentikarInstructionViewProvider?nullReplaces the liveness instruction screen.

Remote image on Android instruction screens

Starting with Core 1.0.20, the standard document and liveness instruction layouts can display the remote image supplied by the active step through header_image. This setting comes from the server; you do not need to assign it in AutentikarCoreCustomization.

Step response
{
  "header_image": {
    "alt": "header",
    "src": "https://example.com/instructions.png",
    "type": "image/png"
  }
}

When alt is header and src contains a valid image, the image replaces the standard title, description, and instruction list. The continue button remains visible. If the image is unavailable or cannot be loaded, the SDK automatically restores the standard content.

A configured photoIDScanViewProvider or livenessCheckViewProvider takes precedence and replaces the entire standard layout. Core does not insert header_image into a custom view; the application controls its content completely.

Complete visual example

MainActivity.kt
import android.graphics.Color
import android.graphics.Typeface
import androidx.core.graphics.toColorInt

val custom = AutentikarCoreCustomization().apply {
    backgroundColor = "#F8FAFC".toColorInt()
    animationColor = listOf(
        "#2563EB".toColorInt(),
        "#06B6D4".toColorInt()
    )
    logoName = R.drawable.company_logo
    showLogo = true

    title.typeface = Typeface.DEFAULT_BOLD
    title.color = "#0F172A".toColorInt()
    text.typeface = Typeface.DEFAULT
    text.color = "#334155".toColorInt()
    caption.typeface = Typeface.DEFAULT
    caption.color = "#64748B".toColorInt()
    footerText.typeface = Typeface.DEFAULT
    footerText.color = "#64748B".toColorInt()

    button.typeface = Typeface.DEFAULT_BOLD
    button.activeTextColor = Color.WHITE
    button.activeColor = "#2563EB".toColorInt()
    button.disabledTextColor = "#94A3B8".toColorInt()
    button.disabledColor = "#E2E8F0".toColorInt()
    button.cornerRadius = 24F
    button.outlineColor = "#2563EB".toColorInt()

    confirm.checkBoxColor = "#2563EB".toColorInt()
    confirm.linkTextColor = "#2563EB".toColorInt()
    confirm.showLogo = true

    instructions.iconColor = "#2563EB".toColorInt()
}

AutentikarManager.setCustomization(custom)

Custom loading view

Starting with Core 1.0.15, loadingView accepts an Android View.

MainActivity.kt
import android.content.res.ColorStateList
import android.graphics.Color
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    // Keep a strong reference while Autentikar may need the view.
    private val customLoadingView by lazy {
        ProgressBar(this).apply {
            isIndeterminate = true
            indeterminateTintList =
                ColorStateList.valueOf(Color.RED)
        }
    }

    private fun configureAutentikar() {
        val custom = AutentikarCoreCustomization()
        custom.loadingView = customLoadingView
        AutentikarManager.setCustomization(custom)
    }
}
Core stores loadingView through a weak reference. Keep a strong reference in your activity, fragment, or another owner for as long as the SDK may display it. The SDK removes the view from its previous parent before adding it to the loading container.

Custom Android instruction screens

Starting with Core 1.0.19, set an AutentikarInstructionViewProvider to replace either instruction screen with an Android View. Each provider is independent, so you can customize only one screen or both.

ScreenConfiguration property
Document capturecustom.instructions.photoIDScanViewProvider
Liveness verificationcustom.instructions.livenessCheckViewProvider

The provider's createView method receives these values:

ParameterPurpose
inflaterA LayoutInflater you can use to inflate an XML layout.
parentThe container where Core will present the view. Pass it as the root when inflating, with attachToRoot = false.
actionsActions that return control of the flow to the SDK.

The view must call one of these actions:

  • actions.agree() closes the instructions and continues to document capture or liveness verification.
  • actions.dismiss() closes the instructions without starting the capture step.

Reusable XML layout

You can use the same layout for both screens and change its content from each provider:

res/layout/view_custom_instructions.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="24dp">

    <TextView
        android:id="@+id/instructionTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/continueButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="@string/continue_action" />

    <Button
        android:id="@+id/closeButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/cancel_action" />
</LinearLayout>

Also add the strings used by the example:

res/values/strings.xml
<resources>
    <string name="photo_id_instructions_title">Prepare your identity document</string>
    <string name="liveness_instructions_title">Prepare for the liveness check</string>
    <string name="continue_action">Continue</string>
    <string name="cancel_action">Cancel</string>
</resources>

Configure both providers with Kotlin

This helper creates a new view for each presentation and connects its buttons to the Core-managed flow:

MainActivity.kt
import android.view.View
import android.widget.TextView
import androidx.annotation.StringRes
import com.autentikar.core_v2.common.managers.AutentikarManager
import com.autentikar.core_v2.common.views.AutentikarInstructionViewProvider
import com.autentikar.core_v2.utilities.customizations.AutentikarCoreCustomization

private fun instructionProvider(
    @StringRes titleRes: Int
) = AutentikarInstructionViewProvider { inflater, parent, actions ->
    inflater.inflate(
        R.layout.view_custom_instructions,
        parent,
        false
    ).apply {
        findViewById<TextView>(R.id.instructionTitle).setText(titleRes)

        findViewById<View>(R.id.continueButton)
            .setOnClickListener { actions.agree() }

        findViewById<View>(R.id.closeButton)
            .setOnClickListener { actions.dismiss() }
    }
}

val custom = AutentikarCoreCustomization()

custom.instructions.photoIDScanViewProvider =
    instructionProvider(R.string.photo_id_instructions_title)

custom.instructions.livenessCheckViewProvider =
    instructionProvider(R.string.liveness_instructions_title)

AutentikarManager.setCustomization(custom)

If you only need to customize one screen, assign only that provider. The other screen will keep using the standard design.

Build the view programmatically

XML is optional. The provider can also build and return a new view hierarchy:

MainActivity.kt
import android.view.Gravity
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import com.autentikar.core_v2.common.views.AutentikarInstructionViewProvider

custom.instructions.livenessCheckViewProvider =
    AutentikarInstructionViewProvider { _, parent, actions ->
        val padding = (24 * parent.resources.displayMetrics.density).toInt()

        LinearLayout(parent.context).apply {
            orientation = LinearLayout.VERTICAL
            gravity = Gravity.CENTER
            setPadding(padding, padding, padding, padding)

            addView(TextView(context).apply {
                text = context.getString(R.string.liveness_instructions_title)
            })

            addView(Button(context).apply {
                text = context.getString(R.string.continue_action)
                setOnClickListener { actions.agree() }
            })

            addView(Button(context).apply {
                text = context.getString(R.string.cancel_action)
                setOnClickListener { actions.dismiss() }
            })
        }
    }

Configure a provider from Java

The properties expose Java-compatible getters and setters. The same pattern works with setLivenessCheckViewProvider.

MainActivity.java
import android.view.View;

import com.autentikar.core_v2.common.managers.AutentikarManager;
import com.autentikar.core_v2.utilities.customizations.AutentikarCoreCustomization;

AutentikarCoreCustomization custom = new AutentikarCoreCustomization();

custom.getInstructions().setPhotoIDScanViewProvider(
    (inflater, parent, actions) -> {
        View view = inflater.inflate(
            R.layout.view_custom_instructions,
            parent,
            false
        );

        view.findViewById(R.id.continueButton)
            .setOnClickListener(button -> actions.agree());

        view.findViewById(R.id.closeButton)
            .setOnClickListener(button -> actions.dismiss());

        return view;
    }
);

AutentikarManager.setCustomization(custom);
The provider runs every time its instruction screen is presented, so it must return a new view. Do not add the view to parent yourself: Core inserts and removes it. If a provider is null, Core uses the corresponding standard screen. Do not start a capture activity from the custom view; use agree() or dismiss() so Autentikar remains in control of the active flow.

Localized content

Visual customization and text customization are independent. Use the platform localization files to replace user-facing copy without hard-coding strings in the customization object:

Copyright © 2026