Live location tracking: continuous foreground updates (250m filter) + significant-change background monitoring; list/widget refresh and geofences follow the user, re-fetch on every move
This commit is contained in:
@@ -96,7 +96,7 @@ struct ContentView: View {
|
||||
.tabItem { Label("Alerts", systemImage: "bell.fill") }
|
||||
}
|
||||
.onAppear {
|
||||
locationManager.requestUpdate()
|
||||
locationManager.startForegroundTracking()
|
||||
monitor.update(stations: stations, favourites: refreshedFavourites,
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
monitor.setEnabled(alertsEnabled)
|
||||
@@ -104,10 +104,12 @@ struct ContentView: View {
|
||||
}
|
||||
.onChange(of: scenePhase) { _, newPhase in
|
||||
if newPhase == .active {
|
||||
locationManager.requestUpdate()
|
||||
locationManager.startForegroundTracking()
|
||||
monitor.update(stations: stations, favourites: refreshedFavourites,
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
Task { await refresh() }
|
||||
} else {
|
||||
locationManager.stopForegroundTracking()
|
||||
}
|
||||
}
|
||||
.onChange(of: locationManager.current) { _, newLocation in
|
||||
@@ -123,6 +125,9 @@ struct ContentView: View {
|
||||
monitor.setEnabled(newValue)
|
||||
monitor.update(stations: stations, favourites: refreshedFavourites,
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
if newValue {
|
||||
locationManager.startBackgroundTracking()
|
||||
}
|
||||
}
|
||||
.onChange(of: alertsRadius) { _, newValue in
|
||||
FuelStore.saveAlertsRadius(newValue)
|
||||
@@ -284,15 +289,48 @@ final class LocationManager: NSObject, ObservableObject, @preconcurrency CLLocat
|
||||
super.init()
|
||||
manager.delegate = self
|
||||
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
||||
manager.distanceFilter = 250 // metres — re-fires while driving
|
||||
manager.pausesLocationUpdatesAutomatically = true
|
||||
}
|
||||
|
||||
func requestUpdate() {
|
||||
/// Continuous tracking while the app is in the foreground, so the list
|
||||
/// re-fetches around the user's new position as they drive.
|
||||
func startForegroundTracking() {
|
||||
switch manager.authorizationStatus {
|
||||
case .notDetermined:
|
||||
manager.requestWhenInUseAuthorization()
|
||||
manager.requestLocation()
|
||||
case .authorizedWhenInUse, .authorizedAlways:
|
||||
manager.requestLocation()
|
||||
manager.startUpdatingLocation()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/// One-shot fix (first launch / after permission grant).
|
||||
func requestUpdate() {
|
||||
manager.requestLocation()
|
||||
}
|
||||
|
||||
/// Background wake-ups on significant movement. Needs Always permission;
|
||||
/// called once the user enables alerts so geofences + prices follow them.
|
||||
func startBackgroundTracking() {
|
||||
guard manager.authorizationStatus == .authorizedAlways else { return }
|
||||
manager.startMonitoringSignificantLocationChanges()
|
||||
}
|
||||
|
||||
func stopForegroundTracking() {
|
||||
// Significant-change monitoring keeps running in the background.
|
||||
manager.stopUpdatingLocation()
|
||||
}
|
||||
|
||||
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
||||
switch manager.authorizationStatus {
|
||||
case .authorizedAlways:
|
||||
manager.startMonitoringSignificantLocationChanges()
|
||||
manager.startUpdatingLocation()
|
||||
case .authorizedWhenInUse:
|
||||
manager.startUpdatingLocation()
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user