Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetch the battery status of my MacBook with Swift

I want to setup a Playground to fetch the battery status of my macbook.

I have already tried the following:

import Cocoa
import IOKit
import Foundation

var blob = IOPSCopyPowerSourcesInfo()

I am currently receiving an error as below

Use of unresolved identifier 'IOPSCopyPowerSourcesInfo'

like image 784
Maanas S. Bukkuri Avatar asked Dec 05 '22 20:12

Maanas S. Bukkuri


1 Answers

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:

  1. Add IOKit.framework to your project (click + in Linked Frameworks and Libraries)

  2. Create a new empty .m file, whatever its name. Xcode will then ask if it should make a "bridging header". Say YES.

  3. 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)

  4. You can now access most of the IOPowerSources functions.

Example:

func getBatteryStatus() -> String {
    let timeRemaining: CFTimeInterval = IOPSGetTimeRemainingEstimate()
    if timeRemaining == -2.0 {
        return "Plugged"
    } else if timeRemaining == -1.0 {
        return "Recently unplugged"
    } else {
        let minutes = timeRemaining / 60
        return "Time remaining: \(minutes) minutes"
    }
}

let batteryStatus = getBatteryStatus()
print(batteryStatus)

Note: I couldn't access constants like kIOPSTimeRemainingUnlimited and kIOPSTimeRemainingUnknown so I used their raw values (-2.0 and -1.0) but it would be better to find these constants if they still exist somewhere.

Another example, with IOPSCopyPowerSourcesInfo:

let blob = IOPSCopyPowerSourcesInfo()
let list = IOPSCopyPowerSourcesList(blob.takeRetainedValue())
print(list.takeRetainedValue())

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;
}
)

like image 50
Eric Aya Avatar answered Dec 26 '22 10:12

Eric Aya