Settings: plain test notification + foreground banner delegate
- New 'Send plain test notification' button fires with zero criteria checks (no geofence, no cheapest check, no permission gate) to isolate delivery and tap behaviour - ProximityMonitor is now the UNUserNotificationCenter delegate: banners show even in the foreground (system suppresses them otherwise), and taps complete the 'open FuelBoard' action
This commit is contained in:
@@ -8,7 +8,7 @@ import SwiftUI
|
||||
/// Region budget: iOS allows 20 monitored regions per app — favourites are
|
||||
/// always registered first, then the closest remaining stations fill the rest.
|
||||
@MainActor
|
||||
final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLocationManagerDelegate {
|
||||
final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLocationManagerDelegate, UNUserNotificationCenterDelegate {
|
||||
@Published var monitoredStationIDs: [String] = []
|
||||
@Published var lastAlert: String?
|
||||
|
||||
@@ -25,6 +25,9 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca
|
||||
manager.delegate = self
|
||||
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
||||
manager.pausesLocationUpdatesAutomatically = true
|
||||
// Show alert banners even while the app is open, and complete the tap
|
||||
// action (opening FuelBoard) when the user taps a notification.
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
// Restore persisted state on background relaunch so region events work
|
||||
// even before the view fully appears.
|
||||
enabled = FuelStore.loadAlertsEnabled()
|
||||
@@ -187,4 +190,43 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca
|
||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
|
||||
UNUserNotificationCenter.current().add(request)
|
||||
}
|
||||
|
||||
/// Fires a notification with NO criteria checks at all — no geofence, no
|
||||
/// cheapest-within-radius, no dedup, no permission gate, no fuel/radius
|
||||
/// coupling. Purely tests "does a notification appear, and does tapping
|
||||
/// it open the app". If notifications are denied system-wide nothing can
|
||||
/// display, but this fires regardless of every FuelBoard condition.
|
||||
static func sendPlainTestNotification() {
|
||||
let content = UNMutableNotificationContent()
|
||||
content.title = "FuelBoard test notification"
|
||||
content.body = "This is a plain test alert — no criteria were checked. Tap to open FuelBoard."
|
||||
content.sound = .default
|
||||
|
||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
|
||||
UNUserNotificationCenter.current().add(request)
|
||||
}
|
||||
|
||||
// MARK: - Notification presentation + tap
|
||||
|
||||
/// Show alert banners even while FuelBoard is in the foreground — without
|
||||
/// this, the system silently suppresses notifications when the app is open.
|
||||
nonisolated func userNotificationCenter(
|
||||
_ center: UNUserNotificationCenter,
|
||||
willPresent notification: UNNotification,
|
||||
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
|
||||
) {
|
||||
Task { @MainActor in
|
||||
completionHandler([.banner, .sound])
|
||||
}
|
||||
}
|
||||
|
||||
/// Tapping a notification just opens the app (the alert's "Tap to open").
|
||||
/// No extra routing — the app comes to the foreground as-is.
|
||||
nonisolated func userNotificationCenter(
|
||||
_ center: UNUserNotificationCenter,
|
||||
didReceive response: UNNotificationResponse,
|
||||
withCompletionHandler completionHandler: @escaping () -> Void
|
||||
) {
|
||||
completionHandler()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user