Theming, branding, and localization 

Use the MobileIDTheme APIs and the SDK localization override mechanism to make SDK-provided journeys consistent with your app's visual identity and language.

What This Covers 

  • configuring the SDK color palette with ThemeColorSet
  • understanding light and dark appearance behavior
  • applying semantic text styles with ThemeConfiguration
  • reusing MobileIDTheme controls in app-owned screens
  • adding brand imagery in custom integration screens
  • translating or replacing SDK copy from the host app
  • validating accessibility, formatting, and fallback behavior

API Surface 

API
Purpose
MobileIDConfiguration.colorsSupplies the palette applied when MobileID is created.
ThemeColorSetDefines primary, secondary, grayscale, status, and background colors.
MIDColorCreates SDK colors, including from six-digit RGB or eight-digit ARGB hex strings.
ThemeConfigurationDescribes a color set and semantic UIKit text styles.
ThemeConfiguration.colors(for:)Resolves the palette for the current or specified appearance.
ThemeColorSet.tint(for:tintColor:)Chooses a contrasting foreground for a supplied background.
ThemeManager.apply(_:)Applies a theme through the SDK's UIKit appearance configuration.
ThemeManager.updateNavigationBarAppearance(_:)Refreshes navigation bar colors and typography.
ThemeManager.updateTabBarAppearance(_:)Refreshes tab bar colors.
MIDLabel, MIDButton, MIDTextField, and related typesReusable themed controls for app-owned or custom SDK screens.
LocalizationFile and String.localized(_:)Resolve localized strings from an app or framework bundle.

Configure The Brand Palette 

Create one palette and pass it to MobileIDConfiguration. The SDK applies it during MobileIDFactory.create(...), before SDK-provided screens are presented.

Swift
1import MobileIDCore
2import MobileIDTheme
3
4extension ThemeColorSet {
5 static let appBrand = ThemeColorSet(
6 primary: MIDColor(hexString: "#1F3A8A"),
7 secondary: MIDColor(hexString: "#2563EB"),
8 grayscaleDark: MIDColor(hexString: "#0F172A"),
9 grayscaleMediumDark: MIDColor(hexString: "#334155"),
10 grayscaleMedium: MIDColor(hexString: "#64748B"),
11 grayscaleLight: MIDColor(hexString: "#CBD5E1"),
12 accentRed: MIDColor(hexString: "#DC2626"),
13 accentOrange: MIDColor(hexString: "#EA580C"),
14 accentGreen: MIDColor(hexString: "#16A34A"),
15 background: MIDColor(hexString: "#FFFFFF")
16 )
17}
18
19let configuration = MobileIDConfiguration(
20 appInfo: AppInfoConfiguration(projectId: "<PROJECT_ID>"),
21 colors: .appBrand,
22 enrollmentPlugins: [
23 // Plugins enabled for your tenant.
24 ],
25 captureSDKConfiguration: nil,
26 walletConfigurationTimeToLiveInMinutes: WalletDownloadConfiguration.twentyFourHoursInMinutes
27)

MIDColor(hexString:) accepts RRGGBB and AARRGGBB, with or without #. Use eight digits only when an alpha channel is intentional.

Color Token Responsibilities 

Token
Typical SDK usage
primaryPrimary brand emphasis, switches, selections, and some plain actions.
secondaryMain buttons, links, navigation actions, and selected controls.
grayscaleDarkStrong text and the dark-appearance background source.
grayscaleMediumDarkBody and supporting text.
grayscaleMediumMuted or disabled content.
grayscaleLightBorders, fields, keypads, and subtle surfaces.
accentRedError and destructive states.
accentOrangeWarning states.
accentGreenSuccess states.
backgroundPrimary light-appearance surface.

The same token may be used by several SDK controls. Treat each value as a design-system role rather than as a screen-specific color.

Light And Dark Appearance 

The SDK derives its dark palette from the supplied light palette. It does not accept a second, independent dark ThemeColorSet through MobileIDConfiguration.

In dark appearance, the SDK:

  • makes primary, secondary, and accentOrange more vibrant,
  • uses white for grayscaleDark,
  • swaps the light and medium-dark grayscale roles,
  • uses the configured grayscaleDark as the background,
  • preserves the red, green, and medium grayscale tokens.

Test both appearances with real content. In particular, verify contrast for the secondary color against background, and for text against both background and grayscaleDark.

Semantic Typography 

ThemeConfiguration maps SDK text roles to UIKit semantic styles. ThemeManager resolves those styles with UIFont.preferredFont(forTextStyle:), so Dynamic Type remains active.

Swift
1import MobileIDTheme
2import UIKit
3
4struct AppTheme: ThemeConfiguration {
5 let colors: ThemeColorSet
6
7 let largeTitleStyle: UIFont.TextStyle = .largeTitle
8 let titleStyle: UIFont.TextStyle = .title1
9 let title3Style: UIFont.TextStyle = .title3
10 let headlineStyle: UIFont.TextStyle = .headline
11 let bodyStyle: UIFont.TextStyle = .body
12 let calloutStyle: UIFont.TextStyle = .callout
13 let footnoteStyle: UIFont.TextStyle = .footnote
14}
15
16@MainActor
17func applyAppTheme() {
18 ThemeManager.apply(AppTheme(colors: .appBrand))
19}

Call ThemeManager.apply(_:) on the main thread before creating the screens that should receive the appearance. Normal SDK initialization already applies the color set from MobileIDConfiguration; call it yourself only when you need a separate ThemeConfiguration, such as one shared with a custom screen or FaceConfiguration. When using a separate theme with MobileID, apply it after MobileIDFactory.create(...) finishes so SDK initialization does not replace it.

