From 0501c8824484115288768d9aa8f76cd871903031 Mon Sep 17 00:00:00 2001 From: Peter-John Welcome Date: Thu, 8 Oct 2026 17:42:06 +0200 Subject: [PATCH 1/2] Add Scan to Pay app deeplinks and audience-gate the QR / bank transfer UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scan to Pay customers on a phone can now hand off to their banking app instead of scanning the QR code on their own screen. The QR number the API already returns is used to build a Masterpass deeplink per app. - Add ScanToPayApp + ScanToPayAppDirectory covering the 13 supported apps, with three deeplink shapes (FNB/RMB's https handoff, Nedbank's nedbank:// scheme, and the generic masterpass.app.scheme:// form) and a URIComponentEncoder matching JS encodeURIComponent's allowed set - Add ScanToPayAppPickerView, a grid of app icons pushed from the QR screen behind a new "See Scan to Pay apps" button; failing to open an app surfaces an inline message rather than failing silently - Rename QRVariant.showsQRReferenceRow to supportsAppDeeplinks and turn it on for Scan to Pay, so QRDetails keeps the qrCode the deeplinks need; SnapScan is unchanged - Gate the new elements by audience: customer-facing gets the QR number, the apps button and "Open any Scan to Pay app…" copy, merchant-facing keeps the QR code and scan instruction - Gate the bank transfer copy buttons the same way — they're useless on a merchant-facing display where the customer can't tap them - Add ScanToPayAppDirectoryTests (deeplink shapes, encoding, initials) and UIElementVisibilityTests, plus previews for both audiences --- .../BankTransferAccountDetailsView.swift | 38 ++++- .../Charge/QR/Models/QRDetails.swift | 2 +- .../Charge/QR/Models/QRVariant.swift | 4 +- .../Charge/QR/Models/ScanToPayApp.swift | 73 ++++++++++ .../Charge/QR/Views/QRDisplayView.swift | 79 +++++++++-- .../QR/Views/ScanToPayAppPickerView.swift | 130 ++++++++++++++++++ .../Design/UIElementVisibility.swift | 16 +++ .../ScanToPayApps/Contents.json | 6 + .../scanToPayAppAbsa.imageset/Contents.json | 20 +++ .../scanToPayAppAvo.imageset/Contents.json | 20 +++ .../Contents.json | 20 +++ .../scanToPayAppFNB.imageset/Contents.json | 20 +++ .../Contents.json | 20 +++ .../Contents.json | 20 +++ .../Contents.json | 20 +++ .../scanToPayAppRMB.imageset/Contents.json | 20 +++ .../Contents.json | 20 +++ .../scanToPayAppSpot.imageset/Contents.json | 20 +++ .../Contents.json | 20 +++ .../Contents.json | 20 +++ .../Contents.json | 20 +++ .../QR/ScanToPayAppDirectoryTests.swift | 112 +++++++++++++++ .../QRRepositoryImplementationTests.swift | 2 +- .../UI/Utils/UIElementVisibilityTests.swift | 71 ++++++++++ 24 files changed, 778 insertions(+), 15 deletions(-) create mode 100644 Sources/PaystackUI/Charge/QR/Models/ScanToPayApp.swift create mode 100644 Sources/PaystackUI/Charge/QR/Views/ScanToPayAppPickerView.swift create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppCapitec.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankMoney.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankScanToPay.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppRMB.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppScanToPay.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppSpot.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppStandardBank.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppVodapay.imageset/Contents.json create mode 100644 Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift diff --git a/Sources/PaystackUI/Charge/BankTransfer/Views/BankTransferAccountDetailsView.swift b/Sources/PaystackUI/Charge/BankTransfer/Views/BankTransferAccountDetailsView.swift index ab0d408..6290264 100644 --- a/Sources/PaystackUI/Charge/BankTransfer/Views/BankTransferAccountDetailsView.swift +++ b/Sources/PaystackUI/Charge/BankTransfer/Views/BankTransferAccountDetailsView.swift @@ -9,6 +9,9 @@ struct BankTransferAccountDetailsView: View { let onIveSentTheMoney: () async -> Void let onChangePaymentMethod: () -> Void + @Environment(\.displayAudience) + private var displayAudience + @State private var provisionedAt: Date = Date() @State private var now: Date = Date() @@ -52,6 +55,10 @@ struct BankTransferAccountDetailsView: View { } } + private var copyTrailing: AccountDetailRow.Trailing { + displayAudience.shows(.bankTransferCopyButtons) ? .copy : .none + } + private var accountCard: some View { VStack(spacing: 0) { AccountDetailRow(label: "BANK NAME", @@ -59,17 +66,17 @@ struct BankTransferAccountDetailsView: View { divider AccountDetailRow(label: "ACCOUNT NUMBER", value: details.accountNumber, - trailing: .copy) + trailing: copyTrailing) divider AccountDetailRow(label: "AMOUNT", value: amount.description, - trailing: .copy) + trailing: copyTrailing) if provider == .pesalink { divider AccountDetailRow(label: "NARRATION / REASON", value: details.transactionReference, - trailing: .copy) + trailing: copyTrailing) } } .overlay( @@ -117,3 +124,28 @@ struct BankTransferAccountDetailsView: View { return min(1.0, elapsed / total) } } + +@available(iOS 14.0, *) +struct BankTransferAccountDetailsView_Previews: PreviewProvider { + static var previews: some View { + Group { + BankTransferAccountDetailsView( + details: .example, + amount: AmountCurrency(amount: 1000000, currency: "NGN"), + provider: .standard, + onIveSentTheMoney: {}, + onChangePaymentMethod: {}) + .environment(\.displayAudience, .customerFacing) + .previewDisplayName("Customer-facing — copy buttons") + + BankTransferAccountDetailsView( + details: .example, + amount: AmountCurrency(amount: 1000000, currency: "NGN"), + provider: .standard, + onIveSentTheMoney: {}, + onChangePaymentMethod: {}) + .environment(\.displayAudience, .merchantFacing) + .previewDisplayName("Merchant-facing — no copy buttons") + } + } +} diff --git a/Sources/PaystackUI/Charge/QR/Models/QRDetails.swift b/Sources/PaystackUI/Charge/QR/Models/QRDetails.swift index bba78db..be999b4 100644 --- a/Sources/PaystackUI/Charge/QR/Models/QRDetails.swift +++ b/Sources/PaystackUI/Charge/QR/Models/QRDetails.swift @@ -14,7 +14,7 @@ extension QRDetails { guard let url = URL(string: response.data.url) else { return nil } return QRDetails( qrImageURL: url, - qrReference: variant.showsQRReferenceRow ? response.data.qrCode : nil, + qrReference: variant.supportsAppDeeplinks ? response.data.qrCode : nil, pusherChannel: response.data.channel) } } diff --git a/Sources/PaystackUI/Charge/QR/Models/QRVariant.swift b/Sources/PaystackUI/Charge/QR/Models/QRVariant.swift index 1fee92f..81c5f0b 100644 --- a/Sources/PaystackUI/Charge/QR/Models/QRVariant.swift +++ b/Sources/PaystackUI/Charge/QR/Models/QRVariant.swift @@ -31,10 +31,10 @@ enum QRVariant: String, Equatable { } } - var showsQRReferenceRow: Bool { + var supportsAppDeeplinks: Bool { switch self { case .scanToPay: - return false + return true case .snapScan: return false } diff --git a/Sources/PaystackUI/Charge/QR/Models/ScanToPayApp.swift b/Sources/PaystackUI/Charge/QR/Models/ScanToPayApp.swift new file mode 100644 index 0000000..9fb4a7e --- /dev/null +++ b/Sources/PaystackUI/Charge/QR/Models/ScanToPayApp.swift @@ -0,0 +1,73 @@ +import Foundation + +struct ScanToPayApp: Equatable, Identifiable { + + enum DeeplinkStyle: Equatable { + case fnb + case nedbank + case generic + } + + let name: String + let iconAsset: String + let deeplinkStyle: DeeplinkStyle + + var id: String { iconAsset } + + var initials: String { + let words = name.split(separator: " ") + if words.count >= 2 { + return words.prefix(2).compactMap { $0.first }.map(String.init).joined().uppercased() + } + return String(name.prefix(2)).uppercased() + } + + func deeplink(for qrCode: String) -> URL? { + guard let encoded = URIComponentEncoder.encode(qrCode) else { return nil } + switch deeplinkStyle { + case .fnb: + return URL(string: "https://www.online.fnb.co.za/banking/mobileservices" + + "?codetype=masterpassdeeplink&urlencodedqr=\(encoded)") + case .nedbank: + return URL(string: "nedbank://masterpass.oltio.co.za/\(encoded)") + case .generic: + return URL(string: "masterpass.app.scheme://masterpass.oltio.co.za/\(encoded)") + } + } +} + +enum ScanToPayAppDirectory { + + static let apps: [ScanToPayApp] = [ + ScanToPayApp(name: "Absa Scan to Pay", iconAsset: "scanToPayAppAbsa", deeplinkStyle: .generic), + ScanToPayApp(name: "Avo", iconAsset: "scanToPayAppAvo", deeplinkStyle: .generic), + ScanToPayApp(name: "Capitec", iconAsset: "scanToPayAppCapitec", deeplinkStyle: .generic), + ScanToPayApp(name: "FNB Pay", iconAsset: "scanToPayAppFNB", deeplinkStyle: .fnb), + ScanToPayApp(name: "Instapay", iconAsset: "scanToPayAppInstapay", deeplinkStyle: .generic), + ScanToPayApp(name: "Nedbank Money", iconAsset: "scanToPayAppNedbankMoney", deeplinkStyle: .nedbank), + ScanToPayApp(name: "Nedbank Scan to Pay", iconAsset: "scanToPayAppNedbankScanToPay", deeplinkStyle: .generic), + ScanToPayApp(name: "RMB", iconAsset: "scanToPayAppRMB", deeplinkStyle: .fnb), + ScanToPayApp(name: "Spot", iconAsset: "scanToPayAppSpot", deeplinkStyle: .generic), + ScanToPayApp(name: "Standard Bank Scan to Pay", iconAsset: "scanToPayAppStandardBank", deeplinkStyle: .generic), + ScanToPayApp(name: "Telkom Pay", iconAsset: "scanToPayAppTelkomPay", deeplinkStyle: .generic), + ScanToPayApp(name: "Scan to Pay", iconAsset: "scanToPayAppScanToPay", deeplinkStyle: .generic), + ScanToPayApp(name: "Vodapay", iconAsset: "scanToPayAppVodapay", deeplinkStyle: .generic) + ] + + static func openFailedMessage(appName: String) -> String { + "Couldn't open \(appName). Make sure it's installed." + } +} + +enum URIComponentEncoder { + + private static let allowed: CharacterSet = { + var set = CharacterSet() + set.insert(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()") + return set + }() + + static func encode(_ value: String) -> String? { + value.addingPercentEncoding(withAllowedCharacters: allowed) + } +} diff --git a/Sources/PaystackUI/Charge/QR/Views/QRDisplayView.swift b/Sources/PaystackUI/Charge/QR/Views/QRDisplayView.swift index 2c57832..ff6de92 100644 --- a/Sources/PaystackUI/Charge/QR/Views/QRDisplayView.swift +++ b/Sources/PaystackUI/Charge/QR/Views/QRDisplayView.swift @@ -13,27 +13,45 @@ struct QRDisplayView: View { let onICompletedPayment: () -> Void let onChangePaymentMethod: () -> Void + @Environment(\.displayAudience) + private var displayAudience + @State private var showCopiedToast = false + @State private var showsAppPicker = false var body: some View { + Group { + if showsAppPicker, let qrCode = deeplinkQRCode { + ScanToPayAppPickerView(qrCode: qrCode, + onBack: { showsAppPicker = false }) + } else { + paymentDetails + } + } + .copiedToast(isPresented: $showCopiedToast) + } + + private var paymentDetails: some View { ScrollView { VStack(spacing: .triplePadding) { headerLogo - Text(variant.instructionCopy) + Text(instructionText) .font(.body16M) .foregroundColor(.contentPrimary) .multilineTextAlignment(.center) - qrCodeBlock + if showsQRCode { + qrCodeBlock + } Text(amount.description) .font(.body16M) .foregroundColor(.contentPrimary) - if variant.showsQRReferenceRow, let reference = details.qrReference { - qrReferenceRow(reference: reference) + if showsQRNumber, let qrCode = deeplinkQRCode { + qrReferenceRow(reference: qrCode) } if let banner = inlineBanner { @@ -44,7 +62,33 @@ struct QRDisplayView: View { } .padding(.doublePadding) } - .copiedToast(isPresented: $showCopiedToast) + } + + private var deeplinkQRCode: String? { + guard variant.supportsAppDeeplinks, + let qrCode = details.qrReference, + !qrCode.isEmpty else { return nil } + return qrCode + } + + private var deeplinksAvailable: Bool { + deeplinkQRCode != nil + } + + private var instructionText: String { + deeplinksAvailable ? displayAudience.text(.scanToPayInstruction) : variant.instructionCopy + } + + private var showsQRCode: Bool { + !deeplinksAvailable || displayAudience.shows(.scanToPayQRCode) + } + + private var showsQRNumber: Bool { + deeplinksAvailable && displayAudience.shows(.scanToPayQRNumber) + } + + private var showsSeeAppsButton: Bool { + deeplinksAvailable && displayAudience.shows(.scanToPaySeeAppsButton) } private var headerLogo: some View { @@ -91,8 +135,16 @@ struct QRDisplayView: View { private var actionButtons: some View { VStack(spacing: .singlePadding) { - Button("I've completed payment", action: onICompletedPayment) - .buttonStyle(PrimaryButtonStyle(showLoading: false)) + if showsSeeAppsButton { + Button("See Scan to Pay apps", action: { showsAppPicker = true }) + .buttonStyle(PrimaryButtonStyle(showLoading: false)) + + Button("I've completed payment", action: onICompletedPayment) + .buttonStyle(SecondaryButtonStyle()) + } else { + Button("I've completed payment", action: onICompletedPayment) + .buttonStyle(PrimaryButtonStyle(showLoading: false)) + } Button("Change payment method", action: onChangePaymentMethod) .foregroundColor(.contentSecondary) @@ -122,7 +174,18 @@ struct QRDisplayView_Previews: PreviewProvider { inlineBanner: nil, onICompletedPayment: {}, onChangePaymentMethod: {}) - .previewDisplayName("Scan to Pay — awaiting scan") + .environment(\.displayAudience, .customerFacing) + .previewDisplayName("Scan to Pay — customer-facing (number + apps)") + + QRDisplayView( + variant: .scanToPay, + details: .scanToPayExample, + amount: AmountCurrency(amount: 4500, currency: "ZAR"), + inlineBanner: nil, + onICompletedPayment: {}, + onChangePaymentMethod: {}) + .environment(\.displayAudience, .merchantFacing) + .previewDisplayName("Scan to Pay — merchant-facing (QR only)") QRDisplayView( variant: .snapScan, diff --git a/Sources/PaystackUI/Charge/QR/Views/ScanToPayAppPickerView.swift b/Sources/PaystackUI/Charge/QR/Views/ScanToPayAppPickerView.swift new file mode 100644 index 0000000..8d32495 --- /dev/null +++ b/Sources/PaystackUI/Charge/QR/Views/ScanToPayAppPickerView.swift @@ -0,0 +1,130 @@ +import SwiftUI +#if canImport(UIKit) +import UIKit +#endif + +@available(iOS 14.0, *) +struct ScanToPayAppPickerView: View { + + let qrCode: String + let onBack: () -> Void + + @State private var openFailedMessage: String? + + private let columns = Array(repeating: GridItem(.flexible(), spacing: .doublePadding), count: 3) + + var body: some View { + ScrollView { + VStack(spacing: .triplePadding) { + + Text("Choose your Scan to Pay app") + .font(.body16M) + .foregroundColor(.contentPrimary) + .multilineTextAlignment(.center) + + if let message = openFailedMessage { + Text(message) + .font(.body14M) + .foregroundColor(.contentWarning) + .multilineTextAlignment(.center) + .padding(.singlePadding) + .frame(maxWidth: .infinity) + .background(Color.warningSurface) + .cornerRadius(.cornerRadius) + } + + LazyVGrid(columns: columns, spacing: .triplePadding) { + ForEach(ScanToPayAppDirectory.apps) { app in + Button(action: { open(app) }) { + ScanToPayAppCell(app: app) + } + .buttonStyle(PlainButtonStyle()) + } + } + + Button("Back", action: onBack) + .foregroundColor(.contentSecondary) + .font(.body14M) + .padding(.top, .singlePadding) + } + .padding(.doublePadding) + } + } + + private func open(_ app: ScanToPayApp) { + openFailedMessage = nil + let failedMessage = ScanToPayAppDirectory.openFailedMessage(appName: app.name) + guard let url = app.deeplink(for: qrCode) else { + openFailedMessage = failedMessage + return + } + #if canImport(UIKit) + UIApplication.shared.open(url, options: [:]) { success in + guard !success else { return } + DispatchQueue.main.async { + openFailedMessage = failedMessage + } + } + #endif + } +} + +@available(iOS 14.0, *) +private struct ScanToPayAppCell: View { + + let app: ScanToPayApp + + private let iconSize: CGFloat = 64 + + var body: some View { + VStack(spacing: .singlePadding) { + icon + .frame(width: iconSize, height: iconSize) + .cornerRadius(.cornerRadius) + + Text(app.name) + .font(.body14R) + .foregroundColor(.contentPrimary) + .multilineTextAlignment(.center) + .lineLimit(2) + .fixedSize(horizontal: false, vertical: true) + } + .frame(maxWidth: .infinity, alignment: .top) + } + + @ViewBuilder + private var icon: some View { + if let image = bundledIcon { + image + .resizable() + .scaledToFit() + } else { + ZStack { + RoundedRectangle(cornerRadius: .cornerRadius) + .fill(Color.surfaceTertiary) + Text(app.initials) + .font(.body16M) + .foregroundColor(.contentSecondary) + } + } + } + + private var bundledIcon: Image? { + #if canImport(UIKit) + guard let image = UIImage(named: app.iconAsset, in: .current, compatibleWith: nil) else { + return nil + } + return Image(uiImage: image) + #else + return nil + #endif + } +} + +@available(iOS 14.0, *) +struct ScanToPayAppPickerView_Previews: PreviewProvider { + static var previews: some View { + ScanToPayAppPickerView(qrCode: "1490884538", onBack: {}) + .previewDisplayName("Scan to Pay app picker — placeholder icons") + } +} diff --git a/Sources/PaystackUI/Design/UIElementVisibility.swift b/Sources/PaystackUI/Design/UIElementVisibility.swift index be191a6..8f89148 100644 --- a/Sources/PaystackUI/Design/UIElementVisibility.swift +++ b/Sources/PaystackUI/Design/UIElementVisibility.swift @@ -4,10 +4,15 @@ import PaystackCore enum AudienceGatedElement: CaseIterable { case zapQRCode case zapOpenAppButton + case bankTransferCopyButtons + case scanToPayQRCode + case scanToPayQRNumber + case scanToPaySeeAppsButton } enum AudienceCopy: CaseIterable { case zapInstruction + case scanToPayInstruction } extension DisplayAudience { @@ -18,6 +23,14 @@ extension DisplayAudience { return resolve(customerFacing: false, merchantFacing: true) case .zapOpenAppButton: return resolve(customerFacing: true, merchantFacing: false) + case .bankTransferCopyButtons: + return resolve(customerFacing: true, merchantFacing: false) + case .scanToPayQRCode: + return resolve(customerFacing: false, merchantFacing: true) + case .scanToPayQRNumber: + return resolve(customerFacing: true, merchantFacing: false) + case .scanToPaySeeAppsButton: + return resolve(customerFacing: true, merchantFacing: false) } } @@ -26,6 +39,9 @@ extension DisplayAudience { case .zapInstruction: return resolve(customerFacing: "Open Zap to complete this payment", merchantFacing: "Scan this QR code with Zap to complete this payment") + case .scanToPayInstruction: + return resolve(customerFacing: "Open any Scan to Pay app to complete this payment", + merchantFacing: "Open any Scan to Pay app on your phone to scan the QR code") } } diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppCapitec.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppCapitec.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppCapitec.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankMoney.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankMoney.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankMoney.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankScanToPay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankScanToPay.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankScanToPay.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppRMB.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppRMB.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppRMB.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppScanToPay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppScanToPay.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppScanToPay.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppSpot.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppSpot.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppSpot.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppStandardBank.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppStandardBank.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppStandardBank.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppVodapay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppVodapay.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppVodapay.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift b/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift new file mode 100644 index 0000000..3c86201 --- /dev/null +++ b/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift @@ -0,0 +1,112 @@ +import XCTest +@testable import PaystackUI + +final class ScanToPayAppDirectoryTests: XCTestCase { + + private let qrCode = "1490884538" + + func testDirectoryListsAppsInAgreedOrder() { + XCTAssertEqual(ScanToPayAppDirectory.apps.map(\.name), [ + "Absa Scan to Pay", + "Avo", + "Capitec", + "FNB Pay", + "Instapay", + "Nedbank Money", + "Nedbank Scan to Pay", + "RMB", + "Spot", + "Standard Bank Scan to Pay", + "Telkom Pay", + "Scan to Pay", + "Vodapay" + ]) + } + + func testAppNamesAndIconAssetsAreUnique() { + let apps = ScanToPayAppDirectory.apps + XCTAssertEqual(Set(apps.map(\.name)).count, apps.count) + XCTAssertEqual(Set(apps.map(\.iconAsset)).count, apps.count) + } + + func testIconAssetsFollowNamingConvention() { + for app in ScanToPayAppDirectory.apps { + XCTAssertTrue(app.iconAsset.hasPrefix("scanToPayApp"), "\(app.name) has icon asset \(app.iconAsset)") + XCTAssertGreaterThan(app.iconAsset.count, "scanToPayApp".count) + } + } + + func testFNBPayAndRMBUseFNBDeeplink() { + XCTAssertEqual(styles(named: ["FNB Pay", "RMB"]), [.fnb, .fnb]) + } + + func testNedbankMoneyUsesNedbankDeeplink() { + XCTAssertEqual(styles(named: ["Nedbank Money"]), [.nedbank]) + } + + func testAllOtherAppsUseGenericDeeplink() { + let others = ScanToPayAppDirectory.apps.filter { !["FNB Pay", "RMB", "Nedbank Money"].contains($0.name) } + XCTAssertEqual(others.count, 10) + XCTAssertTrue(others.allSatisfy { $0.deeplinkStyle == .generic }) + } + + func testFNBDeeplinkURL() { + let app = ScanToPayApp(name: "FNB Pay", iconAsset: "scanToPayAppFNB", deeplinkStyle: .fnb) + XCTAssertEqual(app.deeplink(for: qrCode)?.absoluteString, + "https://www.online.fnb.co.za/banking/mobileservices" + + "?codetype=masterpassdeeplink&urlencodedqr=1490884538") + } + + func testNedbankDeeplinkURL() { + let app = ScanToPayApp(name: "Nedbank Money", iconAsset: "scanToPayAppNedbankMoney", deeplinkStyle: .nedbank) + XCTAssertEqual(app.deeplink(for: qrCode)?.absoluteString, + "nedbank://masterpass.oltio.co.za/1490884538") + } + + func testGenericDeeplinkURL() { + let app = ScanToPayApp(name: "Capitec", iconAsset: "scanToPayAppCapitec", deeplinkStyle: .generic) + XCTAssertEqual(app.deeplink(for: qrCode)?.absoluteString, + "masterpass.app.scheme://masterpass.oltio.co.za/1490884538") + } + + func testEncoderEscapesReservedCharactersLikeEncodeURIComponent() { + XCTAssertEqual(URIComponentEncoder.encode("a b/c?d&e=f"), "a%20b%2Fc%3Fd%26e%3Df") + XCTAssertEqual(URIComponentEncoder.encode("#+:@,;$"), "%23%2B%3A%40%2C%3B%24") + } + + func testEncoderLeavesUnreservedCharactersUnchanged() { + XCTAssertEqual(URIComponentEncoder.encode("AZaz09-_.!~*'()"), "AZaz09-_.!~*'()") + } + + func testEncoderPercentEncodesNonASCIIAsUTF8() { + XCTAssertEqual(URIComponentEncoder.encode("é"), "%C3%A9") + } + + func testDeeplinkEncodesQRCodeInEveryStyle() { + for style in [ScanToPayApp.DeeplinkStyle.fnb, .nedbank, .generic] { + let app = ScanToPayApp(name: "Test", iconAsset: "scanToPayAppTest", deeplinkStyle: style) + let url = app.deeplink(for: "12 34")?.absoluteString + XCTAssertEqual(url?.hasSuffix("12%2034"), true, "\(style) did not encode the QR code") + } + } + + func testOpenFailedMessage() { + XCTAssertEqual(ScanToPayAppDirectory.openFailedMessage(appName: "FNB Pay"), + "Couldn't open FNB Pay. Make sure it's installed.") + } + + func testInitialsUseFirstTwoWordsOrFirstTwoLetters() { + XCTAssertEqual(app(named: "Absa Scan to Pay")?.initials, "AS") + XCTAssertEqual(app(named: "FNB Pay")?.initials, "FP") + XCTAssertEqual(app(named: "Avo")?.initials, "AV") + XCTAssertEqual(app(named: "RMB")?.initials, "RM") + } + + private func app(named name: String) -> ScanToPayApp? { + ScanToPayAppDirectory.apps.first { $0.name == name } + } + + private func styles(named names: [String]) -> [ScanToPayApp.DeeplinkStyle?] { + names.map { app(named: $0)?.deeplinkStyle } + } +} diff --git a/Tests/PaystackSDKTests/UI/Charge/QRRepository/QRRepositoryImplementationTests.swift b/Tests/PaystackSDKTests/UI/Charge/QRRepository/QRRepositoryImplementationTests.swift index 3ffda14..ba04d9d 100644 --- a/Tests/PaystackSDKTests/UI/Charge/QRRepository/QRRepositoryImplementationTests.swift +++ b/Tests/PaystackSDKTests/UI/Charge/QRRepository/QRRepositoryImplementationTests.swift @@ -39,7 +39,7 @@ final class QRRepositoryImplementationTests: PSTestCase { channelOption: "MPASS_OLTI", variant: .scanToPay) - XCTAssertEqual(result.qrReference, nil) + XCTAssertEqual(result.qrReference, "1490884538") XCTAssertEqual(result.pusherChannel, "api_mpass_olti_qr_51826223921246") } diff --git a/Tests/PaystackSDKTests/UI/Utils/UIElementVisibilityTests.swift b/Tests/PaystackSDKTests/UI/Utils/UIElementVisibilityTests.swift index a4d24d3..f8738cb 100644 --- a/Tests/PaystackSDKTests/UI/Utils/UIElementVisibilityTests.swift +++ b/Tests/PaystackSDKTests/UI/Utils/UIElementVisibilityTests.swift @@ -52,4 +52,75 @@ final class UIElementVisibilityTests: XCTestCase { XCTAssertEqual(futureAudience.text(.zapInstruction), DisplayAudience.customerFacing.text(.zapInstruction)) } + + func testBankTransferCopyButtonsReturnsTrueWhenCustomerFacing() { + XCTAssertTrue(DisplayAudience.customerFacing.shows(.bankTransferCopyButtons)) + } + + func testBankTransferCopyButtonsReturnsFalseWhenMerchantFacing() { + XCTAssertFalse(DisplayAudience.merchantFacing.shows(.bankTransferCopyButtons)) + } + + func testBankTransferCopyButtonsFollowsCustomerFacingForUnknownAudience() { + XCTAssertTrue(futureAudience.shows(.bankTransferCopyButtons)) + } + + func testScanToPayQRCodeReturnsFalseWhenCustomerFacing() { + XCTAssertFalse(DisplayAudience.customerFacing.shows(.scanToPayQRCode)) + } + + func testScanToPayQRCodeReturnsTrueWhenMerchantFacing() { + XCTAssertTrue(DisplayAudience.merchantFacing.shows(.scanToPayQRCode)) + } + + func testScanToPayQRCodeFollowsCustomerFacingForUnknownAudience() { + XCTAssertFalse(futureAudience.shows(.scanToPayQRCode)) + } + + func testScanToPayQRNumberReturnsTrueWhenCustomerFacing() { + XCTAssertTrue(DisplayAudience.customerFacing.shows(.scanToPayQRNumber)) + } + + func testScanToPayQRNumberReturnsFalseWhenMerchantFacing() { + XCTAssertFalse(DisplayAudience.merchantFacing.shows(.scanToPayQRNumber)) + } + + func testScanToPayQRNumberFollowsCustomerFacingForUnknownAudience() { + XCTAssertTrue(futureAudience.shows(.scanToPayQRNumber)) + } + + func testScanToPaySeeAppsButtonReturnsTrueWhenCustomerFacing() { + XCTAssertTrue(DisplayAudience.customerFacing.shows(.scanToPaySeeAppsButton)) + } + + func testScanToPaySeeAppsButtonReturnsFalseWhenMerchantFacing() { + XCTAssertFalse(DisplayAudience.merchantFacing.shows(.scanToPaySeeAppsButton)) + } + + func testScanToPaySeeAppsButtonFollowsCustomerFacingForUnknownAudience() { + XCTAssertTrue(futureAudience.shows(.scanToPaySeeAppsButton)) + } + + func testScanToPayShowsExactlyOnePaymentEntryPointForEveryAudience() { + for audience in [DisplayAudience.customerFacing, .merchantFacing, futureAudience] { + let visible = [audience.shows(.scanToPayQRCode), audience.shows(.scanToPaySeeAppsButton)] + .filter { $0 } + XCTAssertEqual(visible.count, 1, "Audience \(audience.id) must show exactly one Scan to Pay entry point") + } + } + + func testScanToPayInstructionTextForCustomerFacing() { + XCTAssertEqual(DisplayAudience.customerFacing.text(.scanToPayInstruction), + "Open any Scan to Pay app to complete this payment") + } + + func testScanToPayInstructionTextForMerchantFacing() { + XCTAssertEqual(DisplayAudience.merchantFacing.text(.scanToPayInstruction), + "Open any Scan to Pay app on your phone to scan the QR code") + } + + func testScanToPayInstructionTextFallsBackToCustomerWordingForUnknownAudience() { + XCTAssertEqual(futureAudience.text(.scanToPayInstruction), + DisplayAudience.customerFacing.text(.scanToPayInstruction)) + } } From a4a054135435c7d0055d7a12986fabf4bd0327cf Mon Sep 17 00:00:00 2001 From: Peter-John Welcome Date: Mon, 12 Oct 2026 09:11:38 +0200 Subject: [PATCH 2/2] Add Scan to Pay app icon artwork The ScanToPayApps imagesets were committed with empty 1x slots, so every app row in the Scan to Pay list rendered a blank icon. - Add the 13 missing PNGs (Absa, Avo, Capitec, FNB, Instapay, Nedbank Money, Nedbank Scan to Pay, RMB, Scan to Pay, Spot, Standard Bank, Telkom Pay, Vodapay) - Point each imageset's 1x entry at its filename - Add ScanToPayAppDirectoryTests.testEveryAppIconLoadsFromTheBundle so a missing or misnamed asset fails CI instead of shipping blank --- .../scanToPayAppAbsa.imageset/Contents.json | 3 ++- .../scanToPayAppAbsa.png | Bin 0 -> 9665 bytes .../scanToPayAppAvo.imageset/Contents.json | 3 ++- .../scanToPayAppAvo.png | Bin 0 -> 10838 bytes .../scanToPayAppCapitec.imageset/Contents.json | 3 ++- .../scanToPayAppCapitec.png | Bin 0 -> 9113 bytes .../scanToPayAppFNB.imageset/Contents.json | 3 ++- .../scanToPayAppFNB.png | Bin 0 -> 10173 bytes .../scanToPayAppInstapay.imageset/Contents.json | 3 ++- .../scanToPayAppInstapay.png | Bin 0 -> 10433 bytes .../Contents.json | 3 ++- .../scanToPayAppNedbankMoney.png | Bin 0 -> 9841 bytes .../Contents.json | 3 ++- .../scanToPayAppNedbankScanToPay.png | Bin 0 -> 9903 bytes .../scanToPayAppRMB.imageset/Contents.json | 3 ++- .../scanToPayAppRMB.png | Bin 0 -> 8903 bytes .../Contents.json | 3 ++- .../scanToPayAppScanToPay.png | Bin 0 -> 9266 bytes .../scanToPayAppSpot.imageset/Contents.json | 3 ++- .../scanToPayAppSpot.png | Bin 0 -> 8287 bytes .../Contents.json | 3 ++- .../scanToPayAppStandardBank.png | Bin 0 -> 10906 bytes .../Contents.json | 3 ++- .../scanToPayAppTelkomPay.png | Bin 0 -> 12180 bytes .../scanToPayAppVodapay.imageset/Contents.json | 3 ++- .../scanToPayAppVodapay.png | Bin 0 -> 8375 bytes .../Charge/QR/ScanToPayAppDirectoryTests.swift | 12 ++++++++++++ 27 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/scanToPayAppAbsa.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/scanToPayAppAvo.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppCapitec.imageset/scanToPayAppCapitec.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/scanToPayAppFNB.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/scanToPayAppInstapay.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankMoney.imageset/scanToPayAppNedbankMoney.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppNedbankScanToPay.imageset/scanToPayAppNedbankScanToPay.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppRMB.imageset/scanToPayAppRMB.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppScanToPay.imageset/scanToPayAppScanToPay.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppSpot.imageset/scanToPayAppSpot.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppStandardBank.imageset/scanToPayAppStandardBank.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/scanToPayAppTelkomPay.png create mode 100644 Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppVodapay.imageset/scanToPayAppVodapay.png diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json index a19a549..b860796 100644 --- a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/Contents.json @@ -2,7 +2,8 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" + "scale" : "1x", + "filename" : "scanToPayAppAbsa.png" }, { "idiom" : "universal", diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/scanToPayAppAbsa.png b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAbsa.imageset/scanToPayAppAbsa.png new file mode 100644 index 0000000000000000000000000000000000000000..f62db53daa49ac361234341b8c613f869736ef77 GIT binary patch literal 9665 zcmeHLc{G%N+n*U@U$XDZ*q4}Q#x{s-WzP~?RE*h7%wlHjOLkG&OG0*uM5rW%$W{p{ zDcO~hB~c-Hhdlj$&-*;jdC&XDd)|MVb7t=Q`rg;_xjxr2XC}enpanOFI0pa#;I^_f zcVb)}w%%+kjL#&#rAh!mI2?^KJ+gH@gQ-eFO#tgQGpM8Ys99LPHCoiPF%6dFp6*YQZsBPc1DS6avnO z#gx9|PW6{N6zyMvLQymtmP#j(Ni>E5pnk`|eA~d2O#Qooz*cN1frO`GF$64$4)xdE zvJpiiXkNj$?&cqxFp?PdYs}1|+RQP|eb5a1A_4}jk0VowC^~^aMB%Y}C?xzT0*OXP zk5Y_0020#gWKdk<3^#k4Wa&s-=JmpAH7<3bI<0K`&p>`zO>g2M_F5- z3-LS3QH8i)ci!8nlPOpd7ITUb7e&ONkJ;v5fPL$NBcs!I0V=d~PG@3{q8H){%_cn3$I6q-zg zqDXWvDw#q+L(x7cKMWR1p_2Uxn16;ADD%&%WGVqqAZeh{9&VhhMT+c4a(> z*eY-d8s&q>(Y#OyZ5=cPg|XYR`2E_cNica~IcIVBjQNWmCTNXI|2(09Y}_P}-x(#n zKYY=lV;eMSyU>jENdz2&l~dS224vb+hej4MWE7PyDvR^MlJImdG2ui20A#e2hw^qF z2(-`NCv1BUY!#J2{MDzRUH=^}fkwcSP;@^kHqh>GownUtd;V7o;#W8RcK2_GQWv44 z=cx(P)zHRxYHDcV;GP;t1Ol$1i_+E6L!!|-7zCWUQ*!se8a?{|a1?&IR{LA-|8~m$ z8uy)YTIc}c3(O4oxa(r@y;ixVCSR0Kq}*&ZlNZ59>)#JJ`OB~B|K#^~lkK?O#-Rqs_5Y6rD_UCy;RDqV3)xoBU&r zAqN-(M#K9vRtlqauy8003iGB>uxQtv69iNX3IhOmkvrX^veP~PW}*KsD5IZw*|yrJ zKjtWizYwS-Dti>f0gD2$z@mWX^O-RS((1QdTifSCQ7aEKY>JAyIU1e6aA z;zTCXA!a5pX%TLO4h#v?g(I~zwRMg$L?lDhf$MFHF!TQ$N)@L3D-`5!p?+h8=|ou&{2!2LX5TU;?r-nF7F{^8Zz!J1X;Pa?f{ zN`-d=H3KjK8^hgu_cPH|rlI;_Vfzw=wOp>e3v03#xvzUCz32$c6~@EBA+-w#+ysM} zK&%nl+(;>cd0<>D9J^V7U|{sjNf3}BG1LUM)Icx*OlC`x2aCdlBLsUKC%};hF>dnT zC)=J~Hp*!kJpSQ(5)qVpfPr- zV&C5VufNPF46dvi=SI7mzO?1kM~4+DP~ z_`|^eBLiQL7`I-)z0t1gZyAcrjM@98vpngrb$SPTyN@K!<>@yIo{*&WH&yv@E<-;9 z#)QeYGmgj75FQ254z(&}-Qc-v4ItgyBPxsx*eRAr8GrI}3T(ZBfXg|ej6)#J$-)$H zqet=sLjdDV>`VZFo5`F%P|N@T&l4+i6X!tS+zEEN;I!1{(B1^b2vPMBc zRzX5%NIvAr{PN~grR->4rY9uWyY~_~xo=nBy&3)4v}q{7GiS~hCl*#FwL9Y8g_AfY zr&6$JAA2)UXKm1Q6u&R5N(1D17&k8AX7G$Cv0pSzEaJN$@1<8q*}P@yOF#pA@TjXL zPwjITxRrc?13i%b(lI<2`wvMWb2;ki3jQIrNRw+{NJ>kHKIQ{yvGKS-@BYp^dmUnC zYwvY>^RzQh7N^t`R!?fOe@bh--FI0bj_vwj(5PSPpiYzm%MD_0LV@COG7QldtJ8wy zFSy*dc2(He`y~@fg4HVz8nxKm=CL&M{e&3GGMud7|YiAK>W(*Xx zhfnReQc9<`OG&$#LGiwU!^;sKiA*9Iouvn0yLb7{o>L%W);eSZo?Y zC$8GXlrCJT7YyV)*sQZIj~vj=dGh`jwH^C&oeJjDdFGlQoaqtcFj8t5S{;!|Dm?WuyUeYLHPyV0ZK_U9 zp>a+0+##j@vujv2D@y3a-47G0`8yT%5NAz?G*F8|#~gIzc6s^+*5J#}fiDd{UkS#uR0R}@mNY$)x8jmX z7_Z$d{^Hb>BO&+feifkPjxC2o5Z6T4DLEhhVayrPSGNugHgcO^sY_`c^iNC`Hedk0o?)2F==u>0BHyNlRF9@fP8$+NaJk{(>20J%z7-?*1q zEMH?qzMXS#;e?4k{L*e!iB;AC;w#pYf<`chq%GM{pk^2TN}%Gz6uf%+`2O~CVCm5F zsk^G&kJz>LX4o90l7mKXp$u{!>lPL@s~gfXMK4WCYofF=;$ULeGz%c1%=;IGGSg1K zWWq}avq!3hWakZ@7eDigb%7<%Gh!j1xjQNvKWZ{VWogw9gXZL2msh-Yz1_)~mE(gF z2Lf4BhxfvqOyUaXDvdqFoB0iJYQ!zFyu;n>Nb~dKpl~*^t}zuc*^4UgJ$5(5oPU;N zaiH&5G3f+AR$DrgGbRIh>CO|2cL||wc2c_(3m}oKuq>&t`;(`uVk9^aT3z5Me*j%$SeJ>3CACl$xB*sF_Rki}zJ=BQJqmI<*9 zr}waZ_FWttaGF?wD7c+i#9Tf*J3Dvg?tA}kz0xk)O6Chwc9jG9U*mu#C(IT@-FWq- z*S{k#jRf5s!iOnaI~sk2e^0s)n0W{nHc}BfvY%FXV*ttTCH!7 z?Pd1$wA0aN9p!83hi2Be(mHJ7CN&10oaD=SJ_5=zR*HSyvN3*a)m;Vnh|SqORr>We zDOL74nxkWxe8RGj6svbv->6=qQ8vr-;cJ3$Tkf!f3SIQD6>Tery~|BKvGeUdZB2`? z^1LvK(mU=MT>>`UW8KPy$b|NKjz%al%%vt30b^d2Rxxg#j+!r(?d8g6n_9s;-kagH z^uIZjGjOS6PhA*X1@m^vl+M zavFY3#gsb>rWU7%I4e{n^&Ypo>A=y=C;D8p+NR_@i@ENEzCt5{`SMRg)eC!iU7Mab zzfa~EHsBG6Tuxmk`Dg|5NSiHdM5n+u;A%`$UGu36WwHI9wU&40ap^qg z`%^}Uo)WV~$;L+~a{}*EOCZdZlp-ywm0?OSP_^Q{<9L}&0`WyI(@zDPGjrm~Ljo2ZkF6eg^!+_Vy3%}@Ccqo^<~%W}M2eq_dB1qHmheX2 z#A{_-{Kz2JeC+ax&5T(&Q(dV#rnRmP?~x6`+lMbk*}rH;uD0ONON8^>qQLlF)+TzO z3h}ofzc{gx6Y*UxWhuL{K0~FUOZp#g&zlYO{;a%G)ijBta9-^e!*0AXm_mP@UiIit ztD8}zx~FyVrY>6nXGlDy3yOJ`L(;kz^v+sd^|u(7S-AQIZQ1eRnONRaRjtDn2q;&y zC%EPlnQ7pDw6LB>KHsxSd z=R9yVMQ%j9U;l_~-nnGsxHEH!%DW2$1?}(&k1i}`GQN#F-&*ebt~wAFl3!FXpOv_5 zw%eogof@rn)pYEY*=V=CO!6;#0#XG6o?3V~e;!18mQ z_^U^cY7$PO#VbE%=?YcF!(vLRdp=g(*0YHcvDA`Vso2k(CXc@m)ZqGYjak+{;;G_s zA{jMnTYWHZ*Rx3Zr3a;lm7H`NCHVMjIJjvV{`AJv*TZ9u(4by^6cLI$;fTF69qVat_so_)x-KRr z?E1>lNyZ8TBV~5r`g@u?cR%im-gFKO0n7J$T(j1cEx|@l$IVqA%<}8vz9_z=E%44Z z`T-$Y@mkXJyXmUyZ`sAw%|z1NLSdiNfF~M zeP>qfNa+_*2vJ&Q{@UuQv-3xDjR$rG654E~cdlH}?6%{hAg@U_nBABON)|kXJdy<1 z%}r?mR}N!F?y=Slu3QkPX)FlpNnQ8UZ<$L*#zx3my|N~kOw&z&9Sz|q@Ixukr;UU{B=N)9YHlGuU3NivgLmKi+qE3 zHx!jCwEWd0?Z&Sb`+$UI)*ox*BD;&Pd-N<9Pw|ge)f}>J61|eksv_3C#%=J^wdzq> zeGc0X!Z`0om~?FBv!`*Xfb^F+?@fYax2UCHl)uE(1DpG6y&x*X2uI7?ya z7>i5u*Z|({2_0-WJ2mwUnRKFBo~!!Wt8@vgdV}d`w_9Bh7mm}v_fP8W_(FBDLP z@2wHguE(teI z`BiJUFa}d8UL{la@FNE#;cL9o2Vd_*Y2lFUYtHkZ}#J$;#dXWj6$7 zYuBCWg$f-7;=B5-7IJTVnG8wnD(b2`_~e{L&N1WgtjW;KBZ>KZD5EfsB$*$FX3Tl} zf)AVPra`qkCZ8S7Ca~Lx=9Cpp&$d-#gxZV6DE-rB8EO&m!)^Ja<&$O9Jl*E-tPObq zODC^_GZ^TczZ$<=t4;+IT!oxcv)fiill{t6)%{*?-b9AlYE-2#VIIuFgNF2SggP9#aypjz%J7_ zPvS&mL0M3B)2|e{n}_zr=s1?NTt`oTpP(aIg*Tr&*lIMx#&Ayc-_jFYzdAG!K+_+g1^3faAB9fp zedqIgIUl|moFHkVSB(OF_l9=ti$`6>uFI-@mR4z~hpmaCgga03Fu8fTCHNn}Z?Z<_ X#z#TKpR_Z6=K`$uA2h#V>Jjx{LJw+I literal 0 HcmV?d00001 diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json index a19a549..6067db5 100644 --- a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/Contents.json @@ -2,7 +2,8 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" + "scale" : "1x", + "filename" : "scanToPayAppAvo.png" }, { "idiom" : "universal", diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/scanToPayAppAvo.png b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppAvo.imageset/scanToPayAppAvo.png new file mode 100644 index 0000000000000000000000000000000000000000..4c3cba792efa8a79037091257206520feaaa3123 GIT binary patch literal 10838 zcmeHrXH-+&)@~@$q^R^BdXa>LUZsOnL3%(jB!PsIKoSrT=_nmUP(V7UAcCS)ed*Ga zCZJN4Dn)t`DZ&@j<9W|_&KY;yA9vh8W{hO7wf8K~dge1{G7@cWX23wlMF#)?7!1$r zUL;-3kKZ&@q|b!Y8>IjMTMz=SZFhWi^YL^h-R2`*kq8+tIN&tkR0sg@2%vP&o8rd} zl9k;rD}$d_p8sm)gU6~ITdKGy%R4(G*|KV z5{Pgt0%fS{C*|kqrGmjARb-T8U1a3sok7a-3P_Ngf(vOSgM@(O6=dY0N^l4YDy!sy zM|qF}k-(xcUT7~ko`m9p3jjbi^$WMwf5#0+{BQ*O%KQecbfYqNUuf|S4f4#iuZHme zDNy<`=zP~-#$ov`KUeNQj*jy}VNpmoQeLVtL1 z;;v%dkthNJkMTOD$InIQM?~O1A_9qM3<2nZ@jwCLMA8NY#G|}@Py`|n=K_QSeMsT~ z!m&u8C)^*1hWny`2s{c-L?MAVJkS$|#JFHc>tnYcAxO!Iq>>T9o&=l=@hYi)TCSvh z9ui9;^jB&;+`~ibXRQpe2oKWnklUn+b^NNZ=6|p7F_mB>oCyD2;O?bcF*n%+9w$Gz z@!%Z7JcRTht)f+J0jJ$}D_)x-)-XP7<6J5~8AK0Xav9Cttu zbB~}I^lQj;>g|1szVZV!_D7*f$H!t^NUXS_{78@q#|jP2C+*>QB8PyB2MX&-M02vm z0089Yew{e`vu74=vzfj%K5xw+uzp&gvoKl&J`PiioNt1oG!kfeixf+1jtJHZQuu=#aI1}q1L005_yeyKuA(lAce|9LuLa!k+w0KA9+ofIT@KB#fL25=IuEOF>RXPR^n^n@hLStlU>$6TU~K zeL~&Uni&A0qoR?#alS{Ll7a$a2xW(`Qc+k_(lIms#w!Ih*VZASlsbMu!7TFo0Z`{> zhXZv;-w~wF#=t!Yz>7E>5vZdD;bUizQGh5x6roCTvhoTr(pHJIRe&o0*g|ywdnyTt z*w0kJzoq&)ss54ClGGQZX$-N4FjGl_qh)D+qP%CrDF_c!JoCs^Le)oI^X zcFXr& zlpGMY5SAW`DaueYq=V46=~ulO=Q5itu)V996>i-|4)Jnw9N&gNayEJ(of28XVBRVI z<%5h<;cfMO*fz z`O-j{D12s#)c{thSd*do9}2eHXei`sH~I zY+daGf#>!z7UqX4+b~}S^L?#YW<}g`VTGCuOac+7&d_w$?WlbXJPKZ6ppA&&?xP!X z(!uu*yXMq2d_VehG$ba*79g=Q#VOkYOhY?<5sXNq3CG(VsGNS4OMA!qpibv z+a-XM8)6103kNJI_TQew>3|PTMZ4##Sjwp=#9c*>8YM zDEfpu+;4#UD$j19t@iConUB5jE|Zi9=XYsV9&BX}BgA>mmv26MempC(rV^80ME5R| zhblL%)G;KP$R=qOVd}atqnoKW@R|GMPQI`~a`D$$p^R?As4W{K&rD;hWr-A`p*iP~ zdGbnOXW^79+qb9V5uQVz^lASpI2|8-l3$P^u40uUWu_<+W+wnE;!68apUfiQ>uxrU zIMJ78DfvbTtnGU3USM_Mqcdr1tSN&_tTWj!No zSdIEsp=nnJ!maXz>r(Oi!jGkbGcRHbgxiHh0Erex0KS6E3IOcEcd_q_2el=>tyl|v zd_P$SuRK-FR=k4Nb5lM6p<;Fo<5zqlgdA2B9 z<2CaT>N|fv^A=x7gm<~d=nd0&hjrMv%E4!*l5)2>+%2DHG(2vi^0wBMH06&C9iqwA1AHh^jWir9wzo`#T3w8KNk@ZGs? zJx+N^m-Z`RfGTE;W5>Sgqgw*_gMf!Y%qzjmVtzq$lE~sJ=ZSt?Q^qx}X(&Ypyh$WD z<=yEt3T4XhiyaRbOk4CcJ-u|`yptmQ>yT*VbvDkjs&}8XM75sNs_xj@g*5kiXB1AW zMlBB|K7A%FgUMmu@{_vZI94=SE5OhnJGpUs!0RXz=Zt=)ZE8H6s5n&PE#wakS>F5kI(p?9o-LF~>I+HEqFk=>%|USXk;@}p zy_qJGR67}jB<`%R)eW9RTEn}j+Q-IKg8L&jL!k^i&G1I{M}2HNOkb)2`Chg;RBo>e z+$ZG&AlE|&w{PF#lvs;W*^RQeQcfse%U4YzCcm((I=uR2eWHbFGC13xDn34* zSJXow)d>FaFaMg^I}Q+^MWSDrZBpyAJ)fGr;b3hNO(HOg~D0(41j$dt^l8cM0 zXcoS2t6A!X!88qA(1_=hb(wJAoGYlzGvw`vYszUx5LUwwda+li)i>d90WjYBlXKtB zeo;o3rO+1bQJU7TGQt~rO-q2zTG}@pwU?k|pC)I{UA%H(DDJS6)qjN6dyGsft?;qA{Yh4wX`NXQU8-D%a>N_Ijyj9p z=-AFamWUKiZQ%#>B1NI(v5f}4p6dP7G*x_2X`>f6QAce4*zusWx~(L#eX)mvpL0E& zMRw(5J~>w$Hq@=b=#B5V)9)x&e+-?w`&UTc=I~8F&Wllf9gUQ)d$>ckB0{4Q#l!D; zb&SqvZa8spJig}2d$>_z`&Q=JUr!<(dK$P25QQAfTXEDer=ZerWjJf3o5U(xD*OU^ z(rBmz+}4Sct2>RQn>5*=m=;KrSV%Yxx%^q8zdF;#$l7?_(hz3#(|c)^NC?^L^711z z`Ca49*eumk>2z-3x`)&IN z@XU-gtqkt-_A*VgxNi)BW&O1b0~695inn>{EGA}fX?^#(X*~C5pmJGqi4+;AJ56n& zuJ)eiC93CnT-N6lHSuCu?QNnbtl8T{iUz2JgtBerVwZMiy$QE~PN?Xkt4Fgr7{Ju` z&MfBuYfK?FJM6RJEZX$7;I#wnQ|T-%KQ`X+_}jO592lEA*l=C@pLXh2CpEb%lj!iX zL&N9$2XD_y}_DC;jNkdL(DE+>XK3Id}l)>;^Tl72eC$nh$@Ks;Ik6gNH27P$7 zITP;YRHoG4n){I+%jc9{ItV1e5=yzmLlYZZ#ME!q2~Xl) zTJd(P;-0jZtK@?NFgNGoVxgpXgS}Hq zo@wXi1FdotSQvYs_<1U;ZCpOT$vko)u2k2T(#NW4N?pW@u~PB;gapsx?RySycng)V z@GbL@&w+P9*Hc5NU(_S0v&V%5^~lAA=bJod03Sz9v+;w0ytHv*457VgV5q;i*4NZ& zWS?hA^_ebV!hreiKrD5XEL8Y6(Ww*u6fS=926i44QmVFst~X z!O20<{t#Bn!|#FH^eG}{LPvVckBf@X?PhM|TE=&7XnPO@;gdAA^M6_xmpb~F;*=9D z2F);+Ez773b#*(UzE;KelKHKllccz_k#G=h_of#GR6Tm1X0b4D(Sl+$p-a;_6Pg;e z9eJjPa>#k5iA&|g_9Oi|lpmG+eAl^=hP1L?-xZ^<_AY&GmIX@|DS039(ANv*kvi?x zR)~#|w-%Bff^@Z8{l>LyReW!v>9B60o1<*oOM-auej61TLo%raY0Xa{`fncw1vuU4 zb0xhyU0q8Gwo0Yk78Q3WFZ2Q)own0gx6c0xkfB!%3^;oiZj{;SyL2ERb%hIL{%FK} zq@QPTCiL{vkbvc-7~b=)OK9kjtAloCr+EZX(s}7dy5YbxP{&}Uq*(Obgy+wua|RM) zMXXP|FlEE%WvC^nhGo3Oa5>i2)@iagVTSP^PE37gJlLVy8cwn_a6K;@nl-EJqA1$N zp^z{LJ_))|7M=rl=;`&YRVpa)?rdfM;&{32QhZiZefGoxpJq2bQYHW6xi^+2Y0?1+ z4@^Tdc?{*byW*PktPnccX~kOa2L)ifY@2s@wn9M|Orq1E^6(2olNJElg@nd@&pm~sn|)T3E# z5f$c^QSnKHP070A!5pu;v}n}JqW?0bW;Peab(Gb#fxTL)BQ*z3sVCGF$L6+Gb*ABl1!BJyZw1aJ5;{ z;3xJZMZ`zljZ2`86?eo|_Kg-dJeXIbtJ_#S*P1?TSOLBx_XsoZnxn3FvZN_CMmGwPdVdN^d~O|P*$c> zjoZoG?8;M>aB~=#Hu;W}1J*?@xD5K=x>C~}Z{!GPe}8Iu(U6;}rmQN)SxrRT_#~MG z81_k5#z_ZkrhPUC+vfZ>A(u_V8I3?c5BTu1=ISm}c?A}@zx8PT`Xo7s z<#{y!=k~#I`R2--SqZ+zmHn53b1k$$7mr5vX;LVPqaBk>L8EIE{rr;)p3(wB!wh1n zvF-9p$!iT95?qbsAdZqvHl(fd>~sbBZ8T~`1>eA1S&^Ggu9@(l!KIz5i@(>S=)6e9 zNx+#R^JELANMZy zd>Q?4r74Dgx_g}4&)cC|a)pnA(kVrm zIOC&rdRj49x|ek>e^q|DPF|BedFQPddz^L6;Nse;L2tg{XtD{d@{OVnij)_3pIj66 zuS;%MTsq&zB6Z0#b{` zJK@@Ee2wvMRO_6|-w;P(YIR$5eJ!sZK^5!Pi**ux?R#X>huCMyQ-sglklH&lQfB6J zHLDIi(%kIu+RVE1-tuXu6XVMYsk_@%bI{c-kgok@qib#`$++`&pXm`|a}VXBSvWqO+3?50?ZN007{z zv$b+%UY)nz9BjC|Fh0@4|TbhOjaBW=!eY7rAO9!V1MWV5~Py>XHJ`{t{)2w^8L8OrBOas839RsUv1AhwbuLeR}v0+3qfri5pabyN8 zOnb{l41=HtyrjiBR3^qa4YHK^a%uP-W1f>RO#31t7GsE~(1OtnA~6_Ez-dy+gg_#h z&OnnfI6JEdjfh~XA(4nR#2e^qYw7DDq5eob8j3`s5m0|^ye001jwTjo#`o67D3HHU&&y$zuM{|pJa70LB zD8Vo^nGryvP>C2AhJ+5q;$T!7C5(vuJG2OyzpGMcL;{fv#Zbt2rYe(sLMS2u!&EOJ)+f z6Pku5kx)NsWk<%4nCW4cm=$}nQ(^P}T;VM$VOTT+{jcqS`>xCka>`c{WV7cylujUgtBC*jBhMu50T5&!@+-N{3F zI}Zeg^w$a7-UC}jB?kZKQy|}ehfAar31l=Ql!l9N{7a{8x0dGrYC-(y#-Hx~aVU{+ zEi3}AgMn&mX(6FVjK4ke(1T&w*h_kWzS zKgWHioWplk4pvD9mc3j?o_@midAPh-cUiXiX!5h+bvY&awZR{LRsScyKbvgFt@!tX z*hlMj(O%JOA0YXsDr}AxD}@dVypqI?tn!ulSu?h)>Bnqy91YE&(ENyGJfcPOYo z<`}YYmegV2TR!}YZEk=i=C2brQiQ`FTm*cRbd|2dQ@T=_>R$X`PJ*i?T+ zbYsp1a~s3G;X-We+wg%bJ9&Uu*g+Nm@Wo?XL7mQGtinUcMvD>yAFKDHFGg;z*?$!6 ztuGZ(XVDJFhJT;vFt!FURNlZ0PnbJ;YvdE`*bUl|7x0B|f2u0@v?zQS^>ztbbNd+(IVm82XJn-l)z81VMuein1w z;#D(a>#?uz6h@ZT%=2PB+JJDX-=P;v=t_V4Qq9cMS9zSDs?3cb{E9P7en0qv4}4Ce z^_(H1Ix*s%+q%2URHF@N!Pe&U=DG57@BO;@#lSBHelhTifnN;#V&E48zZm$%z%K@V zG4P9l|3?Ovz099h-jfL&C&#HyuB>OpAT7jL-+xX~d1eTVZI{M=3cN6J$$azqE0HVF z$OmuGptfwI(&i({SBI*`Ki)S;IA_oV5UXloX240c^=5v_%Pq9^W&vEz6=NQ<&|PgT z0M*@6@0kLafO13u05#{hzoA(HfL+CQRw(xfmQRO?RF5I)%{=U zs5W1gpU3;dMlg?oF(oo*F^MFwcR+h zPMc=;yPg^VE!9dDnv#ofu{iIbigQa(b5)KRo`QMVU-j!#2Ne6AEZYM2}`Q(BKd#4U2s5XCJ_ z9|*C@1+S-%$Q#=EXPVa?ttFk_@4NqqV5dor*wq%khsv7bnJv_k0>xgB7iz1v5(?26 z?<^C}NPwv;P*K?MzEJfiBNmy8!Yd`tV|9%H(|!~SU0HQLhf{_atw1f^CoHvY%X`RO z0K4n?MxK^+jPG6(q4HPq!M3YUI839(Ta@9J;4~$$w^RHE1{A1zkh`0UwM&H6hSRpa zG!K;* zNC(=uF&d-({K3|HcQq~>{gICXO!&VyIV(6 z_9W)k%s}GbwAN{O-F;)R(wtx(XnV>04evE;6TX4$V2}8kuz|41yDJWnbzcDorT5?x zjb<~^>zRpnqeJqhxZ}oqmnRLu@&eGu6?#TGUrglICq+oIF4@xN)Ryox?O-*Ff$J7u za_K1X(?LD1K@RC)wP#Xp&2hE8Z?h-I&yMItral|z8-OJ*8yOEC8tZG9y!~oGSf}D} z*F`g5pu&mspk+1E(JbOFY_M_4u=G_L|mK_9aB&o zs4M1h9|S1c4F;bM4|AW^ySjNMm_4<>Je_A|T*b4){a&qjL;vwUm$p?S2MhD1lE2vcAJjaYMDab5IA|rFJeX3*czWuY z?}f9UAISS*Hu`s$8!uj)o3$PkQtvydHmV0-zU*J|E?guRV9-!1y1{X;M*MX63p=28 zu>u6SfQYe>9N*F@5~{|Ro)UUy5z$f za=e}=Ep;^ykFB@1FAKyyYnEua>RGTLvx&TaXVd?@GjMIt#?L1{$s|6}7~9WfHH1w= zvHK-uuu8W7D@x-0^>Yff@p+1AXCDrCNEk28D#>X|`c@8HbrjlD6AOACdOP6Q+HN_w zP=Ae$s|eNSH$8&-tjKvYh6R}0rq0${34=MgxB(+d(a|25=I&&2AK$kk`*xA}x>j$SG83wQ#ayt@W1g(kEZ>B& zPUGa=SP?4;ys5oZ+q_56{9P`0Kw68~t{YMgk~cGCqQD-WqV<}o4=Hk7^PV4-TX1dS zZK<(CtBZ3pV_(|R%S%#YJPqh*&luI8AW$g$@Q4)MrTb@32z)PpkD zcZY5%ns35}aZP9r2ec9PSb2vrAr_{S^O0X+D*z(jdO#_9v`SJctdFsb@a zW0rPjX7&n7b4<7#9Rx!Q->O*&)?0Vloi>v3i5+XBb{&|>9W|Ww4VO-e3N;(!vUzvN zJt10hOuwbLx^h`1_sp^Sy;akkRlx!MB=r)*hB-#B2*bJNI-A+SW#b3=wfspRsD_1l zZ?yK57L0UTFC?oAtSx@X(E*exYP}8ePtc7 zqoNNoslg3zta@FKcRdprHGbU1-E;8UE?pOnSSL;gd|L4pOcL!z#MGe)M7RW(W$76- z{o-rtq+OirqN-di(haB3U&-#GRGXM8x##u>s@BS_J@=JHzD`8Im9G$E9Za2d{ zpAFY3?3?sz&odNCGSOTZ(zg(Edg~;i4J;{2vaPI;(u6uzQH$6&q}En+2Td0A2Styg z6DL(0YtHZA}Xm+wMdJ#CdLta*>`{6a>pa%jIW zmv)fNCth5ugg2?hcqsZ|at}15Z26-TodYBkqab&xZJ6V;_kz;K1KjmJkanI{hMz|I z-NGrcng9Wu=X1kx`!yKyZrxR2bN|;@*tY@GV8e(hyOJWuU8A0?alY(EeA)y{xBk^P z+LYc2hGcC~$c+6Y#brVy7s+YxwK}DZq8crgb_q}vlqz#wh-JU`G)JzBDa+}jDEccv z>Qn!M8SQZY`<2V!jr9eQ^cLH}?wSsxkHuE}!?o%I{Tl6A^|}%%-`?Nqg525FCUDV# zUE_X~8ko(q5ys^|cdJonu-Uv!f`4R@R()qz7@WHzMw)}*P;jdowXBF+_}#xrA8F4` z$jk^QD%PwRPeD`-n&V&|p*(r^4-ZPIIHflmgYEZ1JXFM$DwIa7E@gCdq>hW)KpbXE zgnC+I#IqY5onsSB*~E|gm^~7xA3C03yAozgcJ*|v{&KN7|9$s# zu{*|CTd|5EDa3o9=A3{gUu3;yxvx)r7uvVSr`T@y_f<&mDL}tsz3B#aG5DoqU*7>G-~;P0-B_Rf(ymIzypm_rk6p z?A5roShPt0^10QlJ$<|yWqS$vRCqrkr@?6H$bc~N{LLGop(=B2Ia+~lxSk}6x;>6J zF^8CNo^498I&k6ioBHn7_?|Rms$^n*(vdH5dWTW(*Cdu}gN2kZqw?qcN2iYqJdxqO zgng3Xp4FFG_b$D-$QfCR z8%i+z7xl$03HwHFH^QHl*=mx|C%)Q4?I3TOvcB@pDres>%U`mPA1A4Qyjt1Zx6UR- z39t&%7j(P$?spyb2G&;EjaMCuyf5_jU%ol$9hL*rtrcZBt_>acLJqZ04y>s91HOsq1^z>FN@9Q_Y)?zi9q<`UzEM|>*S-J9| zOl|eLshxPHo~V5k-yVTgL}W2I$_`3bp3vNwn|HOEn44b(39Jf7DzMIW9Oo%dc>b;l zh%``$Vl5vg$l_biao>ww5gZFx?3?Q2ZD#)lFilL%Z+O27dmpC=-wb_{m-a3Bj(D}g zh2K*ZKfpVzMdt_SYdAXlZLLTA23X1Mmq5~zZWoq|ZCBbk4CQ9u!ts69YpSiTxo6Dc jQN_XeJ$9Q?ZJR8eaKdV}py1YT`v5y@C#!0UBQgI4B0go4 literal 0 HcmV?d00001 diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json index a19a549..95077e8 100644 --- a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/Contents.json @@ -2,7 +2,8 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" + "scale" : "1x", + "filename" : "scanToPayAppFNB.png" }, { "idiom" : "universal", diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/scanToPayAppFNB.png b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppFNB.imageset/scanToPayAppFNB.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd9d85a931f11c47c92267d5e7c5faf55278e99 GIT binary patch literal 10173 zcmeHrc{r4P`}df!?;@0K8f&u5SjO0jkbTL%g)ti$Gh=3K5uubVYg+7U*(D00qB2x& zSrSE*>~2fR)}7ywr{{it&+{Db@&551?>{+?ab4&4I+xG+IhWyzv#~PfVn56d006j5 zO$=@6SDW1rD>MD~Rle0K06;JTg*@rJdp#TI?@d1zr(e-16%rD_2jIN`0F(m|SplHE z1G<*;zLxP%E&qSj3M3P>b~Uv$)V<*9P!BGFh) z1U(igec#>DpYD*9e+#OFq);$qsxOg1p&I}i_YDm947`ctzZ>xH##Ztr;K&%XFNQ!> z3R2y*5k{#{e0aDeeX9-2s#O&Ls@8%=-Sl%jif&)zi$-Z-iDZ8y)z{Y_iNh$92)MJp z1PT>NKw(S`Lli>%Nm{1@y05uX<{@Ly)g)wA{wr)3Ws`QHJ}It zo{YiM9nr!1_>z1`NHQITH5LG1__&W-|G(o#qV^1xf>eHih8PWOnu=Hil*9bEn~&#Z z(;eO11zm{SSB@^k{=D8DB6!`s<4N6oYDv*p1QKVq-Sjk;H zSlvCVe=@B6?*yWKkQ5(h@R7XKt`lbAK#@h(kvFn0GCgzGjdW_?#bkU1apSNT-W2cS z2oXaO{gsdest=h+@V_U4>AY?Mv*Z{Dh3TElEMB&v@h0|e!pwB=Yk%bN-r5j$)7^RQiJLB)5p=} z0yKe6=zeH25|7vaSu0Zl3QtcDy+*GXZNI{L|GmPyR4Sp7ROGJ$hp&t~PS8GRrPtrl z3LGwIq(8W@Ti_BD5|6`De2^;Ya1;rNw%oP&^|N0S7&sv*?(ib`qLlqNSR+qw`y36j z(Jbbe2+f2nHG_zIpb2}0rl(Kv#nM?hiwU7artEfTR3TkPlBvQ+uy_msNA)=*7!Lpd zkMHLpyO)Ow3jg;B+uH-XMfLUn*{49B{|(od;)^37sexonh~?ipZLhVI|F0Ir&u;wX z?mrHtsyYgRR7E2d;V?K_QOz3zS45(q>WWA;tO{Hmp$>zoBgp$D_xxw0$NWDWg`ckF z|CalIoU(t8`+hl7V=9ST2Sko~(LAbIDDA1Nb{xk{ovJWZrA_D0Kb-RT>G$aW$?vZw z+jr~wH7rY|*U_Pak3VM)WfRV8Y8y2pX?M2-@iI45lDnU}S4~fPn`6jGDv|8zOTZF~ z_Iih?|BpEapP~;K1s6nLDfHICz?7g$P(KO@gL2$IQBhJ;f&u`%i2d%7+wY$Lu+V=M zl-|$0th?>gchLoSppZdE_=pRT9U2W}hDI|a<%56>K%ju$=X~}*+ckUJ8e_JYPcrG^ z9QXlHc4k)jSd$)IMi2;U3KN1JWCl4fvh#EQ!m9wbIcY#gsj&M1#4r8p0odT@go6#} z-x2i5_C?|;U|S-Q3O3M(iVJb6z@Z4J1`MI5st$LhiwL?1hiUGKP{aQo>L^t9XDIOB zLjBxS|A=Tup9}gnhPpucnOXMW0~z-705PzDP68NjoMZQUVI#~WFsRmgvP9F(aQ5x! zP~E24f>7^+Qo&;ks=?^szutH27=fsApOv)EpFa^VsOFG6b^ei=P^-p+^de`dBb1wt zLyU)kVTX|s1Z26e$BmdYBR7oY_MDo~&5h5(Gh1OJ zM}Q5h)(m=>)ru23Mk8Nlq=wcu^>Shyo&%vIPxsL^WVyFlsdC1p3ND*2x%nX#&*F65 zZP!sA#$<(#WG$8IxR4pUE&J0Gt;TExyPMC2EBDvl`+f79f!_@LX5cpizZv+=z;6bA zGw_>%-wga_;5P&R9~t=OthfGhebjEnHK8LrOzvCDX8aOADScIWP&4clZ>?ylvEIhK zUAb4RX4q?fs6!NSr#g^EYCc<%`)uhfpT1+2^dHNf-V^i;*hnTW^q0IG{JS3pz^!ay z`XK|w*7zi#x<_=DE->QsE%gC_yU85ikxcZr2Q*VdeftoG#WQRq(ZQQPJl1_q_01fw z>|jZgc6q*fB*r>?f_<2mGTdluexLRcaoO%*OG+Rn802pLq)b%zev77xY9pKj~Z~M|+4FX4kQZ!0RtPn0F3A1~Ul! zb(|H|FBDr#0zc*U>9$^89MIAe89_ zqki_~>Pjx@r0!b(;6RhfQ41ff9!JlWD*nPb(zA# zy*Q9OUMmr3;myfwoOX=Al+kQ(upAb*Tu^bTvb&VA9F%AUv0$}~4Q{VL?|Q6SOW438 zS?o))>d3e~huHG`JS>X$Yo57-&8_Uj(6Xa)K@U^2QZ9&I=Z`BlV`CT}q`H6Gv{_oz z4|LLy*U~06w}QkiV+g`Gz{Rj&ZdaF>0OoYKE=+uW^~=g&i)bZ{X4tIC9nWgr%?YVe z<$e4*)A4)LT{h*R!3n&vP}f3ZdebSd=>&o1e9=z;ea5O6ub#9%Gjh&SWl}O?Yehaj zCS<^I!NEn2n)m4=gE8b}8Ch>AAdwbcTF3tItlw*c1KL)IBenC--Z%@fIoAJVJAX)`^pONeF%QtHXqcPa*bnwE00RdRR~iMttpX4fcgA~Z-eC>~ zr@4Go&g@(}Dla_#!{C5TJs%|wk77%lJ>6}awzAPq4!RT zc4#Kbqm}2}vl?W5-lg+036M{+EJgI;BFD%^{sk)FHzj$eoG^hEyGcwn4oky*W$b?FE^FZ`qjO zg@~>ske}0fI?nxg+~XI)dNm{35tCh@{ztK&SQp%QTBjT~9SJ9OzSVdf^}m}_o1~Z7 zGDLJwiZ<*|nOEQDdmAZ~*mKxI_}r}mu?_Lz_qXFtiiKjfd^xae*jm(XFZp(zAHydnk|5xh)OrNuNvvcbWa*2OG0#R|oxiqp@>ODbQ@tB$YC&U`&Q z!zH|`{xEj~5yj|wAP3mB62CcODr?{5rtE$K3*s!Kphc(d4Ro{S|3-K}Y3NQHO< zXWt*~xM8hdXI4W!R4$xDAL&lxVt4!?sdD79Dp$mSJNLLntAvB)Evd>O;^UemE4K70 z2=EMbs$a$4J!{EOKQq4YsFgy_A=x4R>>}E=nxusy_SxJC2pNv96$8)c3zP+ zg2J^a14~dPC%v6XO*zV=gtTI*_fEDK^G^Q|WrL_NxQm8(S(V+y_+;dYoi{A+bf#I@ zo=od>P`D(OQ1W6HDxEl}Hr7>sw)#uhcb9DW$@`KHZMOXF52Y51JlkjB4#9q=us#S? zj?Z-5sZ6Rtt|PJJYx((%T!+{O&lLd{!Gm?(nl>4WdJ)ah*#aze=?=v*>{3kvbpbL+ zZgrD1wOXmr!xf0$L34PWv9b1W*OU?$*W%&1cU1dy%{y%ZkF&o+mCGK8ZO!5elz#A$ zKYhA;b7A5WuIlzpz7q1bQ`O^Fp-oS7d4A|VusJ=AciuLg<-e=g^95$u$U-W4a(4w_ z7%tNj6jZn{I8+>03w&_^AqivfyM1Fe#baG5b=~Fdc04#VLOzk2E)`09;qm7{??AyP zZ*9{|O3Kyqdwk+T*j48g`5C(qV;z%E?dNE*a+$;)N^l(U|&w#H`K? z%QeCyL%ePorhO}Nv#Tv1xRhk=k=D0C8w-+38}NUq$>a#Vh4HH1h+Rp`6pp<%*XAXt zmtmOEI9dxdXC!xCxHxsqAbH|~vKp`b6G7X1&D?ekKh6?#g2Y!$wAcPnZumsHW=-fU z;9_~Hg6V&m{qCjShVmt~`ksrbu(CM$zR{_3vF|wj5Qw~!QBCRh<3yxUhZtK~VjtY> z-ifOlc$RTlyAB_xM|hC3%pY}&_;%Xj`D{W&c9G3zJNX0l9)%?^y&zKq$<%4t25%OP zda;T%^6+cg;1yCBNqrCo_?+PI+_iL`-7?Oe2ZwcsOTHfP&uK`s@Wai z)PWwR?$HaKe8}VpX9XF?rB|#U7E8ax2ajl3VUFEMFMBfMMU$O*C|B_$O`2`tb+m2g zrz&s6Y0-$u;_^OF-DtPf=@es*+is=;&q=3xO~=+Jrz65GZn9N;wW-X?yO2k);0on? z_u)^7@^PJSlXILnZ~}XFpCH*kwN>Z#6-zO9QZL3)>LM)K?ugs$6&{ZwrL61im!yHp zYs`aDJf#SOktZ5IknsvZ&1XQeS_3IxHgig%=afIpJiQv+{Q241#5H#1KV7GupD|}) zsW+x|;UmLpb0)_(uFfA=UiUOjb;vEaTlaeB1kFt2vU))sU(@LpmosPA)=nm0W7qil z^~SOHF&{a_f=I8DODqMs4QIMpA35C;y1dh(4XVLsK`3vJ*NSaV^f(^XJ?|AavK5|? zQGQ&?4!`+5le48(n!_BcWiZtY1WiBIP)lf`n5^07@Ujh)8_I4E+5S-=4Xk+haNF9l z_>WWd;|VUOKc-1xrMa@rBnLMlnu+62@;`_#w8!0I@Wp+p{j%-y*2E>TwqsIek}poF z$#oFpZ_(K|actz>_R>{aqhL^!K>`kr;ZB1%`irYh#B<@4oIV!3vm@EL02iWZa*Inv zWivCi^)=E!>tJf(u^E$$_a(Lb59~Zzn$_BN0(pijZu3w-MqWKVv9t{Kn!jF! zQA8CixjG{nPxtq=Il`w>D~euWnIUyAx^6al$+m@|`tpY!otS(=+);TuA2EIEfvD_V zeuxS9T}XwPdnPOT^IsHH(PsNK`7DverL`t9`1qB=J2^sU14{eV z?sr!{%JgptLOPdBvLhUj5>W!{N58azGPkWF0oFMjM0}VW1X6n)KaRphSMg3-G|CQF zzaD#yM_fJ>G#Hwp8Of3Asxb7xDbM)4XC`JXjQ2={(-+O-KI-?F2s46BLmk|t9<2lD z9y}-}dcg6_axl5I?14~n1etmF50T+fqV@{kcLf!JXB8E>DU#n`N4vpK0iDQ&ga$`< zYIXAZ^eRubj*(FsZTnDBw^S(a)@-+YQ%|si%Zl<9xF#k-C4C@;!^yVL!Ta-;f3c$Z z*`bRCuM zPANsXktxg0o4}W5;&Pc}kxQo=jNuyONDnpN{L1NrHP=hjk8psdf&*e##=DYN++T%~ zMemBtNL)Amq3PK2sF-oRNB&gqe7rn-`o5S0bdIM>P*p9`!q(LfzQvif_B6%AUdn>0 z&pdxpvE)KXlP0`~bAVTy_D0t{=xYBxAC*MtYj}0K)p8MI76(Ud$()OQ*ak>~a$t~MsFfRwx8LgmE+CHDf6D1o{1292? zZ>+Oo-6*%cV&5ep5(4F`U#g`&*s(K64|ksrl7Q7*Z zOTb`=AP()NPx>fEfW06!qlfudJpRz=-^)pS?1%?B|Cf!>~0yiuyT zmhM^6c5BKQGp(wohq)y~$}H?9mCwd!vsiah8souk1F;HDVxc;wiUC5Ly#umPHox&h z5wEXzuViF0{{W@4^1O5)9qwhY`(!JT+3#kx|KBo*(ah~mWsX#U8l!AMtGCtclb);3 zY~@5`OgWj5WL31%Y*$=kNA$J0#zQSftk<+>oh>duaZiNaj<|8+RK9LvfYrK;!1sA> zQ4var&`L5NClgLVS8FgSQDk-yIC5`1VT~dT7Lm2m>*t0XS6ayH*f=qKpbor^bZg&z Pk7H_NWmtXEEBb!`6vB33 literal 0 HcmV?d00001 diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json index a19a549..221b732 100644 --- a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/Contents.json @@ -2,7 +2,8 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" + "scale" : "1x", + "filename" : "scanToPayAppInstapay.png" }, { "idiom" : "universal", diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/scanToPayAppInstapay.png b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppInstapay.imageset/scanToPayAppInstapay.png new file mode 100644 index 0000000000000000000000000000000000000000..5c515b789b7b84dc513d74d6bd7a386c5de3841f GIT binary patch literal 10433 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 Xt?Q1dIimUZUs9Tz*dXs4c}D#Y^WVaN literal 0 HcmV?d00001 diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json index a19a549..fce9710 100644 --- a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json +++ b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/Contents.json @@ -2,7 +2,8 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" + "scale" : "1x", + "filename" : "scanToPayAppTelkomPay.png" }, { "idiom" : "universal", diff --git a/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/scanToPayAppTelkomPay.png b/Sources/PaystackUI/Images/Images.xcassets/ScanToPayApps/scanToPayAppTelkomPay.imageset/scanToPayAppTelkomPay.png new file mode 100644 index 0000000000000000000000000000000000000000..80952bf7fc880f67335d5a019cceba172f6d587f GIT binary patch literal 12180 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 YudS5Zb-*l`^$XV8+}`Y}iC^r00rVyk9RL6T literal 0 HcmV?d00001 diff --git a/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift b/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift index 3c86201..84de5f0 100644 --- a/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift +++ b/Tests/PaystackSDKTests/UI/Charge/QR/ScanToPayAppDirectoryTests.swift @@ -1,4 +1,7 @@ import XCTest +#if canImport(UIKit) +import UIKit +#endif @testable import PaystackUI final class ScanToPayAppDirectoryTests: XCTestCase { @@ -36,6 +39,15 @@ final class ScanToPayAppDirectoryTests: XCTestCase { } } + #if canImport(UIKit) + func testEveryAppIconLoadsFromTheBundle() { + for app in ScanToPayAppDirectory.apps { + XCTAssertNotNil(UIImage(named: app.iconAsset, in: .current, compatibleWith: nil), + "Missing icon image for \(app.name) (\(app.iconAsset))") + } + } + #endif + func testFNBPayAndRMBUseFNBDeeplink() { XCTAssertEqual(styles(named: ["FNB Pay", "RMB"]), [.fnb, .fnb]) }