# 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 ```swift 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 ```swift 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 ```swift 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. ```swift 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 } ``` | Property | Type | Default | Description | | ---------------------- | ---------------------------------- | -----------------: | ----------------------------------------------------------------------------------------------- | | `leadingElement` | `TransactionHistoryLeadingElement` | `none` | Pick between none (`.none`), icon (`.icon`), and brand logo (`.brandLogo`) leading visuals. | | `groupByMonth` | `Bool` | `false` | Group rows by month; when `true` headers such as “July 2025” are rendered by the view model. | | `timestampFormat` | `String` | `DD/MM/YYYY HH:mm` | Format string passed directly to `DateFormatter` for each timestamp (no internal sanitization). | | `filter` | `Bool` | `false` | Show the calendar‑style filter button that exposes built‑in date presets. | | `numberOfTransactions` | `Int` | `5` | Maximum number of rows shown in compact mode. Fullscreen ignores this limit. | #### `TransactionHistoryLeadingElement` ```swift public enum TransactionHistoryLeadingElement { case none case icon case brandLogo } ``` #### Usage ```swift 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. ```swift 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 } ``` | Property | Type | Default | Applies to | | --------------------------- | --------- | ------: | --------------------------------------------------------------------- | | `internalHorizontalPadding` | `CGFloat` | `16` | Left/right padding inside transaction history row. | | `internalVerticalPadding` | `CGFloat` | `12` | Top/bottom padding inside of transaction history row\.. | | `externalPadding` | `CGFloat` | `16` | Padding around the transaction history row\.. | | `internalGap` | `CGFloat` | `16` | Spacing between stacked elements (e.g., title ↔ list, rows ↔ footer). | | `radius` | `CGFloat` | `12` | Corner radius for card image. | *** #### Usage ```swift 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 ```swift 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 ```swift 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 ```swift 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") } ) } } ```