Delete Speedo/LocationManager.swift
This commit is contained in:
1 parent
11cb865d5e
commit
dae80366ab
1 file changed
-156
@@ -1,156 +0,0 @@
|
|||||||
//
|
|
||||||
// LocationManager.swift
|
|
||||||
// Speedometer
|
|
||||||
//
|
|
||||||
// Created by Justin Oros on 5/2/2025.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import CoreLocation
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
/// A class responsible for managing and publishing location and speed updates.
|
|
||||||
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
|
||||||
|
|
||||||
/// The underlying Core Location manager instance.
|
|
||||||
private let manager = CLLocationManager()
|
|
||||||
|
|
||||||
// MARK: - Published Properties (UI-bound)
|
|
||||||
|
|
||||||
/// Current speed in MPH (calculated from CLLocation speed).
|
|
||||||
@Published var speed: Int = 0
|
|
||||||
|
|
||||||
/// Most recent known location.
|
|
||||||
@Published var location: CLLocation?
|
|
||||||
|
|
||||||
/// Horizontal accuracy in meters.
|
|
||||||
@Published var accuracy: Double = 0.0
|
|
||||||
|
|
||||||
/// Current authorization status.
|
|
||||||
@Published var authorizationStatus: CLAuthorizationStatus = .notDetermined
|
|
||||||
|
|
||||||
/// Flag to show alert when location permissions are problematic.
|
|
||||||
@Published var showAlert = false
|
|
||||||
|
|
||||||
/// Message to display in the alert.
|
|
||||||
@Published var alertMessage = ""
|
|
||||||
|
|
||||||
// MARK: - Initialization
|
|
||||||
|
|
||||||
override init() {
|
|
||||||
super.init()
|
|
||||||
manager.delegate = self
|
|
||||||
manager.activityType = .automotiveNavigation
|
|
||||||
manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
|
|
||||||
manager.distanceFilter = 1 // Update for every meter moved
|
|
||||||
|
|
||||||
print("LocationManager initialized")
|
|
||||||
|
|
||||||
requestAuthorization()
|
|
||||||
startUpdatingLocationIfNeeded()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Authorization
|
|
||||||
|
|
||||||
/// Requests location permission from the user.
|
|
||||||
private func requestAuthorization() {
|
|
||||||
print("Requesting location authorization")
|
|
||||||
manager.requestWhenInUseAuthorization()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts updating location only if authorization is granted.
|
|
||||||
private func startUpdatingLocationIfNeeded() {
|
|
||||||
if authorizationStatus == .authorizedAlways || authorizationStatus == .authorizedWhenInUse {
|
|
||||||
print("Attempting to start location updates")
|
|
||||||
manager.startUpdatingLocation()
|
|
||||||
} else if authorizationStatus == .denied || authorizationStatus == .restricted {
|
|
||||||
print("Location updates not started due to denied/restricted authorization")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.showAlert = true
|
|
||||||
self.alertMessage = "Location services are disabled. Please enable them in Settings."
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Authorization not yet determined: \(authorizationStatus.rawValue)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called whenever the app's location authorization status changes.
|
|
||||||
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
|
||||||
let status = manager.authorizationStatus
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.authorizationStatus = status
|
|
||||||
print("Authorization status changed: \(status.rawValue)")
|
|
||||||
self.startUpdatingLocationIfNeeded()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle alert messaging for denied or restricted access
|
|
||||||
switch status {
|
|
||||||
case .authorizedAlways:
|
|
||||||
print("Location authorization: Authorized Always")
|
|
||||||
case .authorizedWhenInUse:
|
|
||||||
print("Location authorization: Authorized When In Use")
|
|
||||||
case .denied:
|
|
||||||
print("Location authorization: Denied")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.showAlert = true
|
|
||||||
self.alertMessage = "Location access was denied. Please enable it in Settings for the app to function correctly."
|
|
||||||
}
|
|
||||||
case .restricted:
|
|
||||||
print("Location authorization: Restricted")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.showAlert = true
|
|
||||||
self.alertMessage = "Location access is restricted. This might be due to parental controls or system settings."
|
|
||||||
}
|
|
||||||
case .notDetermined:
|
|
||||||
print("Location authorization: Not Determined")
|
|
||||||
@unknown default:
|
|
||||||
print("Location authorization: Unknown status")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Location Updates
|
|
||||||
|
|
||||||
/// Called whenever new location data is available.
|
|
||||||
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
|
||||||
guard let latest = locations.last else {
|
|
||||||
print("No latest location found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip updates if accuracy is too poor (≥ 20 meters)
|
|
||||||
guard latest.horizontalAccuracy >= 0 && latest.horizontalAccuracy < 20 else {
|
|
||||||
print("Skipping update due to poor accuracy: \(latest.horizontalAccuracy)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging raw location data for debugging
|
|
||||||
print("New location: \(latest.coordinate.latitude), \(latest.coordinate.longitude)")
|
|
||||||
print("Speed (m/s): \(latest.speed)")
|
|
||||||
print("Accuracy: \(latest.horizontalAccuracy)")
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
// Ensure speed is non-negative
|
|
||||||
let rawSpeed = max(latest.speed, 0)
|
|
||||||
|
|
||||||
// Ignore very small fluctuations when stopped (less than 0.5 m/s)
|
|
||||||
let filteredSpeed = rawSpeed < 0.5 ? 0 : rawSpeed
|
|
||||||
|
|
||||||
// Convert from m/s to MPH
|
|
||||||
let mph = filteredSpeed * 2.23694
|
|
||||||
|
|
||||||
// Update UI-bound values
|
|
||||||
self.speed = Int(mph.rounded())
|
|
||||||
self.location = latest
|
|
||||||
self.accuracy = latest.horizontalAccuracy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called when location updates fail.
|
|
||||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
|
||||||
print("Location update failed: \(error.localizedDescription)")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.showAlert = true
|
|
||||||
self.alertMessage = "Location update failed: \(error.localizedDescription)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user