taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 25615038b269b152bfab288fa1cf647a9fe2a7d4
parent 68c8a57b62783a029f0c4d82473b31c36faa48d0
Author: Marc Stibane <marc@taler.net>
Date:   Sat, 31 May 2025 20:45:39 +0200

BorderWithNFC

Diffstat:
MTalerWallet1/Helper/TagEmulation.swift | 9+++++----
MTalerWallet1/Views/HelperViews/GradientBorder.swift | 37+++++++++++++++++++++++++++++++++++++
MTalerWallet1/Views/HelperViews/QRCodeDetailView.swift | 37+++----------------------------------
MTalerWallet1/Views/HelperViews/QRGeneratorView.swift | 10++++++----
MTalerWallet1/Views/Transactions/QRcodesForPayto.swift | 3++-
5 files changed, 53 insertions(+), 43 deletions(-)

diff --git a/TalerWallet1/Helper/TagEmulation.swift b/TalerWallet1/Helper/TagEmulation.swift @@ -11,7 +11,7 @@ import os.log @available(iOS 18.3, *) @MainActor class TagEmulation: ObservableObject { - + public static let shared = TagEmulation() @Published var canUseHCE: Bool = false nonisolated let logger = Logger(subsystem: "net.taler.gnu", category: "TagEmulation") @@ -68,8 +68,12 @@ class TagEmulation: ObservableObject { logger.info("starting eventStream") try await eventStream(cardSession, data: emulatedData) logger.info("eventStream finished") + + logger.info("cardSession.invalidate") + await cardSession.invalidate() result = true } + cardSession = nil } catch let error { // Handle failure to acquire NFC presentment intent assertion or card session. logger.error("❗️NFCPresentmentIntentAssertion not possible: \(error.localizedDescription)") @@ -82,9 +86,6 @@ class TagEmulation: ObservableObject { func killEmulation() { Task() { if let session = cardSession { - if await session.isEmulationInProgress { - logger.info("cardSession.invalidate") - } await session.invalidate() cardSession = nil } diff --git a/TalerWallet1/Views/HelperViews/GradientBorder.swift b/TalerWallet1/Views/HelperViews/GradientBorder.swift @@ -24,6 +24,43 @@ */ import SwiftUI +@available(iOS 18.3, *) +struct BorderWithNFC<Content: View>: View { + let talerURI: String + let size: CGFloat + var content: () -> Content + + @AppStorage("minimalistic") var minimalistic: Bool = false + @StateObject private var tagEmulation = TagEmulation.shared + + var body: some View { + let _ = Self._printChanges() + if tagEmulation.canUseHCE { + VStack { + if !minimalistic { + Text("Tap for NFC:") + .talerFont(.subheadline) + .padding(.vertical, -4) + } + let screenWidth = UIScreen.screenWidth + GradientBorder(size: size + 20.0, + color: .accentColor, + background: WalletColors().backgroundColor) + { + content() + .onTapGesture { + tagEmulation.emulateTag(talerURI) + } + } + }.onDisappear() { + tagEmulation.killEmulation() + } + } else { + content() + } + } +} +// MARK: - // Use radius: 0 for rect instead of rounded rect struct GradientBorder<Content: View>: View { let size: CGFloat diff --git a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift @@ -9,38 +9,6 @@ import SwiftUI import taler_swift import AVFoundation -@available(iOS 18.3, *) -struct QRCodewithNFC<Content: View>: View { - let talerURI: String - var content: () -> Content - - @AppStorage("minimalistic") var minimalistic: Bool = false - @StateObject private var tagEmulation = TagEmulation() - - var body: some View { - if tagEmulation.canUseHCE { - if !minimalistic { - Text("Tap QR for NFC:") - } - let screenWidth = UIScreen.screenWidth - GradientBorder(size: screenWidth/1.8, - color: .accentColor, - background: WalletColors().backgroundColor) - { - content() - .onTapGesture { - tagEmulation.emulateTag(talerURI) - } - } - .onDisappear() { - tagEmulation.killEmulation() - } - } else { - content() - } - } -} - struct QRCodeDetailView: View { let talerURI: String let talerCopyShare: String @@ -90,12 +58,13 @@ struct QRCodeDetailView: View { var body: some View { if talerURI.count > 10 { Section { - let qrView = QRGeneratorView(text: talerURI) + let size = 240.0 + let qrView = QRGeneratorView(text: talerURI, size: size) .frame(maxWidth: .infinity, alignment: .center) Group { #if TALER_NIGHTLY || GNU_TALER if #available(iOS 18.3, *) { - QRCodewithNFC(talerURI: talerURI) { + BorderWithNFC(talerURI: talerURI, size: size) { qrView } } else { diff --git a/TalerWallet1/Views/HelperViews/QRGeneratorView.swift b/TalerWallet1/Views/HelperViews/QRGeneratorView.swift @@ -22,7 +22,8 @@ import SwiftUI struct QRGeneratorView: View { - var text: String + let text: String + let size: CGFloat var body: some View { if let data = getQRCodeData(text: text) { @@ -31,7 +32,7 @@ struct QRGeneratorView: View { .interpolation(.none) .resizable() .scaledToFit() - .frame(width: 200, height: 200) + .frame(width: size, height: size) } else { EmptyView() } @@ -55,8 +56,9 @@ struct QRGeneratorView: View { struct QRGeneratorView_Previews: PreviewProvider { static var previews: some View { VStack { - QRGeneratorView(text: "Hello World!") - QRGeneratorView(text: "taler://pay-pull/exchange.demo.taler.net/7J7SNHYMCCAZ1ARY9YCB5Z9FTY0YZP8F2KDRXV94KZCQ6WAVMTX0") + QRGeneratorView(text: "Hello World!", size: 200) + QRGeneratorView(text: "taler://pay-pull/exchange.demo.taler.net/7J7SNHYMCCAZ1ARY9YCB5Z9FTY0YZP8F2KDRXV94KZCQ6WAVMTX0", + size: 200) } } } diff --git a/TalerWallet1/Views/Transactions/QRcodesForPayto.swift b/TalerWallet1/Views/Transactions/QRcodesForPayto.swift @@ -23,8 +23,9 @@ struct QRcodesForPayto: View { .listRowSeparator(.hidden) } ForEach(qrCodeSpecs, id: \.self) { spec in + let size = 200.0 Text(spec.type) - QRGeneratorView(text: spec.qrContent) + QRGeneratorView(text: spec.qrContent, size: size) .frame(maxWidth: .infinity, alignment: .center) .accessibilityLabel(Text("QR Code", comment: "a11y")) .listRowSeparator(.hidden)