It doesn't work in a Playground, but it works in a real app.
I couldn't access the IOPowerSources.h
header file with Swift and import IOKit
only, though: I had to make a bridge to Objective-C.
Here's my solution:
Add IOKit.framework
to your project (click +
in Linked Frameworks and Libraries
)
Create a new empty .m
file, whatever its name. Xcode will then ask if it should make a "bridging header". Say YES.
Ignore the .m
file. In the new YOURAPPNAME-Bridging-Header.h
file that Xcode just created, add the line #import <IOKit/ps/IOPowerSources.h>
(and don't add import IOKit
in your Swift file)
You can now access most of the IOPowerSources
functions.
Example:
func getBatteryStatus() -> String {
let timeRemaining: CFTimeInterval = IOPSGetTimeRemainingEstimate()
if timeRemaining == kIOPSTimeRemainingUnlimited {
return "Plugged"
} else if timeRemaining == kIOPSTimeRemainingUnknown {
return "Recently unplugged"
} else {
let minutes = timeRemaining / 60
return "Time remaining: \(minutes) minutes"
}
}
let batteryStatus = getBatteryStatus()
print(batteryStatus)
Another example, with IOPSCopyPowerSourcesInfo
:
let blob = IOPSCopyPowerSourcesInfo()
let list = IOPSCopyPowerSourcesList(blob.takeRetainedValue())
print(list.takeRetainedValue())
Think to release all retained CFValues (here: blob & list) at the function end with:
CFRelease(value) >> here: CFRelease(blob) & CFRelease(list)
Result:
(
{
"Battery Provides Time Remaining" = 1;
BatteryHealth = Good;
Current = 0;
"Current Capacity" = 98;
DesignCycleCount = 1000;
"Hardware Serial Number" = 1X234567XX8XX;
"Is Charged" = 1;
"Is Charging" = 0;
"Is Present" = 1;
"Max Capacity" = 100;
Name = "InternalBattery-0";
"Power Source State" = "AC Power";
"Time to Empty" = 0;
"Time to Full Charge" = 0;
"Transport Type" = Internal;
Type = InternalBattery;
}
)