mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
65 lines
2.2 KiB
Swift
65 lines
2.2 KiB
Swift
import Foundation
|
|
import IOKit.ps
|
|
|
|
/// Lightweight helper for querying macOS battery charging status and ETA.
|
|
final class MacBatteryManager {
|
|
static let shared = MacBatteryManager()
|
|
|
|
private init() {}
|
|
|
|
struct BatteryStatus {
|
|
let timeRemainingMinutes: Int?
|
|
let isCharging: Bool
|
|
let percentage: Int?
|
|
}
|
|
|
|
func currentStatus() -> BatteryStatus {
|
|
guard let sourcesInfo = IOPSCopyPowerSourcesInfo()?.takeRetainedValue(),
|
|
let sourcesList = IOPSCopyPowerSourcesList(sourcesInfo)?.takeRetainedValue() as? [CFTypeRef] else {
|
|
return BatteryStatus(timeRemainingMinutes: nil, isCharging: false, percentage: nil)
|
|
}
|
|
|
|
for source in sourcesList {
|
|
guard let description = IOPSGetPowerSourceDescription(sourcesInfo, source)?.takeUnretainedValue() as? [String: Any],
|
|
let type = description[kIOPSTypeKey] as? String,
|
|
type == kIOPSInternalBatteryType else {
|
|
continue
|
|
}
|
|
|
|
let isCharging = description[kIOPSIsChargingKey] as? Bool ?? false
|
|
let timeRemaining = description[kIOPSTimeToFullChargeKey] as? Int
|
|
let currentCapacity = description[kIOPSCurrentCapacityKey] as? Int
|
|
let maxCapacity = description[kIOPSMaxCapacityKey] as? Int
|
|
|
|
let percentage: Int?
|
|
if let current = currentCapacity, let max = maxCapacity, max > 0 {
|
|
percentage = (current * 100) / max
|
|
} else {
|
|
percentage = nil
|
|
}
|
|
|
|
return BatteryStatus(
|
|
timeRemainingMinutes: timeRemaining,
|
|
isCharging: isCharging,
|
|
percentage: percentage
|
|
)
|
|
}
|
|
|
|
return BatteryStatus(timeRemainingMinutes: nil, isCharging: false, percentage: nil)
|
|
}
|
|
|
|
func formattedTimeToFullCharge() -> String? {
|
|
let status = currentStatus()
|
|
guard status.isCharging, let minutes = status.timeRemainingMinutes, minutes > 0 else {
|
|
return nil
|
|
}
|
|
|
|
let hours = minutes / 60
|
|
let remainingMinutes = minutes % 60
|
|
|
|
if hours > 0 {
|
|
return "\(hours)h \(remainingMinutes)m"
|
|
}
|
|
return "\(remainingMinutes)m"
|
|
}
|
|
}
|