taler-ios

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

commit 2dfb94bc72453507ab93d4bd93bfc1542ee28246
parent 16bf2defc7ec4ddd9433d84cd1e6a204c765bcac
Author: Marc Stibane <marc@taler.net>
Date:   Sat, 18 Apr 2026 08:13:45 +0200

Notifications for Taler Nightly

Diffstat:
MTalerWallet1/Views/Settings/SettingsView.swift | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 94 insertions(+), 13 deletions(-)

diff --git a/TalerWallet1/Views/Settings/SettingsView.swift b/TalerWallet1/Views/Settings/SettingsView.swift @@ -30,23 +30,88 @@ struct SettingsView: View { @AppStorage("pushNotifications") var pushNotifications: Bool = false @State private var listID = UUID() + @State private var mayNotUsePush: Bool = false + @State private var registerState: Bool = false + + var isRegistered: Bool { + UIApplication.shared.isRegisteredForRemoteNotifications + } + + func checkRegisterState(delaySeconds: Double) { + // update isRegistered ==> icon shown + DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) { + registerState = isRegistered + } + } + + private var dismissAlertButton: some View { + Button("Cancel", role: .cancel) { + pushNotifications = false + mayNotUsePush = false + } + } + + func checkPushNotifications(_ shouldUsePush: Bool) { +#if TALER_NIGHTLY + // 1. Request authorisation for remote (push) notifications. + // For background-only (silent) pushes the alert/badge/sound + // entitlements are not strictly required, but requesting them + // avoids surprises when you later add user-visible notifications. + DispatchQueue.main.async { + if isRegistered { + registerState = true + if shouldUsePush { + self.symLog.log("already registered for remote notifications") + } else { + self.symLog.log("unregisterForRemoteNotifications") + UIApplication.shared.unregisterForRemoteNotifications() + controller.deviceTokenAPNs = nil // TODO: tell walletCore + checkRegisterState(delaySeconds: 0.5) + } + } else { + registerState = false + if !shouldUsePush { + self.symLog.log("remote notifications are disabled") + } else { + UNUserNotificationCenter.current().requestAuthorization( + options: [.alert, .badge, .sound] + ) { granted, error in + DispatchQueue.main.async { + if granted { + self.symLog.log("registerForRemoteNotifications") + /// result in didRegisterForRemoteNotificationsWithDeviceToken + UIApplication.shared.registerForRemoteNotifications() + checkRegisterState(delaySeconds: 0.5) + } else { + self.symLog.log("Error requesting notification permissions: \(error?.localizedDescription ?? "unknown")") + mayNotUsePush = true + registerState = false + pushNotifications = false + } + } + } + } + } + } +#endif + + } + var body: some View { #if PRINT_CHANGES let _ = Self._printChanges() let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear #endif - let walletCore = WalletCore.shared - Group { - List { #if TALER_WALLET - let appName = "Taler Wallet" + let appName = "Taler Wallet" #elseif TALER_NIGHTLY - let appName = "Taler Nightly" + let appName = "Taler Nightly" #else - let appName = "GNU Taler" + let appName = "GNU Taler" #endif - let localizedAppName = Bundle.main.bundleName ?? appName + let localizedAppName = Bundle.main.bundleName ?? appName + let list = List { let aboutStr = String(localized: "About \(localizedAppName)") NavigationLink { // whole row like in a tableView AboutView(stack: stack.push(), navTitle: aboutStr) @@ -92,6 +157,15 @@ struct SettingsView: View { // biometricService.isAuthenticated = false } +#if TALER_NIGHTLY + SettingsToggle(name: String(localized: "Push Notifications"), value: $pushNotifications, + id1: "pushNotifications", + imageName: registerState ? NOTIFICATION2 : NOTIFICATION1, // 􀝖 or 􀋙 + description: String(localized: "Check pending payments in the background") + ) { newVal in + checkPushNotifications(newVal) + } +#endif SettingsToggle(name: String(localized: "Minimalistic"), value: $minimalistic, id1: "minimal", imageName: "heart", // 􀊴 description: String(localized: "Omit text where possible")) @@ -142,15 +216,22 @@ struct SettingsView: View { imageName: "ellipsis", // 􀍠 description: nil) {} } - } + } .padding(.bottom) .id(listID) .listStyle(myListStyle.style).anyView - } - .navigationTitle(navTitle) - .onAppear() { - DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push()) - } + + list + .navigationTitle(navTitle) + .onAppear() { + DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push()) + registerState = isRegistered + } + .alert("Push Notifications are disabled", + isPresented: $mayNotUsePush, + actions: { dismissAlertButton }, + message: { Text("Please go to Settings > \(localizedAppName) > Notifications and turn them on.") } + ) } // body } // MARK: -