Skip to main content

iOS Activation — Theming Guide

This guide covers everything a developer needs to customize the visual appearance of BlinkEngage SDK screens. The SDK uses a protocol-based theming system: you implement a single Theme protocol and hand it to the SDK. Every color, font, and icon flows through three key enums — AppearanceColorKey, AppearanceFontNameKey, and AppearanceIconKey.


Table of Contents

  1. Architecture
  2. Setup (Host App)
  3. Theme Protocol Reference
  4. AppearanceColorKey Reference
  5. AppearanceIconKey Reference
  6. AppearanceFontNameKey Reference
  7. AppearanceTextKey Reference
  8. AppearanceGlobalColorKey Reference
  9. Global Font Matrix
  10. Tips and Pitfalls

1. Architecture

BlinkEngage/
└── Appearance/
├── AppearanceKey.swift # AppearanceColorKey, AppearanceIconKey, AppearanceFontNameKey
├── Theme.swift # Theme protocol
├── Appearance.swift # Appearance class
TypeRole
AppearanceColorKey (enum)Identifies every customizable color — backgrounds, label text, icon tints.
AppearanceFontNameKey (enum)Identifies every customizable font. Return a font name string; the SDK applies the correct point size.
AppearanceIconKey (enum)Identifies every customizable image — reward icons, button icons, placeholders.
AppearanceTextKey (enum)Identifies every customizable string — button labels and other SDK-controlled copy.
Theme (protocol)Your class conforms to this. The SDK calls color(forKey:), fontName(forKey:), image(forKey:), and text(forKey:) to resolve styling.
Appearance (class)Holds an optional Theme. Assigned to BlinkEngageSDK.shared.appearance.

All UI customization flows exclusively through the Theme protocol and these key enums. There are no per-property setters on Appearance.


2. Setup (Host App)

Swift Example

import BlinkEngage
import UIKit

class MyTheme: Theme {

var isRewardIconEnabled: Bool { true }

var isMerchantIconEnabled: Bool { true }

var globalFontMatrix: NSDictionary? {
[
NSNumber(value: UIFont.Weight.regular.rawValue): "Outfit-Regular",
NSNumber(value: UIFont.Weight.medium.rawValue): "Outfit-Medium",
NSNumber(value: UIFont.Weight.bold.rawValue): "Outfit-Bold",
NSNumber(value: UIFont.Weight.black.rawValue): "Outfit-Black"
]
}

func color(forKey key: AppearanceColorKey) -> UIColor? {
switch key {
case .postScanHeaderBackground:
return UIColor(named: "BrandPrimary")
case .postScanFooterButtonTitle:
return .white
default:
return nil // SDK default
}
}

func fontName(forKey key: AppearanceFontNameKey) -> String? {
switch key {
case .postScanSuccessTitleLabel:
return "Outfit-ExtraBold"
default:
return nil // falls back to globalFontMatrix, then system font
}
}

func image(forKey key: AppearanceIconKey) -> UIImage? {
switch key {
case .offerRewardIcon:
return UIImage(named: "my_coin_icon")
default:
return nil // SDK default
}
}

func text(forKey key: AppearanceTextKey) -> String? {
return nil // return a String to override SDK defaults
}
}

Objective-C Example

// MyTheme.h
@import BlinkEngage;

@interface MyTheme : NSObject <Theme>
@end

// MyTheme.m
@implementation MyTheme

- (BOOL)isRewardIconEnabled { return YES; }
- (BOOL)isMerchantIconEnabled { return YES; }
- (NSDictionary *)globalFontMatrix { return nil; }

- (UIColor *)colorForKey:(AppearanceColorKey)key {
switch (key) {
case AppearanceColorKeyPostScanHeaderBackground:
return [UIColor colorNamed:@"BrandPrimary"];
default:
return nil;
}
}

- (NSString *)fontNameForKey:(AppearanceFontNameKey)key {
return nil; // Use SDK defaults
}

- (UIImage *)imageForKey:(AppearanceIconKey)key {
return nil; // Use SDK defaults
}

- (NSString *)textForKey:(AppearanceTextKey)key {
return nil; // Use SDK defaults
}

@end

Assigning the Theme

