Home > Enterprise >  Does stopUpdatingLocation() change Authorization when working in background
Does stopUpdatingLocation() change Authorization when working in background

Time:07-16

In my application, I'm using startUpdatingLocation() in the background (I've configured the background mode and set allowsBackgroundLocationUpdates to true, this is working fine).

When the user taps a button in my application, I'm calling startUpdatingLocation(), manually dragging the app to the background, allowing startUpdatingLocation() to run for 10 seconds before I call stopUpdatingLocation(), and finally going back into the app. I've noticed that when I give temporary authorization to the location permission (clicking "allow once") before tapping the button, then after I come back into the app, the authorization returns to not determined and I have to once again click on the allow location permission.

Is this supposed to happen, and if so are there any work-around solutions?

Apple's documentation states "the authorization changes when the user ceases to use the app". However in this case, the app is never terminated, it only goes into background.

Here's some of the relevant code

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: scene)
    window?.makeKeyAndVisible()
    window?.rootViewController = MainViewController()
}

func sceneDidBecomeActive(_ scene: UIScene) {
    AppDelegate.loc.checkRequestPermission()
}
}

class MainViewController: UIViewController {  
override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .red
    
    let button = ReusableUIElements.createButton(title: "Start")
    view.addSubview(button)
    button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
    ReusableUIElements.buttonConstraints(button: button, safeArea: view.safeAreaLayoutGuide, bottomAnchorConstant: -40)

}

@objc func buttonPressed() {
    // I manually move to background when this button is pressed
    AppDelegate.loc.retrieveLocation()
 }
 }

class Location: NSObject, CLLocationManagerDelegate {

var locationManager: CLLocationManager!

override init() {
    super.init()
    
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.showsBackgroundLocationIndicator = true
}

func checkRequestPermission() {
    if locationManager.authorizationStatus == .notDetermined {
        self.locationManager.requestWhenInUseAuthorization()
    }
}

func retrieveLocation()  {
    self.locationManager.startUpdatingLocation()

    DispatchQueue.main.asyncAfter(deadline: .now()   10) {
        print("10 seconds after")
        self.locationManager.stopUpdatingLocation()
        
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    if let location = locations.last {
        
        let geocoder = CLGeocoder()
        
        geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in
            
            if error == nil {
                print(placemarks![0])
            }
        })
    }
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print(error.localizedDescription)
}

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    print("changeAuthorization called")

    switch locationManager.authorizationStatus {
        case .denied, .restricted:
            print("denied, restricted")
   
        case .authorizedWhenInUse, .authorizedAlways
            print("authorized")
       
        default:
            print("not determiend")
    }
}
}

Any help is appreciated

CodePudding user response:

"Ceases to use the app" doesn't mean that the app is terminated. The user is using an app if it is on screen. If it is not then essentially they are no longer using it.

When an app with "only once" permission moves to the background and is suspended you have used your "once" and need to ask again.

In your case, your permission is slightly extended; Since you are using location in the background your location permission will persist (and the blue location indicator will be shown) until you call stopUpdatingLocation. At this point, as your app is no longer actively being used, your permission lapses.

  • Related