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:
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:
Cons:
2. Monitoring a plugged-in phone through Instruments
Pros:
Cons:
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:
Cons:
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:
Cons:
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:
Cons:
Anyhow, I've blathered enough. Has anybody done this before? How?
Although you cannot reset battery usage on iPhone, it is possible to hide app battery usage. Go to the Settings app from your home screen, choose General, Usage, and Battery Usage. Then decide to display or hide battery usage for each app.
Just swipe down from the top-right corner of your display. With iOS 16, you can turn on the battery percentage so it appears in your status bar. Go to Settings > Battery, and turn on Battery Percentage.
Not sure if this is applicable to this exact use-case, but I've developed a library called UIDeviceListener
that allows you to easily (basically with one line of code), retrieve data from the operating system regarding power consumption and many other battery/charging related data points: https://github.com/eldoogy/PowerData
Here is a sample dictionary to give you an idea of the kind of information you can get. I will point your attention to the InstantAmperage key. This shows real-time power consumption in mA for the entire device (while the device is unplugged). That might help accomplish what you're looking for here.
{
AdapterDetails = {
Amperage = 1000;
Description = "usb host";
FamilyCode = "-536854528";
PMUConfiguration = 1000;
Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleRawCurrentCapacity = 1279;
AppleRawMaxCapacity = 1275;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryData = {
BatterySerialNumber = REDACTED;
ChemID = 355;
CycleCount = 524;
DesignCapacity = 1420;
Flags = 640;
FullAvailableCapacity = 1325;
ManufactureDate = REDACTED;
MaxCapacity = 1273;
MfgData = REDACTED;
QmaxCell0 = 1350;
StateOfCharge = 100;
Voltage = 4194;
};
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 52;
BootCapacityEstimate = 2;
BootVoltage = 3518;
CFBundleIdentifier = "com.apple.driver.AppleD1815PMU";
ChargerConfiguration = 990;
CurrentCapacity = 1275;
CycleCount = 524;
DesignCapacity = 1420;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 1;
IOClass = AppleD1815PMUPowerSource;
IOFunctionParent64000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOInterruptControllers = (
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000,
IOInterruptController34000000
);
IOInterruptSpecifiers = (
<03000000>,
<26000000>,
<04000000>,
<24000000>
);
IOMatchCategory = AppleD1815PMUPowerSource;
IOPowerManagement = {
CurrentPowerState = 2;
DevicePowerState = 2;
MaxPowerState = 2;
};
IOProbeScore = 0;
IOProviderClass = AppleD1815PMU;
InstantAmperage = 0;
IsCharging = 0;
Location = 0;
Manufacturer = A;
MaxCapacity = 1275;
Model = "0003-A";
Serial = REDACTED;
Temperature = 2590;
TimeRemaining = 0;
UpdateTime = 1461830702;
Voltage = 4182;
"battery-data" = {
"0003-default" = <...>;
"0004-default" = <...>;
"0005-default" = <...};
"built-in" = 1;
}
UIDeviceListener
supports regular, non jailbroken iOS devices and does not invoke any private APIs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With