Set the theme before presenting any SDK view controller:

// In AppDelegate or wherever you configure BlinkEngage
let theme = MyTheme()
BlinkEngageSDK.shared.appearance = Appearance(theme: theme)

To use SDK defaults with no customization, use the parameterless initializer (this is the default):

BlinkEngageSDK.shared.appearance = Appearance()

Changing Theme at Runtime

You can reassign appearance at any time. The new theme takes effect the next time the SDK creates or reloads a view:

BlinkEngageSDK.shared.appearance = Appearance(theme: MyDarkTheme())

3. Theme Protocol Reference

@objc public protocol Theme: AnyObject {
@objc var isMerchantIconEnabled: Bool { get }
@objc var globalFontMatrix: NSDictionary? { get }
@objc optional func color(forGlobalKey key: AppearanceGlobalColorKey) -> UIColor?
@objc func color(forKey key: AppearanceColorKey) -> UIColor?
@objc func fontName(forKey key: AppearanceFontNameKey) -> String?
@objc func image(forKey key: AppearanceIconKey) -> UIImage?
@objc func text(forKey key: AppearanceTextKey) -> String?
}
MemberTypePurpose
isMerchantIconEnabledBooltrue loads store logos from URL in the Stores screen. false always shows the default storefront icon.
globalFontMatrixNSDictionary?Maps UIFont.Weight raw values to font name strings. Used as a fallback when fontName(forKey:) returns nil. See Global Font Matrix.
color(forGlobalKey:) (optional)UIColor?Return a color for a semantic palette role (e.g. .primary, .textAccent). The SDK calls this after color(forKey:) returns nil for keys that map to a global role. Lets you apply a shared palette without matching every individual key. See AppearanceGlobalColorKey Reference.
color(forKey:)UIColor?Return a custom color for a specific UI element, or nil to fall through to color(forGlobalKey:) and then the SDK default.
fontName(forKey:)String?Return a PostScript font name (e.g. "Outfit-Bold"), or nil. The SDK creates the font at its expected point size.
image(forKey:)UIImage?Return a custom UIImage, or nil for the SDK default.
text(forKey:)String?Return a custom string to override SDK-controlled copy, or nil to keep the SDK default. See AppearanceTextKey Reference.

4. AppearanceColorKey Reference

Return a UIColor from color(forKey:) for any key below. Return nil to use the SDK default.

Offer Wall

KeyDescriptionDefault
offerWallBackgroundBackground of the offer list area.#FFFFFF
offerWallHeaderBackgroundHeader bar at the top of the offer wall.Removed in v1.7.0 — use UINavigationController theming instead.
offerWallHeaderTitleLabelMain title text in the offer wall header.Removed in v1.7.0
offerWallHeaderSubtitleLabelSubtitle or secondary line in the offer wall header.Removed in v1.7.0
offerWallHeaderBackButtonIconBack / close arrow in the offer wall header.Removed in v1.7.0
offerWallSectionHeaderLabelSection title (e.g. "Offers for you") above a group of offers.#142641
offerWallSectionHeaderShowMoreIconArrow or chevron in the "Show more" section header button.#0062F2
offerWallSectionHeaderShowMoreBackgroundBackground of the "Show more" section header button.#0062F2 @ 8% opacity
offerWallFloatingButtonBackgroundBackground of the floating action button.#0062F2
offerWallFloatingButtonLabelLabel text and icon tint on the floating button.#FFFFFF
offerWallMoreMerchantsIcon"More stores" icon in the stores row.#0062F2

Offer Cards

KeyDescriptionDefault
offerBackgroundBackground of each offer card.#FCFBFA
offerBrandLabelBrand or offer title on each offer card.#142641
offerDescriptionLabelDescription or requirements text on each offer card.#374151
offerEligibleMerchantsLabel"Eligible at" or merchants list text on each offer card.#0062F2
offerRewardPointsLabelReward amount or points text on each offer card.#0062F2
offerTagBackgroundBackground of the promo badge on offer cards; also "BUY X" badge on offer details.#D6E6FD
offerTagLabelPromo badge label (e.g. "BUY 2") on offer cards; also "BUY X" badge on offer details.#0062F2

