Created
May 24, 2024 19:45
-
-
Save peterkos/e88175592bda4fad43c46622b3f30786 to your computer and use it in GitHub Desktop.
quantom computin'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreLocation | |
import Foundation | |
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { | |
static let shared: LocationManager = .init() | |
@Published var userCoordinates: UserCoordinates? | |
private let clLocationManager = CLLocationManager() | |
@Published var locationPermissions: LocationPermissionStatus = .unknown | |
override init() { | |
super.init() | |
clLocationManager.delegate = self | |
// Save a bit of power | |
clLocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters | |
CoolLogger.Location.debug("Authorization state: \(self.clLocationManager.authorizationStatus.rawValue)") | |
} | |
func startMonitoringLocationWithRequest() { | |
guard locationPermissions.isGranted else { | |
CoolLogger.Location.error("Unable to get user location: not authorized. Requesting...") | |
clLocationManager.requestWhenInUseAuthorization() | |
return | |
} | |
clLocationManager.startUpdatingLocation() | |
CoolLogger.Location.info("Started monitoring location") | |
} | |
func startMonitoringLocationIfAuthorized() { | |
if locationPermissions.isGranted { | |
clLocationManager.startUpdatingLocation() | |
CoolLogger.Location.info("Started monitoring (already authorized)") | |
} | |
} | |
func stopMonitoringLocation() { | |
clLocationManager.stopUpdatingLocation() | |
CoolLogger.Location.info("Stopped monitoring location") | |
} | |
} | |
// MARK: CLLocationManagerDelegate | |
extension LocationManager { | |
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { | |
CoolLogger.Location.debug("Location auth status changed: \(manager.authorizationStatus.rawValue)") | |
locationPermissions = switch clLocationManager.authorizationStatus { | |
case .authorizedAlways, .authorizedWhenInUse: .granted | |
case .notDetermined: .unknown | |
default: .denied | |
} | |
if locationPermissions.isGranted { | |
clLocationManager.startUpdatingLocation() | |
CoolLogger.Location.info("Authorized. Started monitoring location.") | |
} | |
} | |
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) { | |
guard let latestLocation = locations.last else { | |
CoolLogger.Location.error("Location data not found in update.") | |
return | |
} | |
let latitude = latestLocation.coordinate.latitude | |
let longitude = latestLocation.coordinate.longitude | |
Task { @MainActor in | |
userCoordinates = UserCoordinates( | |
latitude: latitude, | |
longitude: longitude | |
) | |
} | |
} | |
func locationManager(_: CLLocationManager, didFailWithError error: any Error) { | |
CoolLogger.Location.error("Failed to get location with error: \(error.localizedDescription)") | |
} | |
} | |
extension LocationManager { | |
/// A little abstraction to simplify cases | |
enum LocationPermissionStatus: String { | |
case granted | |
case denied | |
case unknown | |
var isGranted: Bool { | |
self == .granted | |
} | |
var description: String { | |
rawValue.capitalized | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment