Location Services and Battery Life

Optimizing Battery Life in Location Based Apps

I’ve finally begun to really begin to think about the overall architecture of my app and I’ve already run into a fork in the road that slowed me down for more time than I’ll like to admit. The fork is whether to get a user’s location in one of two options, standard location service or significant location change service.

From my own experience, I refuse to use apps that unnecessarily drain battery and location based apps are battery hogs. That being said I refuse to build a battery hog so I was initially intrigued by the significant location change service.

According to Apple’s sometimes dull but always useful documentation,

“the significant location change service is better suited for apps that want to get the user’s initial location and then only want to know that location changes. This service requires the presence of cellular hardware and delivers events less frequently than the standard location services.”

So I thought that was great and pretty much all that I needed. In my idea I really only need to know the user’s location for a short period of time and depending on how frequently I can call the process, would think that real significant location changes should be the only ones of true concern. After a bit more research and I found that there are predefined values ready for use,

kCLLocationAccuracyBestForNav

kCLLocationAccuracyBest

kCLLocationAccuracyNearestTenMeters

kCLLocationAccuracyHundredMeters

kCLLocationAccuracy Kilometer

kCLLocationAccuracyThreeKilometers

A few of these are pretty self explanatory but the kCLLocationAccuracyBest and kCLLocationAccuracyBestforNavigation values were ones that I wasn’t so sure of, prompting me to take a further look. After a bit of reading, I came to the conclusion that the best for nav value used the absolute highest level of accuracy possible. All major inputs of location values(GPS, cell service, and WiFi) are essentially always on. Of all the predefined constants, this is the one that draws power the most, hence why Apple intends for this constant to be used when the phone is powered externally. KCLlocationAccuracyBest is considered the standard constant to use by many developers as it uses the highest recommended settings for each location data apparatus. Even though I really would like the most accurate location readings available, after doing a bit of research it seems like kCLLocationAccuracyBestForNavigation, it seems that this constant uses about 20% more power than kCLLocationAccuracyBest. I happened to read a post on StackOverflow about using NSTimer to periodically control the location updates and eventually will like to incorporate such an idea into my app.

[self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
[self.locationManager setDistanceFilter:99999];
- (void) changeAccuracy {
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
}

Here hes switching the highest recommended settings(kCLLocationAccuracyBest) and a constant value(kCLLocationAccuracyThreeKilometers) that turns off the hardware that drains the most battery while gaining location data, the GPS, along with killing the WiFi radio .

So once that was decided it was time to instantiate an instance of the CLLocation Manager, the object responsible for configuring how the device receives the location and also reporting back the current heading of the device.

locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestLocation()

For awhile I was stuck with the code above and soon realized that whenever instantiating a location manager object to get the user’s location data, we need to have authorization. User authorization is required whenever we need data from location hardware. After a bit more reading of the documentation, a call to the class method authorizationStatus() is needed. The app will only work if the user allows for their location data to be accessed. Below is the code block needed to probably set up the location manager, with the authorization line italicized.

locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.