Offer Clip / Clipped

KeyDescriptionDefault
offerClipButtonBackgroundBackground of the clip button on an offer card.#0062F2
offerClipButtonIconIcon for the clip button on an offer card.#FFFFFF
offerClippedButtonBackgroundBackground of the clipped-state button on an offer card.#29CC6A
offerClippedButtonIconIcon for the clipped-state button on an offer card.#FFFFFF
offerClippedToastMessageBackgroundBackground of the "Offer clipped!" toast message.#F3F4F6
offerClippedToastMessageLabelLabel text in the "Offer clipped!" toast message.#142641

Offer Details

KeyDescriptionDefault
offerDetailsTitleLabelPrimary title on the offer details screen.#142641
offerDetailsEarnRewardLabel"Earn …" reward line below the primary title on the offer details screen.#0062F2
offerDetailsShortDescriptionShort description under the offer title (e.g. coupon description and payout).#142641
offerDetailsExpirationLabelExpiration / "X Days Left" on the offer details screen.#6B7280
offerDetailsClipLabel"Clip this offer" label on the offer details screen.#142641
offerDetailsClipRequiredBackground"Clip Required" badge background.#F3F4F6
offerDetailsClipRequiredLabel"Clip Required" badge label.#6B7280
offerDetailsSectionHeaderTitleLabelSection header titles (e.g. "Eligible Products", "Description", "Fine Print").#142641
offerDetailsSectionHeaderToggleLabelSection header toggle text ("See all" / "See less").#0062F2
offerDetailsSectionBodyLabelSection body text (e.g. long description).#142641
offerDetailsFinePrintLabelFine print / full terms body.#9CA3AF
offerDetailsBuyOptionLabelLabel text in the buying options list.#142641
offerDetailsBuyOptionBackgroundBackground of each row in the buying options list.#FCFBFA
offerDetailsTagChipLabelTag chip label text on the offer details screen.#727D8D
offerDetailsTagChipBorderTag chip outline / border on the offer details screen.#E5E7EB
offerDetailsSectionNumberedListBadgeLabelDigit inside each numbered step badge in a section's ordered list.#FFFFFF
offerDetailsSectionNumberedListBadgeBackgroundBackground circle of each numbered step badge in a section's ordered list.#0062F2

Ad Loading (Loading Screen)

KeyDescriptionDefault
adLoadingDefaultTitleLabelTitle label (e.g. "Hang tight!").#FFFFFF
adLoadingDefaultDescriptionLabelDescription label (e.g. "Exclusive rewards are coming your way!").#FFFFFF
adLoadingLoadingBarBackgroundBackground of the progress bar track.Black @ 8% opacity
adLoadingLoadingBarLabelLabel text and icon tint on the progress bar.#FFFFFF
adLoadingLoadingBarProgressProgress fill color.#0062F2

Error Modal

KeyDescriptionDefault
errorModalBackgroundBackground of the error modal card container.#FCFBFA
errorModalIconBackgroundBackground of the warning icon (e.g. "!") on the error modal.#FCA355
errorModalTitleLabelTitle label (e.g. "Oops!", "Invalid Receipt").#142641
errorModalDescriptionLabelDescription / message label.#142641
errorModalBackButtonLabel"Back to offers" / dismiss button label.#0062F2

Post Scan (Receipt Summary)

