0.10.6
This commit is contained in:
commit
92660a4ba0
228 files changed
+24496
No files matched your search
@@ -0,0 +1,94 @@
|
||||
import CoreLocation
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
@MainActor
|
||||
final class LocationProvider: NSObject, ObservableObject {
|
||||
@Published private(set) var location: CLLocation?
|
||||
@Published private(set) var authorizationStatus: CLAuthorizationStatus
|
||||
@Published private(set) var errorMessage: String?
|
||||
@Published private(set) var isLocating = false
|
||||
|
||||
private let manager: CLLocationManager
|
||||
|
||||
override init() {
|
||||
let manager = CLLocationManager()
|
||||
self.manager = manager
|
||||
authorizationStatus = manager.authorizationStatus
|
||||
super.init()
|
||||
manager.delegate = self
|
||||
manager.desiredAccuracy = kCLLocationAccuracyBest
|
||||
}
|
||||
|
||||
func requestCurrentLocation() {
|
||||
errorMessage = nil
|
||||
switch manager.authorizationStatus {
|
||||
case .notDetermined:
|
||||
isLocating = true
|
||||
manager.requestWhenInUseAuthorization()
|
||||
case .authorizedAlways, .authorizedWhenInUse:
|
||||
isLocating = true
|
||||
manager.requestLocation()
|
||||
case .denied, .restricted:
|
||||
isLocating = false
|
||||
errorMessage = "Доступ к геопозиции выключен. Можно выбрать точку на карте вручную."
|
||||
@unknown default:
|
||||
isLocating = false
|
||||
errorMessage = "Не удалось определить статус доступа к геопозиции."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension LocationProvider: CLLocationManagerDelegate {
|
||||
nonisolated func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
||||
let status = manager.authorizationStatus
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self else { return }
|
||||
authorizationStatus = status
|
||||
switch status {
|
||||
case .authorizedAlways, .authorizedWhenInUse:
|
||||
isLocating = true
|
||||
self.manager.requestLocation()
|
||||
case .denied, .restricted:
|
||||
isLocating = false
|
||||
errorMessage = "Доступ к геопозиции выключен. Можно выбрать точку на карте вручную."
|
||||
case .notDetermined:
|
||||
break
|
||||
@unknown default:
|
||||
isLocating = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func locationManager(
|
||||
_ manager: CLLocationManager,
|
||||
didUpdateLocations locations: [CLLocation]
|
||||
) {
|
||||
guard let newest = locations.last else { return }
|
||||
let latitude = newest.coordinate.latitude
|
||||
let longitude = newest.coordinate.longitude
|
||||
let altitude = newest.altitude
|
||||
let horizontalAccuracy = newest.horizontalAccuracy
|
||||
let verticalAccuracy = newest.verticalAccuracy
|
||||
let timestamp = newest.timestamp
|
||||
Task { @MainActor [weak self] in
|
||||
self?.location = CLLocation(
|
||||
coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude),
|
||||
altitude: altitude,
|
||||
horizontalAccuracy: horizontalAccuracy,
|
||||
verticalAccuracy: verticalAccuracy,
|
||||
timestamp: timestamp
|
||||
)
|
||||
self?.isLocating = false
|
||||
self?.errorMessage = nil
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||
let description = error.localizedDescription
|
||||
Task { @MainActor [weak self] in
|
||||
self?.isLocating = false
|
||||
self?.errorMessage = "Не удалось получить текущую геопозицию: \(description)"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user