Search code examples
iosswiftcore-location

How to request for location permission when a button got pressed in swift


I am working a weather app which requires location data. To get the data i want to request for permission only when the user presses the locationButton and not when the app opens. It is working fine when I call locationManagerDidChangeAuthorization method after viewDidLoad but it is not working when I call it inside a button got pressed method. Is there any solution for it?

@IBAction func locationButtonPressed(_ sender: UIButton) {
     
     func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
         if #available(iOS 14.0, *) {
             switch manager.authorizationStatus {
             case .authorizedWhenInUse:  // Location services are available.
                 
                 break
                 
             case .restricted, .denied:  // Location services currently unavailable.
                
                 break
                 
             case .notDetermined:        // Authorization not determined yet.
                 manager.requestWhenInUseAuthorization()
                 break
                 
             default:
                 break
             }
         } else {
             // Fallback on earlier versions
         }
     }
 }

I called the authorisation permission request inside a locationButtonPressed method but it is not working.


Solution

  • You are not calling locationManagerDidChangeAuthorization inside of locationButtonPressed, you are declaring the locationManagerDidChangeAuthorization function inside of the locationButtonPressed function. That function will never be used or called this way.

    Put that delegate method back at the top level of the class where it belongs.

    The solution for your needs to is wait and initialize an instance of CLLocationManager inside your button handler. This will delay any prompt to the user until after they tap the button.

    Your code would look something like this:

    class SomeViewController: UIViewController {
        var locationManager: CLLocationManager?
    
        @IBAction func locationButtonPressed(_ sender: UIButton) {
            if locationManager == nil {
                locationManager = CLLocationManager()
                locationManager.delegate = self
                // locationManagerDidChangeAuthorization will now be called automatically
            }
        }
    }
    
    extension SomeViewController: CLLocationManagerDelegate {
         func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
             if #available(iOS 14.0, *) {
                 switch manager.authorizationStatus {
                 case .authorizedWhenInUse:  // Location services are available.
                     // Begin getting location updates
                     manager.startUpdatingLocation()
                 case .restricted, .denied:  // Location services currently unavailable.
                     break
                 case .notDetermined:        // Authorization not determined yet.
                     manager.requestWhenInUseAuthorization()
                 default:
                     break
                 }
             } else {
                 // Fallback on earlier versions
             }
         }
    
         func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
             // handle location as needed
         }
    }