I'm currently experimenting with CLLocation
and i recently came across authorizationStatus
. I want to show one view if the user allows the app to use location services, and another one if he/she don't. It works as I want it to, except .notDetermined
. If I insert it in my .denied
-block and press "Allow when in use", I can't render the "allow" page but rather have to restart the app to render it. It's also the other way around if I put it in my .accesWhenInUse
-block and press "deny". So my question is, what is a good practice to do with this command? Ideally I want the app to wait until the user actually does a choice and load it from there, but since .notDetermined
is required to handle i'm a bit lost.
My init location func so far:
private func initLocation() {
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse, .authorizedAlways :
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
break
case .notDetermined:
break
case .restricted, .denied:
print("well this is awkward..")
view.addSubview(noLocationTextView)
NSLayoutConstraint.activate([
noLocationTextView.heightAnchor.constraint(equalToConstant: 210),
noLocationTextView.widthAnchor.constraint(equalToConstant: 210),
noLocationTextView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
noLocationTextView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
])
noLocationTextView.text = "Well we're going to need your location"
break
}
}
}
I've extracted .notDetermined
to its own case right now.
So the question is, how do I handle this so that the app waits and loads the proper view when a choice is made?
Thanks to @Paulw11 I managed to fix this by using the delegate method. So instead of using my initLocation()
I used this:
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .authorizedWhenInUse, .authorizedAlways:
goToLocationSettings.removeFromSuperview()
noLocationContainer.removeFromSuperview()
break
case .denied, .restricted:
print("well this is awkward..")
view.addSubview(noLocationContainer)
NSLayoutConstraint.activate([
noLocationContainer.heightAnchor.constraint(equalTo: self.view.heightAnchor),
noLocationContainer.widthAnchor.constraint(equalTo: self.view.widthAnchor),
])
noLocationContainer.insertSubview(goToLocationSettings, at: 3)
NSLayoutConstraint.activate([
goToLocationSettings.widthAnchor.constraint(equalToConstant: 300),
goToLocationSettings.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
goToLocationSettings.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 200),
goToLocationSettings.heightAnchor.constraint(equalToConstant: 50)
])
break
default:
break
}
}
This way .notDetermined
is default
which does nothing until the user made a choice, as I wanted. It also changes in real-time so if I deny access to location and then grants it when the app is running it just updates the view and shows the content. Hope this helps someone with a similar problem!