These APIs have not been audited for nullability, so they all return unmanaged values that are also implicitly unwrapped optionals. To call them safely you must:
-
Check for nil
, otherwise if they fail you’l trap.
-
Call either takeRetainedValue()
or takeUnretainedValue()
depending on whether the document say you are expected to release the value or not.
So, you need code like that shown at the end of this post. Some notes:
-
The docs for IOPSCopyPowerSourcesInfo
and IOPSCopyPowerSourcesList
say to release the value, hence the takeRetainedValue()
.
-
The docs for IOPSGetPowerSourceDescription
say not to release the value, hence takeUnretainedValue()
.
-
The keys for the dictionary are defined in <IOKit/ps/IOPSKeys.h>
.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
import Foundation
import IOKit.ps
func test() {
guard
let psi = IOPSCopyPowerSourcesInfo()?.takeRetainedValue(),
let cf = IOPSCopyPowerSourcesList(psi)?.takeRetainedValue()
else { … handle error … }
let psl = cf as [CFTypeRef]
for ps in psl {
guard let cfd = IOPSGetPowerSourceDescription(psi, ps)?.takeUnretainedValue() else { … handle error … }
let d = cfd as! [String: Any]
guard
let psID = d[kIOPSPowerSourceIDKey] as? Int,
let psTypeStr = d[kIOPSTypeKey] as? String,
let psType = PowerSourceType(string: psTypeStr)
else { … handle error … }
print(psID, psType)
}
}
enum PowerSourceType {
case ups
case internalBattery
}
extension PowerSourceType {
init?(string: String) {
switch string {
case kIOPSUPSType: self = .ups
case kIOPSInternalBatteryType: self = .internalBattery
default: return nil
}
}
}