iOS MFE

TransactionHistoryView Microfrontend (iOS)

Part of the DigitalCardEngineSDK Library for iOS (SwiftUI)

This microfrontend displays a user’s transaction history for a specific card. It is embedded into host apps — the host only needs to provide an auth token, a CardEntity, and callbacks that respond to transaction‑related actions.

Callbacks

TransactionHistoryView exposes three callbacks that let the host app respond to user actions:

  • onTransactionClick(Transaction) — fired when the user taps a transaction row.
  • onSeeMoreClick() — fired when the user presses the See more button.
  • onError(DCEUIError) — fired when an error occurs while loading transaction history.

All callbacks are invoked on the main thread to simplify UI navigation.

Callback Signatures

public struct TransactionHistoryView: View {
    public init(
        card: CardEntity,
        fullscreen: Bool = false,
        onTransactionClick: (Transaction) -> Void,
        onSeeMoreClick: () -> Void,
        onError: ((DCEUIError) -> Void)? = nil
    ) { /* ... */ }
}

onTransactionClick

Triggered when a user taps a transaction item. Provides a full Transaction model suitable for presenting a detail screen or executing follow-up actions.

onSeeMoreClick

Triggered when the user presses the See More button (only shown in non-fullscreen mode when there are more transactions than the limit).

onError

Triggered when an error occurs while loading transaction history. Provides a DCEUIError that wraps the underlying CardProviderException. This optional callback allows the host app to handle errors appropriately (e.g., showing an alert, logging out the user, or displaying custom error UI).

Error Type

public enum DCEUIError: Error {
    case cardProviderxception(CardProviderException)
}

Note: The onError callback is optional. If not provided, errors will be silently caught but not reported to the host app.

Transaction Type

public class Transaction: Codable {
    public let transactionType: TransactionType
    public let merchantCategoryCode: String?
    public let transactionDate: String
    public let transactionAmount: Double
    public let transactionId: String?
    public let transactionDescription: String
}

public enum TransactionType: String, Codable {
    case load = "LOAD"
    case deduction = "DEDUCTION"
    case authorisation = "AUTHORISATION"
}

Customization

This package exposes lightweight types to configure TransactionHistoryView behavior and visuals. Customization can be done in two ways:

  1. Global defaults via StyleConfiguration — Applied to all views across the app
  2. Runtime overrides via method parameters — Passed directly when creating a view, overriding global defaults

When both are provided, runtime parameters take precedence over global configuration.

TransactionHistoryViewProperties

High‑level toggles that control what UI elements appear and which visual style is used.

public struct TransactionHistoryViewProperties {
    public var leadingElement: TransactionHistoryLeadingElement = .none
    public var groupByMonth: Bool = false
    public var timestampFormat: String = "DD/MM/YYYY HH:mm"
    public var filter: Bool = false
    public var numberOfTransactions: Int = 5
}
PropertyTypeDefaultDescription
leadingElementTransactionHistoryLeadingElementnonePick between none (.none), icon (.icon), and brand logo (.brandLogo) leading visuals.
groupByMonthBoolfalseGroup rows by month; when true headers such as “July 2025” are rendered by the view model.
timestampFormatStringDD/MM/YYYY HH:mmFormat string passed directly to DateFormatter for each timestamp (no internal sanitization).
filterBoolfalseShow the calendar‑style filter button that exposes built‑in date presets.
numberOfTransactionsInt5Maximum number of rows shown in compact mode. Fullscreen ignores this limit.

TransactionHistoryLeadingElement

public enum TransactionHistoryLeadingElement {
    case none
    case icon
    case brandLogo
}

Usage

let props = sdk.getStyleConfiguration().transactionHistoryViewProperties
props.leadingElement = .none
props.groupByMonth = true
props.timestampFormat = "HH:mm"
props.filter = true
props.numberOfTransactions = 50

TransactionHistoryViewStyle

Low‑level visual tokens that fine‑tune paddings, gaps, and corner radius for the list container and rows.

public struct TransactionHistoryViewStyle {
    public var internalHorizontalPadding: CGFloat = 16
    public var internalVerticalPadding: CGFloat = 12
    public var externalPadding: CGFloat = 16
    public var internalGap: CGFloat = 16
    public var radius: CGFloat = 12
}
PropertyTypeDefaultApplies to
internalHorizontalPaddingCGFloat16Left/right padding inside transaction history row.
internalVerticalPaddingCGFloat12Top/bottom padding inside of transaction history row..
externalPaddingCGFloat16Padding around the transaction history row..
internalGapCGFloat16Spacing between stacked elements (e.g., title ↔ list, rows ↔ footer).
radiusCGFloat12Corner radius for card image.

Usage

let style = sdk.getStyleConfiguration().transactionHistoryViewStyle
style.internalHorizontalPadding = 10
style.radius = 0
style.internalGap = 10

Runtime Customization

In addition to global configuration, you can pass properties and style directly to individual views. This allows per-instance customization without affecting other views.

Method Signature

func getTransactionHistoryView(
    card: CardEntity,
    fullscreen: Bool,
    properties: TransactionHistoryViewProperties? = nil,
    style: TransactionHistoryViewStyle? = nil,
    onTransactionClick: @escaping (Transaction) -> Void,
    onSeeMoreClick: @escaping () -> Void,
    onError: ((DCEUIError) -> Void)? = nil
) throws -> AnyView

Parameters

  • properties — Optional. Overrides global TransactionHistoryViewProperties for this view instance.
  • style — Optional. Overrides global TransactionHistoryViewStyle for this view instance.

If not provided, the view falls back to the global configuration from sdk.getStyleConfiguration().

Example: Per-View Customization

struct TransactionHistoryScreen: View {
    let sdk: DigitalCardEngine
    let card: CardEntity

    var body: some View {
        // Custom properties for this specific view
        let customProps = TransactionHistoryViewProperties(
            leadingElement: .brandLogo,
            groupByMonth: true,
            timestampFormat: "MMM dd, yyyy",
            filter: true,
            numberOfTransactions: 10
        )
        
        let customStyle = TransactionHistoryViewStyle(
            internalHorizontalPadding: 12,
            internalVerticalPadding: 10,
            externalPadding: 8,
            internalGap: 12,
            radius: 8
        )
        
        return try? sdk.getTransactionHistoryView(
            card: card,
            fullscreen: true,
            properties: customProps,
            style: customStyle,
            onTransactionClick: { transaction in print("Clicked: \(transaction)") },
            onSeeMoreClick: { print("See more") }
        )
    }
}

Note: Runtime parameters take precedence over global StyleConfiguration. This allows you to have app-wide defaults while customizing specific screens.


Filtering presets

When filter is enabled the header renders an outlined button. Tapping the control reveals the TransactionHistoryFilter menu:

Fullscreen mode

Pass fullscreen: true when requesting the view to present a dedicated transaction screen. In this mode:

  • The title moves into the navigation bar
  • Content is wrapped in a ScrollView so the list can extend freely.
  • The “All transactions” footer button is hidden.
  • numberOfTransactions is ignored, so the full filtered history is shown.

Compact mode (fullscreen: false) keeps the inline title, enforces numberOfTransactions, and shows the footer button so hosts can push a detail screen.

Usage Example

import SwiftUI
import DigitalCardEngineSDK

struct HistoryCard: View {
    let sdk: DigitalCardEngine
    let card: CardEntity

    var body: some View {
        sdk.getTransactionHistoryView(
            card: card,
            fullscreen: false,
            onTransactionClick: { print("Transaction: \($0)") },
            onSeeMoreClick: { print("Navigate to full history") }
        )
    }
}