iOS MFE
CardListView Microfrontend (iOS)
Part of the DigitalCardEngineSDK Library for iOS (SwiftUI)
This microfrontend displays a user’s cards. It is embedded into host apps — the host only needs to provide an auth token and the callbacks described below.
Callbacks
CardListView exposes three callbacks that let the host app respond to user actions:
onSelect(CardEntity)— fired when the user taps a card row.onAddCard()— fired when the user taps the Add Card button.onError(DCEUIError)— fired when an error occurs while loading cards.
All callbacks are invoked on the main thread to simplify UI navigation.
Callback Signatures
public struct CardListView: View {
public init(
onSelect: (CardEntity) -> Void,
onAddCard: () -> Void,
onError: ((DCEUIError) -> Void)? = nil
) { /* ... */ }
}onSelect
onSelectTriggered when a user selects a card row. Provides a CardEntity containing aggregated information suitable for navigation to a Card Details screen or for subsequent API calls (e.g., via DigitalCardEngineSDK).
onAddCard
onAddCardTriggered when the user taps the Add Card button. This is an optional button shown when actionButton is enabled in CardListViewProperties.
onError
onErrorTriggered when an error occurs while loading the card list. 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
onErrorcallback is optional. If not provided, errors will be silently caught but not reported to the host app.
CardEntity Type
public class CardEntity: Codable {
public let receivedCard: ReceivedCard
public let cardArt: String? // base64-encoded art (if available)
public let isReceiver: Bool? // indicates viewer role
public let transactionHistory: [Transaction]? // may be nil if not pre-fetched
public let events: [CardEvent]? // lifecycle or activity events
public let assetType: AssetType? // domain-specific categorization
public let metadata: CardMetadata? // extensible key-value info
}
public class ReceivedCard: Codable {
public let giftCardId: String
public let expiryDate: String
public let cardArtId: String
public let balance: Double?
public let name: String?
public let lastName: String?
public let last4: String?
public let message: CardMessage?
public let status: ActivationStatus?
public let cardLabel: String?
}Nullability: Many properties are optional to accommodate partial back-end payloads and progressive loading.
Customization
This package exposes lightweight types to configure CardListView behavior and visuals. Customization can be done in two ways:
- Global defaults via
StyleConfiguration— Applied to all views across the app - 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.
CardListViewProperties
CardListViewPropertiesHigh‑level toggles that control what UI elements appear and which visual style is used.
public struct CardListViewProperties {
public var title: Bool = true
public var actionButton: Bool = true
public var dividers: Bool = true
public var cardListLayout: CardListViewLayout = .largeLayout
}| Property | Type | Default | Description |
|---|---|---|---|
title | Bool | true | Show the list header/title. |
actionButton | Bool | true | Show the Add Card button. |
dividers | Bool | true | Render separators between card rows. |
cardListLayout | CardListViewLayout | .largeLayout | Pick between compact (.defaultLayout) and spacious (.largeLayout) list layouts. |
CardListViewLayout
CardListViewLayoutEnumeration that defines the overall density and typography scale of the list.
public enum CardListViewLayout {
case defaultLayout // Compact rows
case largeLayout // Square cards with a larger preview
}.defaultLayout— Best for dashboards or tight layouts..largeLayout— Ideal for a dedicated "Cards" screen (default option).
Usage
let props = sdk.getStyleConfiguration().cardListViewProperties
props.title = false
props.actionButton = true
props.cardListLayout = .defaultLayoutCardListViewStyle
CardListViewStyleLow‑level visual tokens that fine‑tune paddings, gaps, and corner radius for the list container and rows.
public struct CardListViewStyle {
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 each card row. |
internalVerticalPadding | CGFloat | 12 | Top/bottom padding inside each card row. |
externalPadding | CGFloat | 16 | Padding around the whole list/container. |
internalGap | CGFloat | 16 | Spacing between stacked elements (e.g., title ↔ list, rows ↔ footer). |
radius | CGFloat | 12 | Corner radius for card row backgrounds or list container. |
Usage
let style = sdk.getStyleConfiguration().cardListViewStyle
style.internalHorizontalPadding = 10
style.radius = 0
style.internalGap = 10Runtime 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 getCardListView(
properties: CardListViewProperties? = nil,
style: CardListViewStyle? = nil,
onSelect: @escaping (CardEntity) -> Void,
onAddCard: @escaping () -> Void,
onError: ((DCEUIError) -> Void)? = nil
) throws -> AnyViewParameters
properties— Optional. Overrides globalCardListViewPropertiesfor this view instance.style— Optional. Overrides globalCardListViewStylefor this view instance.
If not provided, the view falls back to the global configuration from sdk.getStyleConfiguration().
Example: Per-View Customization
struct CardsScreen: View {
let sdk: DigitalCardEngine
var body: some View {
// Custom properties for this specific view
let customProps = CardListViewProperties(
title: false,
actionButton: true,
dividers: false,
cardListLayout: .defaultLayout
)
let customStyle = CardListViewStyle(
internalHorizontalPadding: 8,
internalVerticalPadding: 8,
externalPadding: 12,
internalGap: 8,
radius: 8
)
return try? sdk.getCardListView(
properties: customProps,
style: customStyle,
onSelect: { card in print("Selected: \(card)") },
onAddCard: { print("Add card") }
)
}
}Note: Runtime parameters take precedence over global
StyleConfiguration. This allows you to have app-wide defaults while customizing specific screens.
Usage Example
Simple usage:
import SwiftUI
import DigitalCardEngineSDK
struct CardsScreen: View {
let sdk: DigitalCardEngine
init(authToken: String) {
self.sdk = DigitalCardEngine(token: authToken)
}
var body: some View {
sdk.getCardListView(
onSelect: { card in print("Open card: \(card)") },
onAddCard: { print("Add new card") }
)
}
}Customization:
import SwiftUI
import DigitalCardEngineSDK
struct CardsScreen: View {
let sdk: DigitalCardEngine
init(authToken: String) {
sdk = DigitalCardEngine(token: authToken)
let props = sdk.getStyleConfiguration().cardListViewProperties
props.title = false
props.actionButton = true
props.cardListLayout = .defaultLayout
let style = sdk.getStyleConfiguration().cardListViewStyle
style.internalHorizontalPadding = 10
style.radius = 0
style.internalGap = 10
}
var body: some View {
sdk.getCardListView(
onSelect: { card in print("Open card: \(card)") },
onAddCard: { print("Add new card") }
)
}
}Data Source & API Integration
This document describes how the CardListView microfrontend loads its data and maps API responses to UI. The view performs two GET requests:
- Gift cards —
GET /receiver/v2/gift-cards - Card art —
GET /receiver/v1/card-arts
Both calls are authenticated via the authToken supplied to DigitalCardEngineSDK.
1) GET /receiver/v2/gift-cards
Example response (abridged)
[
{
"value": {
"giftCardId": "0f2b6046-3784-400d-9a86-a18f9fe09a20",
"cardLabel": "GiftCard",
"expiryDate": "2025-12-31",
"cardArtId": "0b323e0a-a61c-439b-ae69-8ca465961a3e",
"balance": 500,
"name": "Desarae",
"lastName": "Sanderson",
"message": {
"receiver": "Dear Friend!",
"text": "Happy Birthday!"
},
"status": "ACTIVE",
"last4": "3452"
}
}
]Field mapping → CardListView
| Source field | Used for | Notes |
|---|---|---|
value.cardLabel | Title on card row | Shown as the main label. |
value.balance | Balance | Rendered as numeric balance |
value.last4 | Masked PAN (…1234) | Displayed as •••• last4 on the card row. |
value.cardArtId | Card art lookup | Used to retrieve base64 artwork from the card-arts endpoint. |
Other fields (e.g., expiryDate, status) are fetched but not displayed in the cell.
2) GET /receiver/v1/card-arts
Purpose
Returns a list of available card artworks encoded in base64. CardListView finds the matching item by cardArtId obtained from the gift-cards call.
Example response (abridged)
[
{
"cardArt": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHg...",
"cardArtId": "0b323e0a-a61c-439b-ae69-8ca465961a3e"
}
]Mapping
- Match on
cardArtId. - Decode
cardArt(base64) into an image and show as the preview in the card row.
Updated 3 months ago