The theme protocol selects semantic text styles, not a custom font family. If your brand requires a specific typeface, use it in app-owned screens and verify any direct UIKit appearance customization against SDK updates and Dynamic Type.

Reuse SDK-Themed Controls 

App-owned screens can use MobileIDTheme components to match SDK-provided journeys:

Swift
1import MobileIDTheme
2
3let titleLabel = MIDTitleLabel()
4titleLabel.text = NSLocalizedString("enrollment.welcome.title", comment: "")
5
6let continueButton = MIDPrimaryButton(frame: .zero)
7continueButton.setTitle(
8 NSLocalizedString("common.continue", comment: ""),
9 for: .normal
10)

Common reusable types include:

  • MIDLargeTitleLabel, MIDTitleLabel, MIDHeadlineLabel, and MIDLabel
  • MIDPrimaryButton, MIDSecondaryButton, and MIDPlainButton
  • MIDTextField, MIDTextView, MIDSwitch, and MIDSegmentedControl
  • MIDView, MIDErrorView, and MIDPopupView

These controls receive values from ThemeManager through UIKit appearance. Apply the theme before instantiating them.

Brand Images And Custom Screens 

ThemeColorSet does not contain a logo, illustration, or icon slot. SDK-owned images are not replaced by adding assets with matching names to the host app.

Place brand imagery in app-owned screens instead. Enrollment provides EnrollmentInteractionDelegate.enrollmentView(for:) for supported custom interaction contexts, and authentication delegates let the app control how SDK view controllers are presented. Use the host app's asset catalog for logos and illustrations in those screens.

RequestData.clientMetadata.logoURL is request metadata supplied for a client application; it is not the SDK theme logo.

Localize SDK Copy 

The SDK first looks in the host application's main bundle for a prefixed override. If no override exists, it reads the unprefixed key from the framework that owns the screen.

diagram

1. Add App Localizations 

Create a Localizable.strings file for every supported app language and include it in the main application target. Override an SDK string by prefixing its key with com.idemia.mid..

For example, en.lproj/Localizable.strings:

Text
1"com.idemia.mid.loc_continue" = "Next";
2"com.idemia.mid.loc_enter_your_email" = "Enter your work email";
3"com.idemia.mid.loc_photograph_results_retake" = "Take another photo";

And pl.lproj/Localizable.strings:

Text
1"com.idemia.mid.loc_continue" = "Dalej";
2"com.idemia.mid.loc_enter_your_email" = "Wpisz służbowy adres e-mail";
3"com.idemia.mid.loc_photograph_results_retake" = "Zrób kolejne zdjęcie";

The SDK follows standard iOS bundle language selection; there is no SDK-specific language setter. The app's supported localizations and the user's system/app language determine which resource is loaded.

2. Find The Keys To Override 

Use the English Localizable.strings files shipped in the installed SDK modules as the source list. Include only keys from modules linked by your app:

  • MobileIDCore
  • MobileIDTheme
  • MobileIDCommonUtils
  • MobileIDEnrollmentPluginEmailBinding
  • MobileIDEnrollmentPluginPhoneBinding
  • MobileIDEnrollmentPluginFaceMatching
  • MobileIDEnrollmentPluginDocumentAuthentication

Copy the unprefixed loc_* key, add com.idemia.mid. in the app's strings file, and provide the localized value. Review the key list again when upgrading the SDK because journeys and copy can evolve.

3. Preserve Format Arguments 

Some values contain format placeholders such as %@ or %d. Preserve the placeholder type and count in every translation. For example:

Text
1"com.idemia.mid.loc_invalid_field" = "Invalid %@";

Do not translate localization keys, and do not add or remove format arguments. Validate every formatted string in a debug build because a mismatched placeholder can produce broken copy or a runtime failure.

4. Understand Shared Overrides 

The override namespace is global to the host app. If more than one SDK module requests the same key, such as loc_continue, one prefixed app value overrides that key everywhere. Use shared wording for shared keys. Use custom app-owned screens when different journeys require different wording for the same SDK key.

5. Localize App-Owned Copy 

Use standard Apple localization APIs for your own screens. MobileIDCommonUtils also exposes LocalizationFile and String.localized(_:) when an integration layer needs the same bundle-based lookup helper:

Swift
1import MobileIDCommonUtils
2
3let title = "enrollment_welcome_title".localized(.main)

For an unprefixed app-owned key, the helper falls back to the selected table in the supplied bundle.

Validation Checklist 

  • Initialize MobileID with the production palette before presenting SDK UI.
  • Review every journey in light and dark appearances.
  • Check normal, disabled, selected, warning, error, and success states.
  • Test Dynamic Type through the largest supported accessibility sizes.
  • Check VoiceOver labels after changing visible copy.
  • Exercise every supported app language, including fallback to English.
  • Verify text expansion, line wrapping, button height, and navigation titles.
  • Test all %@ and %d substitutions with representative values.
  • Confirm shared keys such as loc_continue read correctly in every module.

Troubleshooting 

Symptom
Check
The default SDK text still appearsConfirm the key starts with com.idemia.mid., the strings file belongs to the main app target, and the active language has that entry.
A translation changes several screensThe modules share the same underlying loc_* key; a host override is global.
A color change does not affect an existing controlApply the theme before creating the control, then recreate or refresh the screen.
Dark appearance has poor contrastReview the automatically derived dark mapping, especially grayscaleDark, secondary, and background.
A formatted value is missing or malformedMatch every source placeholder and its type in the translated value.
A logo asset is ignored by an SDK screenThere is no global SDK logo override; put the asset in an app-owned/custom screen.
  • Getting Started
  • Enrollment Orchestration
  • PIN And Liveness Verification