Reputation: 472
Hi i was wondering how to get the current battery capacity in swift.
I have this code
let batteryStatus = getBatteryStatus()
print(batteryStatus)
let blob = IOPSCopyPowerSourcesInfo()
let list = IOPSCopyPowerSourcesList(blob.takeRetainedValue())
let PowerDetail = list.takeRetainedValue()
print(PowerDetail)
And this is my output
(
{
"Battery Provides Time Remaining" = 1;
BatteryHealth = Good;
Current = 3907;
"Current Capacity" = 57;
DesignCycleCount = 1000;
"Is Charging" = 1;
"Is Finishing Charge" = 0;
"Is Present" = 1;
"Max Capacity" = 100;
Name = "InternalBattery-0";
"Power Source State" = "AC Power";
"Time to Empty" = 0;
"Time to Full Charge" = 120;
"Transport Type" = Internal;
Type = InternalBattery;
}
)
Now how do i get the "Current Capacity"
Thank you
Upvotes: 3
Views: 3940
Reputation: 299345
import Foundation
import IOKit.ps
// Take a snapshot of all the power source info
let snapshot = IOPSCopyPowerSourcesInfo().takeRetainedValue()
// Pull out a list of power sources
let sources = IOPSCopyPowerSourcesList(snapshot).takeRetainedValue() as Array
// For each power source...
for ps in sources {
// Fetch the information for a given power source out of our snapshot
let info = IOPSGetPowerSourceDescription(snapshot, ps).takeUnretainedValue() as! [String: AnyObject]
// Pull out the name and capacity
if let name = info[kIOPSNameKey] as? String,
let capacity = info[kIOPSCurrentCapacityKey] as? Int,
let max = info[kIOPSMaxCapacityKey] as? Int {
print("\(name): \(capacity) of \(max)")
}
}
Keep in mind that "current capacity" may not mean what you think it means here. The capacity unit is vendor-defined. Apple power supplies publish capacities from 0-100 percent, but other vendors could provide the information in some other unit (mAh for instance). You would need to divide by the maximum capacity to have a meaningful result.
/*!
* @define kIOPSCurrentCapacityKey
* @abstract CFDictionary key for the current power source's capacity.
*
* @discussion
* <ul>
* <li> Apple-defined power sources will publish this key in units of percent.
* <li> The power source's software may specify the units for this key.
* The units must be consistent for all capacities reported by this power source.
* The power source will usually define this number in units of percent, or mAh.
* <li> Clients may derive a percentage of power source battery remaining by dividing "Current Capacity" by "Max Capacity"
* <li> For power source creators: Providing this key is REQUIRED.
* <li> Type CFNumber kCFNumberIntType (signed integer)
* </ul>
*/
Note that this code is somewhat dangerous. It assumes there are no errors along the way. If there are errors, you'll crash. It's hard to imagine errors here that wouldn't indicate a major power system failure, in which case crashing this app is probably the least of our concerns, but even so, it may be reasonable to be more cautious. If so, you'd write it something like this, which is a bit more complicated, but safer:
import Foundation
import IOKit.ps
enum BatteryError: Error { case error }
do {
// Take a snapshot of all the power source info
guard let snapshot = IOPSCopyPowerSourcesInfo()?.takeRetainedValue()
else { throw BatteryError.error }
// Pull out a list of power sources
guard let sources: NSArray = IOPSCopyPowerSourcesList(snapshot)?.takeRetainedValue()
else { throw BatteryError.error }
// For each power source...
for ps in sources {
// Fetch the information for a given power source out of our snapshot
guard let info: NSDictionary = IOPSGetPowerSourceDescription(snapshot, ps as CFTypeRef)?.takeUnretainedValue()
else { throw BatteryError.error }
// Pull out the name and current capacity
if let name = info[kIOPSNameKey] as? String,
let capacity = info[kIOPSCurrentCapacityKey] as? Int,
let max = info[kIOPSMaxCapacityKey] as? Int {
print("\(name): \(capacity) of \(max)")
}
}
} catch {
fatalError()
}
Upvotes: 12