Skip to content

Instantly share code, notes, and snippets.

@quicklywilliam
Last active September 20, 2020 12:44
Show Gist options
  • Save quicklywilliam/842859749c5d78251a77 to your computer and use it in GitHub Desktop.
Save quicklywilliam/842859749c5d78251a77 to your computer and use it in GitHub Desktop.
// Props to the fine folks on this thread http://bbs.iosre.com/forum.php?mod=viewthread&tid=694
//
// Example output of a call to dailyUsageStasticsForBundleIdentifier or weeklyUsageStasticsForBundleIdentifier
// Inline comments are educated guesses at meaning
// {
// Airdrop = 0; // Has App used Airdrop
// Airplay = 0; // Has App used Airplay
// BBCondition = 0; // ?? BB = Backboard? This number is a float (ie 24.8766038700895)
//
// // No idea what the below units are, or what BLD means
// BLDEnergyAudio = 0; // Audio playback usage
// BLDEnergyBGCPU = "46.78369148176786"; // Background CPU usage
// BLDEnergyBGLocation = 0; // Background Location usage
// BLDEnergyBluetooth = 0; // Bluetooth usage
// BLDEnergyCellData = 0; // Cell usage
// BLDEnergyDisplay = "38.64946962044302"; // Display usage
// BLDEnergyFGCPU = "27.25031398030336"; // Foreground CPU usage
// BLDEnergyFGLocation = 0; // Foreground location usage
// BLDEnergyVoice = 0; // Voice(microphone/audio signal processor?) usage
// BLDEnergyWiFi = "1.299869293457897"; // WiFi usage
//
// // BLM is BatteryLifeMonitor class? Not sure how these differ from BLD. Different measurement technique?
// BLMEnergy = "548.7674445304061"; // Total energy usage?
// BLMEnergyAudio = 0; // Audio usage
// BLMEnergyGPS = 0; // GPS chip usage
// PLBatteryUIAppBundleIDKey = "com.Company.App";
// PLBatteryUIAppEnergyValueKey = 22; // This appears to be the total app battery % drain that shows up in Settings
// PLBatteryUIAppNameKey = AppName;
// PLBatteryUIAppQualifiersKey = (2); // Maybe this corresponds to the 'Background Activity' in Settings?
// PLBatteryUIAppTypeKey = 0; // Not sure. Registered background activity types?
// background = "467.7879950688874"; // Time running in the background (in seconds?)
// }
#import "UIDevice+HBAdditions.h"
#import <dlfcn.h>
@implementation UIDevice (UIDevice)
- (NSDictionary *)_usageStastics;
{
NSDictionary *output = nil;
void * handle = dlopen("/System/Library/PrivateFrameworks/PowerLog.framework/PowerLog", RTLD_LAZY);
NSDictionary *(*PLBatteryUsageUIQuery)(NSString *key, NSDictionary *dict) = dlsym (handle, "PLBatteryUsageUIQuery");
if (PLBatteryUsageUIQuery) {
output = PLBatteryUsageUIQuery (@"PLBatteryUIQueryFunctionKey", @{@"PLBatteryUIQueryFunctionKey": @0});
}
if (handle) {
dlclose (handle);
}
return output;
}
- (NSDictionary *)dailyUsageStasticsForBundleIdentifier:(NSString *)bundleID;
{
NSDictionary *usage = [self _usageStastics];
if (!usage) {
return nil;
}
NSArray *appsArray = [[usage objectForKey:@"PLBatteryUIQueryRangeDayKey"] objectForKey:@"PLBatteryUIAppArrayKey"];
for (NSDictionary *dict in appsArray) {
if ([[dict objectForKey:@"PLBatteryUIAppBundleIDKey"] isEqualToString:bundleID]) {
return dict;
}
}
return nil;
}
- (NSDictionary *)weeklyUsageStasticsForBundleIdentifier:(NSString *)bundleID;
{
NSDictionary *usage = [self _usageStastics];
if (!usage) {
return nil;
}
NSArray *appsArray = [[usage objectForKey:@"PLBatteryUIQueryRangeWeekKey"] objectForKey:@"PLBatteryUIAppArrayKey"];
for (NSDictionary *dict in appsArray) {
if ([[dict objectForKey:@"PLBatteryUIAppBundleIDKey"] isEqualToString:bundleID]) {
return dict;
}
}
return nil;
}
@end
@quicklywilliam
Copy link
Author

In case it is not obvious, this is (very) private API. Don’t ship it to the App Store.

@lyonanderson
Copy link

[Shameless self promotion] - I've been interested in this stuff for ages. I've got more info here - http://www.lyonanderson.org/blog/2014/11/05/ios-diagnostics-part-2/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment