Alerts: trigger on approach — geofence radius = alert radius
- Region radius changed from fixed 300 m forecourt fence to the alert radius (the Alerts-tab slider), clamped to the device's maximumRegionMonitoringDistance. - Notification now fires when you ENTER the winner's circle while approaching, not when you reach the forecourt. - Cheapest-gate unchanged: still only fires when the entered station is the cheapest within the alert radius (fresh prices). Dedup still 1/ station/hour. 35 tests pass.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user