I'm currently working with the Swift Composable Architecture (version 0.59.0) and the Composable Core Location (version 0.3.0). I've set it up according to the official instructions, but I've encountered an error that I'm struggling to resolve.
The error message I'm receiving is:
Assertion failure in -[CLLocationManager requestLocation], CLLocationManager.m:1337
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate must respond to locationManager:didUpdateLocations:'
Here's the relevant block of code:
case .onAppear:
return .merge(
locationManager
.delegate()
.map({ action in
return .locationManager(action)
}),
locationManager.requestWhenInUseAuthorization().fireAndForget()
)
case .locationManager(.didChangeAuthorization(.authorizedAlways)),
.locationManager(.didChangeAuthorization(.authorizedWhenInUse)):
return locationManager.requestLocation().fireAndForget()
case .locationManager(.didChangeAuthorization(.denied)),
.locationManager(.didChangeAuthorization(.restricted)):
return .none
case let .locationManager(.didUpdateLocations(locations)):
print("Received locations: \(locations)")
return .none
case .locationManager:
return .none
Has anyone encountered a similar issue or can offer insights on how to address this? Any guidance or suggestions would be immensely appreciated.
Hi, so the reason for an error is that CLLocationManager called method on delegate before it was set.
I assume that you are using protocol based reducers (because you use relatively new version of TCA, but why not 1.2?). How do you store/pass the locationManager? Do you use @Dependency property wrapper or pass it in a reducer init? If you use @Dependency then this version of Composable Core Location is not really compatible without some tweaks to make sure that CLLocationManager is initialised on correct thread/actor.
If you not using Dependencies, than you can also try one thing. In your code:
You setup delegate and request location in parallel and requesting is just faster in reaching CLLocationManager than delegate setup. Even if you use .concatenate then there is no guarantee that delegate setup will be finished before request for location. Just to test it quickly you can try to setup delegate on onAppear action but request location using some button to split these to effects. It it works than you have to chain these effect together and make sure that order is preserved.
Little disclaimer: I didn't used combine versions of effects for some time, so I can be wrong ;)