KeyDescriptionDefault
postScanHeaderBackgroundBackground of the receipt summary header bar.#0062F2
postScanTotalPointsBackgroundBackground of the total points pill (coin + amount) in the header.Black @ 16% opacity
postScanTotalPointsLabelTotal points amount label in the header.#FFFFFF
postScanReceiptButtonIconIcon tint for the receipt / missed earnings button in the header. When nil, the image uses original colors (no template tint).nil (original colors)
postScanReceiptButtonBackgroundBackground of the receipt / missed earnings button in the header.Black @ 16% opacity
postScanFooterBackgroundBackground of the receipt summary footer.#FCFBFA
postScanFooterButtonTitleTitle (text color) of the continue button in the footer.#0062F2
postScanSectionHeaderTitleLabelSection header title label (e.g. "Your Rewards").#9CA3AF
postScanMerchantNameLabelMerchant name label in the trip summary.#142641
postScanTripInfoLabelTrip info label (date and total) in the trip summary.#142641
postScanSuccessTitleLabelTitle label (e.g. "Nice Scan!") in the success state of the boost area.#142641
postScanSuccessDescriptionLabelDescription label in the success state (e.g. points earned).#142641
postScanNoBoostsLabelLabel in the "no boosts" empty state.#142641
postScanBoostTitleLabelTitle label on post-scan boost cards.#142641
postScanBoostDescriptionLabelDescription label on post-scan boost cards.#142641
postScanBoostSkipButtonLabelLabel (text color) on the "Skip" button below boost cards.#0062F2
postScanBoostClaimButtonLabelLabel (text color) on the "Claim" button below boost cards.#FFFFFF
postScanBoostClaimButtonIconIcon tint on the "Claim" button. When nil, the icon uses original colors.nil
postScanBoostClaimButtonBackgroundBackground of the "Claim" button below boost cards.#0062F2
postScanPurchasePointsLabelPoints label (e.g. "+100") on purchase rows.#0062F2
postScanPurchaseBackgroundBackground of a standard product row (no offer, not UGC).#FFFFFF
postScanQualifiedPurchaseBackgroundBackground of qualified product rows.#F9FAFB
postScanPurchaseInfoIconInfo icon tint on product rows with an active earn task.#D1D4D9
postScanInlineProductTaskBackgroundRow background for products showing an inline earn task ("Snap & Earn" or "Watch & Earn").#EBF2FE
postScanInlineProductTaskScanAndEarnBackground"Snap & Earn" pill background and camera icon tint on UGC inline task rows.#0062F2
postScanInlineProductTaskWatchAndEarnBackground"Watch & Earn" pill background and play icon tint on rewarded-video inline task rows.#0062F2
postScanInlineProductTaskScanAndEarnLabel"Snap & Earn" pill text color on UGC inline task rows.#FFFFFF
postScanInlineProductTaskWatchAndEarnLabel"Watch & Earn" pill text color on rewarded-video inline task rows.#FFFFFF
postScanInlineProductTaskPointsLabel"+100" reward amount label on inline earn-task rows.#0062F2

Purchase Row (Shared)

KeyDescriptionDefault
purchaseRowLabelColorProduct name / description label color on purchase rows (receipt summary and Missed Earnings).#142641
purchaseRowMetadataLabelColorMetadata line label color on purchase rows (receipt summary and Missed Earnings).#142641

Stores

KeyDescriptionDefault
storesHeaderBackgroundBackground of the stores screen header bar.#FFFFFF
storesHeaderTitleLabelTitle label in the stores screen header (e.g. "Stores").#142641
storesListBackgroundBackground of the stores list area (view, cells, section headers).#FFFFFF
storesListSectionHeaderLabelSection header label in the stores list.#142641
storesListItemBackgroundBackground of each store item (cell) in the list.#FFFFFF
storesListItemDefaultIconDefault thumbnail icon tint for each store item.#D1D5DB
storesListItemTitleLabelTitle label for each store item.#142641
storesListItemSubtitleLabelSubtitle label for each store item.#374151

Missed Earnings

