iOS Location Services: updates not received when device has been locked for a while.

Hello

I’ve a question regarding CLLocationManager as I’m observing a strange behaviour when receiving location updates. And I don’t really know what could be the culprit here.

Some information regarding the device:

  • Device: iPhone Xs Max
  • OS: iOS 16.1 beta 4
  • App Background Modes: locations updates checked.

CLLocationManager setup:

  • CLAuthorizationStatus: authorizedWhenInUse
  • CLAccuracyAuthorization: fullAccuracy
  • allowsBackgroundLocationUpdates is ON
  • pausesLocationUpdatesAutomatically is OFF (but toggle to turn in on in the POC)
  • activityType (CLActivityType): .otherNavigation (but tried other options).
  • desiredAccuracy (CLLocationAccuracy) : kCLLocationAccuracyNearestTenMeters (to receive GPS updates, and not cell towers)
  • distanceFilter CLLocationDistance): kCLDistanceFilterNone (-1) or 0.

When I record with the device unlocked, everything is working fine with the app either in foreground or in background. It receives location updates as I walk around with quite good accuracy (between 5 and 15 meters, see attachment).

But I notice that when the device is locked in my pocket, the location service stops receiving updates after a while (like few minutes). I tried with Wi-Fi off and it behaves the same. You can see that in my screenshots attached: many values are incorrect (speed, course). When I open the app again (not crashed), the locations are received again but the horizontalAccuracy is not very good: it’s as if it was not using the GPS anymore.

I tried with low power mode enabled and disabled, and I think it behaves the same but maybe not? Is the low power mode responsible for this discrepancies?  As far as I know, it does not modify location services accuracy (only network, background tasks, etc.).

Thanks

I include some basic code to better illustrate how the CLLocationManager is configured and used.

class LocationDataManager: NSObject, CLLocationManagerDelegate {
    private let locationManager: CLLocationManager
    var activityType: CLActivityType = .automotiveNavigation {
        didSet {
            locationManager.activityType = activityType
        }
    }

    var desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBestForNavigation {
        didSet {
           locationManager.desiredAccuracy = desiredAccuracy
        }
    }

    var pausesLocationUpdatesAutomatically: Bool = false {
        didSet {
           locationManager.pausesLocationUpdatesAutomatically = pausesLocationUpdatesAutomatically
        }
    }

    var distanceFilter: CLLocationDistance = kCLDistanceFilterNone {
        didSet {
            locationManager.distanceFilter = distanceFilter
        }
    }
 
    init() {
        locationManager = CLLocationManager()
        locationManager.activityType = .automotiveNavigation // controlled by the Picker
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation // controlled by the Picker
        locationManager.pausesLocationUpdatesAutomatically = false // controlled by the Toggle
        locationManager.distanceFilter = kCLDistanceFilterNone // controlled by the Picker
        locationManager.allowsBackgroundLocationUpdates = true
    }
    
    func start() {
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    func stop() {
        locationManager.stopUpdatingLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print(locations.last)
    }

   func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager) {
        print(#function)
   }
    
   func locationManagerDidResumeLocationUpdates(_ manager: CLLocationManager) {
        print(#function)
   }
}

My previous code was not functional (edited in this forum without compiling), but the problem is the same (the correct configuration provided below was used during my tests).


class LocationDataManager: NSObject, CLLocationManagerDelegate {
    private let locationManager: CLLocationManager = CLLocationManager()
    var activityType: CLActivityType = .automotiveNavigation {
        didSet {
            locationManager.activityType = activityType
        }
    }

    var desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBestForNavigation {
        didSet {
           locationManager.desiredAccuracy = desiredAccuracy
        }
    }

    var pausesLocationUpdatesAutomatically: Bool = false {
        didSet {
           locationManager.pausesLocationUpdatesAutomatically = pausesLocationUpdatesAutomatically
        }
    }

    var distanceFilter: CLLocationDistance = kCLDistanceFilterNone {
        didSet {
            locationManager.distanceFilter = distanceFilter
        }
    }
 
    override init() {
        super.init()

        locationManager.delegate = self
        locationManager.activityType = .automotiveNavigation // controlled by the Picker
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation // controlled by the Picker
        locationManager.pausesLocationUpdatesAutomatically = false // controlled by the Toggle
        locationManager.distanceFilter = kCLDistanceFilterNone // controlled by the Picker
        locationManager.allowsBackgroundLocationUpdates = true
    }
    
    func start() {
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    func stop() {
        locationManager.stopUpdatingLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print(locations.last)
    }

   func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager) {
        print(#function)
   }
    
   func locationManagerDidResumeLocationUpdates(_ manager: CLLocationManager) {
        print(#function)
   }
}

iOS Location Services: updates not received when device has been locked for a while.
 
 
Q