I\'ve prepared in my project the following class to retrieve the user current location:
LocationManager.swift
import Foundation
import CoreLocation
class Loca
You could create an ObservedObject
of your LocationManager
by implementing the ObservableObject
protocol.
With the @Published
attribute you can create a publisher object which notify the observers (your view, in this case) when something changes inside that object.
That's why in my LocationManager I added the @Published
attribute to those var:
locationStatus: CLAuthorizationStatus?
it contains the value received from didChangeAuthorization
delegate methodlastLocation: CLLocation?
it contains the last location calculated by the didUpdateLocations
delegate methodimport Foundation
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject {
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
@Published var locationStatus: CLAuthorizationStatus? {
willSet {
objectWillChange.send()
}
}
@Published var lastLocation: CLLocation? {
willSet {
objectWillChange.send()
}
}
var statusString: String {
guard let status = locationStatus else {
return "unknown"
}
switch status {
case .notDetermined: return "notDetermined"
case .authorizedWhenInUse: return "authorizedWhenInUse"
case .authorizedAlways: return "authorizedAlways"
case .restricted: return "restricted"
case .denied: return "denied"
default: return "unknown"
}
}
let objectWillChange = PassthroughSubject()
private let locationManager = CLLocationManager()
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.locationStatus = status
print(#function, statusString)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.lastLocation = location
print(#function, location)
}
}
In your view you need to create only an instance of LocationManager
marked as @ObservedObject
import SwiftUI
struct MyView: View {
@ObservedObject var locationManager = LocationManager()
var userLatitude: String {
return "\(locationManager.lastLocation?.coordinate.latitude ?? 0)"
}
var userLongitude: String {
return "\(locationManager.lastLocation?.coordinate.longitude ?? 0)"
}
var body: some View {
VStack {
Text("location status: \(locationManager.statusString)")
HStack {
Text("latitude: \(userLatitude)")
Text("longitude: \(userLongitude)")
}
}
}
}
struct MyView_Previews: PreviewProvider {
static var previews: some View {
MyView()
}
}