Article

Requesting Always Authorization

Request authorization to use location services at any time.

Overview

To configure always authorization for location services, follow these steps (Listing 1 demonstrates steps 3-5):

  1. Add the NSLocationWhenInUseUsageDescription key and the NSLocationAlwaysAndWhenInUseUsageDescription key to your Info.plist file. (Xcode displays these keys as "Privacy - Location When In Use Usage Description" and "Privacy - Location Always and When In Use Usage Description" in the Info.plist editor.)

  2. If your app supports iOS 10 and earlier, add the NSLocationAlwaysUsageDescription key to your Info.plist file. (Xcode displays this key as "Privacy - Location Always Usage Description" in the Info.plist editor.)

  3. Create and configure your CLLocationManager object.

  4. Call the requestWhenInUseAuthorization() initially to enable your app's basic location support.

  5. Call the requestAlwaysAuthorization() method only when the user enables a feature of your app that requires that level of authorization.

Don't request authorization at launch time unless you need the user's location immediately or were launched in the background to receive a location update.

Enable When-In-Use Authorization Before Always Authorization

Listing 1 shows one way to enable your app's location services initially. If your app's authorization status is already determined, you don't need to request authorizationa gain. If your app's authorization status is not determined, try to limit your initial authorization request to when-in-use authorization. You can request always authorization right away if your app requires the corresponding location services, but be prepared for the user to grant only when-in-use authorization or to deny your request altogether.

Listing 1

Requesting authorization to use location services

let locationManager = CLLocationManager()   
func enableLocationServices() {
   locationManager.delegate = self
        
   switch CLLocationManager.authorizationStatus() {
      case .notDetermined:
         // Request when-in-use authorization initially
         locationManager.requestWhenInUseAuthorization()
         break
            
      case .restricted, .denied:
         // Disable location features
         disableMyLocationBasedFeatures()
         break
            
      case .authorizedWhenInUse:
         // Enable basic location features
         enableMyWhenInUseFeatures()
         break
            
      case .authorizedAlways:
         // Enable any of your app's location features
         enableMyAlwaysFeatures()
         break
      }
   }      
}

Escalate the App's Authorization Level

In iOS 11 and later, if you initially requested only when-in-use authorization, you can call the requestAlwaysAuthorization() method at a later time (as shown in Listing 2) to escalate your app's authorization level. When requesting always authorization, the system displays the usage description string stored in the NSLocationAlwaysAndWhenInUseUsageDescription key of your Info.plist file. The user must then choose whether to grant the request for always authorization or to leave your app with when-in-use authorization. The system lets your app escalate its authorization level only once, displaying an appropriate interface to the user when you do. Subsequent attempts do not display a system interface and do not change your app's authorization level.

Listing 2

Escalating from when-in-use to always authorization

func escalateLocationServiceAuthorization() {
   // Escalate only when the authorization is set to when-in-use
   if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
      locationManager.requestAlwaysAuthorization()
   }
}

Respond to Changes in Authorization Status

When you request authorization, or when your app's authorization status changes, use the locationManager(_:didChangeAuthorization:) method of your delegate object to process the changes. Listing 3 shows an implementation of that method that enables or disables features based on the app's current authorization level.

Listing 3

Getting changes to the app's authorization

func locationManager(_ manager: CLLocationManager, 
                     didChangeAuthorization status: CLAuthorizationStatus) {   switch status {
      case .restricted, .denied:
         // Disable your app's location features
         disableMyLocationBasedFeatures()
         break
            
      case .authorizedWhenInUse:
         // Enable only your app's when-in-use features.
         enableMyWhenInUseFeatures()
         break
            
      case .authorizedAlways:
         // Enable any of your app's location services.
         enableMyAlwaysFeatures()
         break
            
      case .notDetermined:
         break
   }
}

See Also

Requesting Authorization

Requesting When-In-Use Authorization

Request authorization to use location services only when your app is running.