KeyDescriptionDefault
missedEarningsNavigationTitleLabelTitle label in the navigation header (e.g. "Missing rewards?").#142641
missedEarningsNavigationDescriptionLabelDescription label in the navigation header.#142641
missedEarningsNavigationEditButtonIconIcon tint for the Edit button in the navigation header.#0062F2
missedEarningsNavigationEditButtonBackgroundBackground of the Edit button in the navigation header.#F2F7FF
missedEarningsNavigationSaveButtonIconIcon tint of the Save button in the navigation header.#FFFFFF
missedEarningsNavigationSaveButtonBackgroundBackground of the Save button in the navigation header.#0062F2
missedEarningsFieldEditIconIcon tint of the edit (pen) button on each field row.#0062F2
missedEarningsAddNewFieldLabelLabel and icon color for the "add new field" control.#0062F2
missedEarningsModifiedFieldBackgroundBackground of modified field rows.#ECFDF5
missedEarningsListSectionTitleLabelSection header title in the list (e.g. "Merchant", "Date", "Products").#262626
missedEarningsTripItemLabelLabel text in merchant and date rows only.#142641
missedEarningsEditModalBackgroundBackground of the edit field modal.#FCFBFA
missedEarningsEditModalTitleLabelTitle label at the top of the edit field modal.#142641
missedEarningsEditModalSubtitleLabelSubtitle label at the top of the edit field modal.#142641
missedEarningsEditModalInputLabelLabel for text field titles in the edit field modal.#262626
missedEarningsEditModalInputPlaceholderLabelPlaceholder text color in the edit field modal text fields.#9CA3AF
missedEarningsEditModalInputValueLabelText field value / caption labels in the edit field modal.#142641
missedEarningsEditModalCancelButtonLabelCancel button label (text color) in the edit field modal.#0062F2
missedEarningsEditModalSaveButtonLabelSave button label (text color) in the edit field modal.#FFFFFF
missedEarningsEditModalSaveButtonBackgroundSave button background in the edit field modal.#0062F2
missedEarningsEditModalDatePickerTint color of the date picker (e.g. selected date highlight).#0062F2
missedEarningsAlertTitleLabelTitle label in the alert modal (e.g. "No updates made", "Submit Receipt").#142641
missedEarningsAlertMessageLabelMessage/body label in the alert modal.#142641

UGC (Product Capture)

KeyDescriptionDefault
ugcBarcodeDetectedBorderBorder color when a barcode is detected in the camera.#10B990
ugcBarcodeDetectedIconIcon tint when a barcode is detected.#FFFFFF
ugcNavigationButtonIconIcon tint for navigation buttons (close, torch) in the header.#FFFFFF
ugcNavigationButtonBackgroundBackground of navigation buttons (close, torch) in the header.#434343
ugcProductInfoBackgroundBackground of the product info badges (product name and barcode/UPC).#262626
ugcProductInfoLabelLabel text color in the product info badges.#FFFFFF
ugcToastMessageWarningIconWarning icon tint in the toast message.#F43F5E
ugcRetakeButtonLabel"Retake" button label (text color) in the footer.#FFFFFF
ugcRetakeButtonBackground"Retake" button background in the footer.#434343
ugcSubmitButtonLabel"Submit" button label (text color) in the footer.#FFFFFF
ugcSubmitButtonBackground"Submit" button background in the footer.#0062F2

5. AppearanceIconKey Reference

Return a UIImage from image(forKey:) for any key below. Return nil to use the SDK default.

KeyDescriptionDefault Behavior
offerRewardIconReward / currency icon shown with reward amounts (offer cards, receipt summary).When nil: controlled by isRewardIconEnabledtrue shows default coin, false hides it.
offerWallFloatingButtonIconFloating action button icon (e.g. scan receipt). Tint uses offerWallFloatingButtonLabel color.Default camera icon (SF Symbol).
missedEarningsNavigationEditButtonIconEdit button icon in the Missed Earnings header. Tint uses missedEarningsNavigationEditButtonIcon color.Default pen icon.
missedEarningsFieldEditIconEdit (pen) button icon on each field row in Missed Earnings. Tint uses missedEarningsFieldEditIcon color.Default pen icon.
postScanReceiptButtonIconReceipt / missed earnings button icon in the receipt summary header. Tint uses postScanReceiptButtonIcon color when set; nil color shows original image colors.Default receipt icon.
postScanBoostDefaultIconPlaceholder image for boost cards when no image URL is provided.Default boost icon.
postScanSuccessIconIcon in the success state of the boost area (e.g. "Nice Scan!").Default coin icon.
ugcBarcodeDetectedIconIcon when a barcode is detected in the product capture camera. Tint uses ugcBarcodeDetectedIcon color.No default image (camera uses Lottie animation).
ugcToastMessageWarningIconWarning icon in the product capture toast message. Tint uses ugcToastMessageWarningIcon color.info.circle.fill SF Symbol.

6. AppearanceFontNameKey Reference

Return a PostScript font name (e.g. "Outfit-Bold") from fontName(forKey:) for any key below. Return nil to fall back to the globalFontMatrix (by weight), then the system font. The SDK applies the correct point size for each key automatically.

