Right now I am just trying to get the location printed on screen, and will expand upon it later, but I am getting the following console output (the app also crashes - it is being built and run on a physical device):
2022-11-14 16:43:07.333908-0700 Countries[7257:1687502] *** Assertion failure in -[CLLocationManager requestLocation], CLLocationManager.m:1323
2022-11-14 16:43:07.334806-0700 Countries[7257:1687502] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate must respond to locationManager:didUpdateLocations:'
*** First throw call stack:
(0x1c4566248 0x1bd92ba68 0x1beeea81c 0x1cfd2a654 0x1040d7308 0x1040d3ff8 0x246a377e8 0x1c69396d8 0x1c69393d8 0x1c6938d6c 0x2464f75f8 0x1c6938848 0x1c681e060 0x1c709e1d8 0x1c67e1d18 0x1c67e6674 0x1c67e5944 0x1c67e5000 0x1c682cd64 0x1c7473a30 0x1c6d3b678 0x1c737a904 0x1c7379ad0 0x1c463222c 0x1c463e614 0x1c45c251c 0x1c45d7eb8 0x1c45dd1e4 0x1fd3fd368 0x1c6a8cd88 0x1c6a8c9ec 0x1c808bce8 0x1c7fe8c24 0x1c7fd1b44 0x1040e8b20 0x1040e8bc8 0x1e2901948)
libc abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate must respond to locationManager:didUpdateLocations:'
terminating with uncaught exception of type NSException
(lldb)
Here is the code I am using:
import Foundation
import CoreLocation
import CoreLocationUI
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
let manager = CLLocationManager()
@Published var location: CLLocationCoordinate2D?
override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation], didFailWithError error: Error) {
location = locations.first?.coordinate
}
func requestLocation() {
manager.requestLocation()
}
}
And the code for the view (in a different Swift file):
import SwiftUI
import _CoreLocationUI_SwiftUI
struct SettingsView: View {
@StateObject var locationManager = LocationManager()
var body: some View {
NavigationView {
List {
VStack {
if let location = locationManager.location {
Text("Your location: \(location.latitude), \(location.longitude)")
}
LocationButton {
locationManager.requestLocation()
}
.frame(height: 44)
.padding()
}
}
.navigationTitle("Settings")
}
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
I have tried restarting the project and running the build on both a physical device and the emulator. Both result in the same crash and output when the LocationButton is pressed.
CodePudding user response:
The error is correct. You have not implemented the locationManager:didUpdateLocations:
method. You have some method named locationManager:didUpdateLocations:didFailWithError:
.
Instead of:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation], didFailWithError error: Error) {
location = locations.first?.coordinate
}
you need (drop the didFailWithError
parameter):
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
location = locations.first?.coordinate
}
If you wish to handle any errors, also implement the locationManager(_:didFailWithError:)
delegate method.