How to see if Mac is charging in Swift

Hi, i'm trying to figure out how to detect if the Mac is currently charging in my Swift application. I found lots of information regarding how to do this with UIDevice, but found no information regarding it's MacOS counterpart. Would someone mind pointing me in the right direction? All I need is a simple bool: charging - true/false. Thanks so much!

Accepted Reply

All I need is a simple bool: charging - true/false.

Do you mean:

  • Is connected to an external power adapter?

  • Is actively charging the battery?

These are different things. You can get the former with:

import IOKit.ps

let isPowerAdapterConnected = IOPSCopyExternalPowerAdapterDetails()?.takeRetainedValue() != nil

The latter is more complex. You can iterate through all the power sources looking at the

kIOPSIsChargingKey
key like so:
guard let blob = IOPSCopyPowerSourcesInfo()?.takeRetainedValue() else {
    return
}
guard let sources = IOPSCopyPowerSourcesList(blob)?.takeRetainedValue() as [CFTypeRef]? else {
    return
}
for source in sources {
    guard let sourceInfo = IOPSGetPowerSourceDescription(blob, source)?.takeRetainedValue() as? [String:Any] else {
        continue
    }
    guard let isCharging = sourceInfo[kIOPSIsChargingKey] as? Bool else {
        continue
    }
    print(isCharging)
}

but you’ll need to handle various edge cases (Macs without a battery; Macs with an external battery, aka a UPS; and so on).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • Hi, I think when you call IOPSGetPowerSourceDescription(blob, source)?

    you should call .takeUnretainedValue()

    instead of .takeRetainedValue()

    otherwise the program can crash.

  • Hi, in IOPSGetPowerSourceDescription(blob, source)?.takeRetainedValue(), I think you should instead call .takeUnretainedValue(), otherwise the program can crash.

Add a Comment

Replies

You could detect if level is changing https://stackoverflow.com/questions/29278961/check-mac-battery-percentage-in-swift

All I need is a simple bool: charging - true/false.

Do you mean:

  • Is connected to an external power adapter?

  • Is actively charging the battery?

These are different things. You can get the former with:

import IOKit.ps

let isPowerAdapterConnected = IOPSCopyExternalPowerAdapterDetails()?.takeRetainedValue() != nil

The latter is more complex. You can iterate through all the power sources looking at the

kIOPSIsChargingKey
key like so:
guard let blob = IOPSCopyPowerSourcesInfo()?.takeRetainedValue() else {
    return
}
guard let sources = IOPSCopyPowerSourcesList(blob)?.takeRetainedValue() as [CFTypeRef]? else {
    return
}
for source in sources {
    guard let sourceInfo = IOPSGetPowerSourceDescription(blob, source)?.takeRetainedValue() as? [String:Any] else {
        continue
    }
    guard let isCharging = sourceInfo[kIOPSIsChargingKey] as? Bool else {
        continue
    }
    print(isCharging)
}

but you’ll need to handle various edge cases (Macs without a battery; Macs with an external battery, aka a UPS; and so on).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • Hi, I think when you call IOPSGetPowerSourceDescription(blob, source)?

    you should call .takeUnretainedValue()

    instead of .takeRetainedValue()

    otherwise the program can crash.

  • Hi, in IOPSGetPowerSourceDescription(blob, source)?.takeRetainedValue(), I think you should instead call .takeUnretainedValue(), otherwise the program can crash.

Add a Comment