Offer Wall

KeyDefault SizeDefault Weight
offerWallHeaderTitleLabel24Removed in v1.7.0
offerWallHeaderSubtitleLabel14Removed in v1.7.0
offerWallSectionHeaderLabel18700
offerWallFloatingButtonLabel16700

Offer Cards

KeyDefault SizeDefault Weight
offerRewardPointsLabel16900
offerTagLabel12700
offerBrandLabel16700
offerDescriptionLabel12400
offerEligibleMerchantsLabel12500

Offer Clipped

KeyDefault SizeDefault Weight
offerClippedToastMessageLabel14500

Offer Details

KeyDefault SizeDefault Weight
offerDetailsTitleLabel20700
offerDetailsEarnRewardLabel16700
offerDetailsShortDescription20700
offerDetailsExpirationLabel14400 (Italic)
offerDetailsClipLabel14700
offerDetailsClipRequiredLabel14700
offerDetailsSectionHeaderTitleLabel16700
offerDetailsSectionHeaderToggleLabel12600
offerDetailsSectionBodyLabel14400
offerDetailsFinePrintLabel12400
offerDetailsBuyOptionLabel14500
offerDetailsTagChipLabel12500

Ad Loading (Loading Screen)

KeyDefault SizeDefault Weight
adLoadingDefaultTitleLabel20700
adLoadingDefaultDescriptionLabel16400
adLoadingLoadingBarLabel14700

Error Modal

KeyDefault SizeDefault Weight
errorModalTitleLabel18700
errorModalDescriptionLabel14400
errorModalBackButtonLabel14700

Post Scan (Receipt Summary)

KeyDefault SizeDefault Weight
postScanTotalPointsLabel24900
postScanFooterButtonTitle14700
postScanSectionHeaderTitleLabel14400
postScanMerchantNameLabel24700
postScanTripInfoLabel14500
postScanSuccessTitleLabel18700
postScanSuccessDescriptionLabel14500
postScanNoBoostsLabel16400
postScanBoostTitleLabel14700
postScanBoostDescriptionLabel13400
postScanBoostSkipButtonLabel14700
postScanBoostClaimButtonLabel14700
postScanPurchasePointsLabel18900
postScanInlineProductTaskPointsLabel14700
postScanInlineProductTaskScanAndEarnLabel12600
postScanInlineProductTaskWatchAndEarnLabel12600

Purchase Row (Shared)

KeyDefault SizeDefault Weight
purchaseRowLabelFont14700
purchaseRowMetadataLabelFont14400

Stores

KeyDefault SizeDefault Weight
storesHeaderTitleLabel20700
storesListSectionHeaderLabel18700
storesListItemTitleLabel14700
storesListItemSubtitleLabel14400

Missed Earnings

KeyDefault SizeDefault Weight
missedEarningsNavigationTitleLabel20700
missedEarningsNavigationDescriptionLabel14400
missedEarningsListSectionTitleLabel14400
missedEarningsTripItemLabel14500
missedEarningsEditModalTitleLabel18700
missedEarningsEditModalSubtitleLabel16400
missedEarningsEditModalInputLabel14400
missedEarningsEditModalInputPlaceholderLabel14400
missedEarningsEditModalInputValueLabel14500
missedEarningsEditModalCancelButtonLabel14700
missedEarningsEditModalSaveButtonLabel14700
missedEarningsAlertTitleLabel18700
missedEarningsAlertMessageLabel16400

UGC (Product Capture)

KeyDefault SizeDefault Weight
ugcProductInfoLabel14400
ugcRetakeButtonLabel16400
ugcSubmitButtonLabel16700

7. AppearanceTextKey Reference

Return a String from text(forKey:) for any key below. Return nil to use the SDK default.

KeyDefaultDescription
offerWallFloatingButtonExpandedLabel"Scan Receipt"Label on the floating action button when it is in its expanded (full-width) state.
offerWallFloatingButtonCollapsedLabel"Scan"Label on the floating action button when it is collapsed to a compact size.

8. AppearanceGlobalColorKey Reference

