diff --git a/FuelBoard/ProximityMonitor.swift b/FuelBoard/ProximityMonitor.swift index 859eed7..1f7e8b1 100644 --- a/FuelBoard/ProximityMonitor.swift +++ b/FuelBoard/ProximityMonitor.swift @@ -41,6 +41,9 @@ struct TieChoice { /// /// Region budget: iOS allows 20 monitored regions per app — favourites are /// always registered first, then the closest remaining stations fill the rest. +/// Each region is a circle around a station with radius = the alert radius +/// (clamped to the device ceiling), so the notification fires on APPROACH — +/// entering the winner's circle — not at the forecourt. @MainActor final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLocationManagerDelegate, UNUserNotificationCenterDelegate { @Published var monitoredStationIDs: [String] = [] @@ -117,10 +120,17 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca candidates.append(contentsOf: others) var registered: [String] = [] + // Trigger radius = the ALERT radius (approach heads-up), not a tiny + // forecourt fence: entering the winner's region means you're within + // the alert radius of it, and the notification fires as you approach. + // Clamp to the device's region-monitoring ceiling — registering a + // larger region fails (kCLErrorRegionMonitoringFailure) or is reduced. + let maxRegion = manager.maximumRegionMonitoringDistance + let triggerRadius = maxRegion > 0 ? min(radiusKM * 1000, maxRegion) : radiusKM * 1000 for station in candidates.prefix(18) where station.prices[fuel] != nil { let region = CLCircularRegion( center: CLLocationCoordinate2D(latitude: station.lat, longitude: station.lng), - radius: 300, + radius: triggerRadius, identifier: station.id ) region.notifyOnEntry = true