My current project is a constant-presence application (think Tinder or Foursquare), and the battery consumption is through the roof. We think the main draw on power are the GPS and WiFi antennas. We'd like to be able to measure our app's energy usage under several different configurations.
But how to do this? We want a process that:
- Can be used with the phone disconnected from the computer (so we know we're using battery rather than drawing power over USB),
- Has sufficient granularity to allow us to correlate energy spikes to application events (launching the app, updating the location, sending analytics information to Mixpanel, etc),
- Can be run overnight without babysitting,
- Can be exported as CSV or whatever for statistical analysis.
Quite the list, I know.
Those are the requirements, and here are the options that I'm aware of:
1. Turning on untethered Energy Diagnostics Logging on an iOS device, and exporting to Instruments
This is the obvious answer, but it has one gigantic flaw.
Pros:
- Uses battery instead of USB power.
- Excellent granularity (1sec time series data, 20 discrete energy usage levels),
- Correlated to other device events like GPS antenna usage etc.
Cons:
- Can't run overnight because "if the device battery runs dry or the iOS Device is powered off, the log data is lost." This is a CRAZY restriction, and pretty much makes this approach useless for our case (https://developer.apple.com/library/ios/recipes/Instruments_help_articles/LoggingEnergyUsageinaniOSDevice/LoggingEnergyUsageinaniOSDevice.html).
- Can't export to CSV. Because Instruments.
2. Monitoring a plugged-in phone through Instruments
Pros:
- Same excellent granularity and correlation to other device events.
- Battery can't run out.
Cons:
- Doesn't use the battery, so the energy consumption is incomparable to real-world usage.
- Instruments doesn't even reliably show energy usage. Sometimes it's just blank.
- Can't export to CSV.
3. Using public Cocoa APIs to record energy usage in our app – [UIDevice.currentDevice batteryLevel]
This is the most common answer on SO. I've looked at Estimated battery time on iOS, iphone: Calculating battery life and about a dozen others.
Pros:
- Arbitrarily small time between measurements.
- Can persist data even if the battery dies by writing to disk somehow (CoreData, defaults, network, whatever).
- Can choose arbitrary format for the data, say CSV.
Cons:
- A lot more work than the other approaches.
- Public API only gives you battery level to 5% accuracy. This is essentially the time integral of the instantaneous power consumption data we get from approaches 1 and 2. Not nearly granular enough to correlate with other device events (but maybe enough to get a gross estimate for device battery life).
4. Using private Cocoa APIs to record energy usage
As we'll only ever be doing this during development, it doesn't matter if Apple would reject the app for using a private API. Presumably there's some private API for this, as Apple is able to record the data with Untethered Energy Diagnostics turned on.
Pros:
- Arbitrarily granularity, arbitrary file format, arbitrary persistence.
Cons:
- Waaaaay more work to figure out how to use it. Maybe not even possible.
5. Combined approach
We could use the untethered diagnostics to quantify the marginal energy cost for each action. "Ok, spinning up the GPS antenna takes 150mW•H. Calculating position takes 50mW•H. Sending a Mixpanel event takes 25mW•H, unless we made another network call within the previous 30sec, in which case it takes 15mW•H." (all numbers invented on the spot.) Then we can use the tethered monitoring to record when each of those actions takes place, plug into a linear equation, and estimate the amount of energy it should have taken.
Pros:
- Flexible. Arbitrary everything.
Cons:
- Maths.
- Very easy to miss non-linear contributions. Getting something like E = k0/(gps poll interval) + k1*(number of analytics calls) is easy, but what if the cost of spinning up both antennas is less than the sum of spinning them each up separately?
- Ignores any caching strategies that Apple might make internally in Location Services.
- Not even remotely close to real-world utilization.
Anyhow, I've blathered enough. Has anybody done this before? How?