Reputation: 1547
After building the iOS app I wanted, I realized it's consuming way too much battery due to location services.
Background: My app makes a call to the server over network every time a user moves 10 meters (30 ft). This triggers the didUpdateLocation
function. When that function is triggered I use NSURLSession
to send the users coordinates to the server, that's really about it.
Now the issue lies in that I can't power down location services hardware by calling locationManager.stopUpdatingLocation()
after the first update because I won't get any subsequent updates when the user decides to move again. In addition, location services stays active while the app is in the background to monitor movement, also causing a drag on battery life. I have read almost everything about this issue when it comes to documentation and other questions on here.
A lot of other questions suggest using an NSTimer
and calling the startUpdatingLocation()
after an interval of time has passed by and I have received the first location update and called stopUpdatingLocation
in my didUpdateLocation
function. So I tried the following:
let timerAction = NSTimer(timeInterval: 6.0, target: self, selector: #selector(MapViewController().startLocationServices), userInfo: nil, repeats: true)
timerAction.fire()
func startLocationServices() {
self.locationManager.startUpdatingLocation()
}
This hasn't worked for some reason or another. But my question really focuses around how I can save battery and make my app really energy efficient when I must monitor a user's movements in the foreground and background with the distanceFilter = 10.0
?
Any suggestion maybe around what you have done or what you would recommend would be tremendously sought and appreciated.
Thank you!
Edit
@wain suggested using allowDeferredLocationUpdatesUntilTraveled:timeout:
,
Start the delivery of location updates before calling this method. The most common place to call this method is in your delegate’s locationManager:didUpdateLocations: method. After processing any new locations, call this method if you want to defer future updates until the distance or time criteria are met. If new events arrive and your app is in the background, the events are cached and their delivery is deferred appropriately.
Upvotes: 0
Views: 693
Reputation: 1547
I ended up remedying this problem by using geofencing. I create a CLCircularRegion
and call startMonitoringForRegion(_:)
. Every time the user leaves the region (10 meters), I make a request to the server to see where he's at now and update the region. This use little to no battery and is exactly what I'm looking for. Look at the CLLocationManager
, CLLocationManagerDelegate
and CLCircularRegion
classes on how to do this. I hope this will come in handy for someone.
Upvotes: 2
Reputation: 119041
You have 2 options:
allowDeferredLocationUpdatesUntilTraveled:timeout:
Try the first, if it isn't available on the device you must sacrifice your 10m goal
Upvotes: 2