AppearanceGlobalColorKey defines a small semantic palette. Implement the optional color(forGlobalKey:) method on your Theme to set shared brand colors that the SDK automatically distributes across related UI elements — without having to match every individual AppearanceColorKey.

Color resolution order for any given key:

  1. color(forKey:) — specific per-element override
  2. color(forGlobalKey:) — semantic palette role (if the key maps to one)
  3. Built-in SDK default
func color(forGlobalKey key: AppearanceGlobalColorKey) -> UIColor? {
switch key {
case .primary: return UIColor(named: "BrandPrimary")
case .textAccent: return UIColor(named: "BrandAccent")
case .success: return UIColor(named: "BrandSuccess")
default: return nil
}
}
KeySemantic roleExample elements
primaryMain brand color for actions and prominent interactive elements.Floating button background, clip button, progress bar fill.
secondarySupporting accent for secondary action surfaces.Section headers, secondary buttons.
successCompleted, clipped, or valid states.Clipped button background, "Offer clipped!" toast.
warningCautionary or non-blocking alert states.Error modal warning icon.
errorDestructive, invalid, or blocking states.Error modal icon background.
borderBorders, dividers, and neutral icon tints.Tag chip border, default store icon.
textPrimaryTitles and high-emphasis copy.Offer brand labels, section titles, modal headlines.
textSecondaryCaptions, metadata, and muted copy.Offer description, expiration labels.
textAccentLinks, rewards, and branded inline emphasis.Reward amount labels, eligible merchants line, earn-reward line.
backgroundMain page or screen background.Offer wall background, stores list background.
surfaceBackgroundCards, modals, rows, and elevated surfaces.Offer card background, error modal background.
accentBackgroundTinted pills, badges, and highlights.Offer tag pill, "show more" button.
backgroundInverseForeground content on dark, saturated, or inverse surfaces.Floating button label, clipped button icon.

Return nil for any key to keep the SDK default for that role.


9. Global Font Matrix

The globalFontMatrix property lets you define a single set of brand fonts mapped by weight. When fontName(forKey:) returns nil for a given key, the SDK looks up the expected weight in this matrix before falling back to the system font.

var globalFontMatrix: NSDictionary? {
[
NSNumber(value: UIFont.Weight.regular.rawValue): "Outfit-Regular",
NSNumber(value: UIFont.Weight.medium.rawValue): "Outfit-Medium",
NSNumber(value: UIFont.Weight.semibold.rawValue): "Outfit-SemiBold",
NSNumber(value: UIFont.Weight.bold.rawValue): "Outfit-Bold",
NSNumber(value: UIFont.Weight.black.rawValue): "Outfit-Black"
]
}

Font resolution order:

  1. fontName(forKey:) — specific override for this key
  2. globalFontMatrix — weight-based lookup
  3. System font at the expected weight and size

10. Tips and Pitfalls

Set the theme before presenting SDK views. The Appearance instance is read when views are created. If you assign it after a view controller is already on screen, the old styling persists until the view is recreated.

Return nil to keep SDK defaults. You do not need to handle every case in your color(forKey:) / fontName(forKey:) / image(forKey:) implementations. A default: return nil is sufficient for any keys you don't want to customize.

Font sizing is automatic. When you return a font name from fontName(forKey:), the SDK creates the font at its own expected point size for that key. You control the typeface; the SDK controls the size. Do not try to encode size into the font name.

color(forGlobalKey:) is additive, not a replacement. Per-key overrides from color(forKey:) always take priority. Use the global palette to cover the common case, then add per-key overrides only where you need to diverge.

isMerchantIconEnabled controls URL loading, not the icon slot. When false, the stores list always shows the default storefront icon rather than downloading merchant logos.

Icon tinting pairs. Several icon keys share a tint color key with the same name (e.g. AppearanceIconKey.missedEarningsFieldEditIcon is tinted by AppearanceColorKey.missedEarningsFieldEditIcon). If you provide a custom image for an icon key, check whether you also want to override the corresponding color key, since the SDK renders many icons with template mode.

Objective-C compatibility. All enums are @objc backed by Int. In Objective-C, use the prefixed names (e.g. AppearanceColorKeyOfferWallHeaderBackground).