Skip to content

Instantly share code, notes, and snippets.

@peterkos
Created May 24, 2024 19:45
Show Gist options
  • Save peterkos/e88175592bda4fad43c46622b3f30786 to your computer and use it in GitHub Desktop.
Save peterkos/e88175592bda4fad43c46622b3f30786 to your computer and use it in GitHub Desktop.
quantom computin'
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