Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 11, app not updating location when force killed by user

I am working on an application that requires real time location tracking soo I'm using startMonitoringSignificantLocationChanges and everything is working fine on my iOS 10 simulator even when app has been force quit by the user from the app switcher. I'm using the freeway-drive option when debugging via the simulator also so that the location keeps changing.

But for iOS 11 simulator: When the app is in background or foreground mode the server is updated with the users real-time location but when app has been force quit, this doesn't happen.

The server is not getting the updated location and i even put a breakpoint in didFinishLaunching and used the wait for executable to be launched setting to check if i get a callback, but i don't for iOS 11 and do for iOS 10.

I have also updated the info.plist with appropriate values that are needed for iOS 11 and have confirmed that i'm giving the "always" permission. I am using a singleton for the location manager object using the code:

func setupLocationManager(){

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.requestAlwaysAuthorization()
    locationManager.distanceFilter = 100.0
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
    locationManager.startMonitoringSignificantLocationChanges()
    locationManager.startUpdatingLocation()
}

And in the app delegate:

if let _ = launchOptions?[UIApplicationLaunchOptionsKey.location] {

        ChatSocketHelper.sharedInstance.socket.on("connect") { data, ack in

            if let coordinate = LocationManager.shared.currentLocation?.coordinate{

                ChatSocketHelper.sharedInstance.updateLocation([coordinate.longitude, coordinate.latitude])
            }
        }   
    }

And in the location delegate:

extension LocationManager : CLLocationManagerDelegate{

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

        guard let locationObject = locations.last else {return}

        //update to closest accuracy
        currentLocation = locationObject

        if ChatSocketHelper.sharedInstance.socket != nil{
ChatSocketHelper.sharedInstance.updateLocation([locationObject.coordinate.longitude, locationObject.coordinate.latitude])
        }
    }
}

Is this a known issue with iOS 11 that location is broken when force killed by the user? As i did some digging around and found similar issues for bluetooth but nothing significant for location changes otherwise.

For example this link.

Edit: Also this posts talks about the updates being "slower" but i don't receive updates at all.

like image 493
Rikh Avatar asked Dec 12 '17 10:12

Rikh


1 Answers

I spent quite a while debugging this and trying to find solid answers. Basically, background and foreground location updates work as expected. Now lets come to the real problem and that is the killed mode of the application (mainly force quite by the user).

As far as i can tell the reason location updates weren't working properly when i tested this via the simulator was either because the distance i tested for wasn't nearly far enough or maybe the fact that significantLocationChanges relies on the change in network (the handoff to different towers or something). But when i tested the killed scenario with real devices and travelling quite a distance, i found the results to be varied but basically location did update although the updates were never consistent. Now this consistency maybe owing to bad network connection as well while travelling but I cannot be sure.

While travelling by car for 15-20 minutes (over a distance of 3.8 kilometers), while app was killed, the location was sent to the server on one day 4-5 times and while travelling a different route for the same duration, 2-3 times. Again this maybe either due to poor network conditions or how frequently the network handoff happened.

If you are expecting background and foreground level accuracy/frequency then it is not possible. It simply isn't possible currently.

Now alternatively, i even tried using dynamic geofencing to monitor location updates but that was a bit of a failure. I set up a new geo fence everytime i got a call back from the OS about user exiting/entering the geofence setup. Now these callbacks happened for a while but sometimes they just stopped and entire geo fence regions were skipped entirely or if the vehicle is moving too fast the geo fence doesn't provide you with a callback as there are conditions for us to get these call backs. More can be read here

From the above linked docs, "Testing an iOS App’s Region Monitoring Support

When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn’t deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters."

Basically you get location updates with startMonitoringSignificantLocationChanges but the accuracy and frequency isn't something you can rely on or estimate.

like image 156
Rikh Avatar answered Nov 18 '22 09:11

Rikh