I’m a beginner, trying to get the latitude and longitude from LocationManager and show it in the ContentView using SwiftUI but result showing nil. But the console prints the data from LocationManager class. Not showing the latitude and longitude from the content view. Can anyone help? (Xcode 11)
This is the LocationManager class
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject,CLLocationManagerDelegate, ObservableObject {
private let manager: CLLocationManager
var willChange = PassthroughSubject<LocationManager, Never>()
var getLat: String = ""
var getLon: String = ""
var lastKnownLocation: CLLocation? {
willSet {
willChange.send(self)
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .denied {
print("denied")
}
else{
print("athorized")
manager.requestLocation()
}
}
func start() {
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
init(manager: CLLocationManager = CLLocationManager()) {
self.manager = manager
super.init()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func startUpdating() {
self.manager.delegate = self
self.manager.requestWhenInUseAuthorization()
self.manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//print(locations)
lastKnownLocation = locations.last
getLat = "\(locations.last!.coordinate.latitude)"
getLon = "\(locations.last!.coordinate.longitude)"
showLocation()
}
func showLocation() {
print("from showLocation")
print("Latitude: \(getLat)")
print("Longitude: \(getLon)")
}
}
This is the console that shows the latitude and longitude from LocationManager class
This is the Content View
import SwiftUI
import CoreLocation
struct ContentView: View {
@State var managerDelegate = LocationManager()
@State var manager = CLLocationManager()
@ObservedObject var location = LocationManager()
var lat: String {
return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
}
var lon: String {
return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
}
init() {
self.manager.delegate = self.managerDelegate
do {
try self.manager.requestAlwaysAuthorization()
}
catch {
print(error.localizedDescription)
self.manager.requestAlwaysAuthorization()
}
}
var body: some View {
VStack {
Text("Hello, World")
Text("Latitude: \(lat)")
Text("Longitude: \(lon)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Alright, I found myself the time to read your code and I have a solution for you.
First, you'll want to set the delegate to the variable that you are observing, inside
ContentView.init():Immediately after, you'll want to call the
startUpdating()function that you defined inLocationManager:Finally, you may want to remove your
will-changeimplementation and opt for the more simple:The published wrapper will automatically trigger object changes for you.
Refactor
Now if you like, you can also reduce your init statement down to one line:
Which means you can freely remove a couple properties:
TLDR; Here is a shortened version of the code:
The content view
The Location Manager