6

I have been trying to check the mac battery level programmatically.it can be done on ios but i want to do it in mac.i found some resources on stackoverflow but those links were deprecated. Any Ideas?

Zeist
  • 635
  • 1
  • 7
  • 17

4 Answers4

5

First create a "Umbrella-Bridging-Header.h" with the content:

#import <IOKit/ps/IOPowerSources.h>

then in main.swift

import Foundation

println("Hello, World!")
let timeRemaining = IOPSGetTimeRemainingEstimate ()
println("timeRemaining: \(timeRemaining)")
Isidoro Ghezzi
  • 104
  • 1
  • 3
2

If you don't want to add Objective-C bridging and you need just to know a couple of values. Then you could use this function.

func getBatteryState() -> [String?]
{
    let task = Process()
    let pipe = Pipe()
    task.launchPath = "/usr/bin/pmset"
    task.arguments = ["-g", "batt"]
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String

    let batteryArray = output.components(separatedBy: ";")
    let source = output.components(separatedBy: "'")[1]
    let state = batteryArray[1].trimmingCharacters(in: NSCharacterSet.whitespaces).capitalized
    let percent = String.init(batteryArray[0].components(separatedBy: ")")[1].trimmingCharacters(in: NSCharacterSet.whitespaces).characters.dropLast())
    var remaining = String.init(batteryArray[2].characters.dropFirst().split(separator: " ")[0])
    if(remaining == "(no"){
        remaining = "Calculating"
    }
    return [source, state, percent, remaining]
}

print(getBatteryState().flatMap{$0}) -> "AC Power", "Discharging", "94", "3:15"

pmset is a very old command line function which is very unlikely to change in the future. Of course this does not give extended properties of power options like mAh and so on, but it was enough for me, because I just needed to know is it charging or not and how much percent battery has currently.

Just my 2 cents. I understand if people will find this discouraging to use.

N.B. If charging - remaining will show how long until it's fully charged. If discharging - it will show how long until it's discharged.

Just A Minnion
  • 161
  • 2
  • 9
1

First, you can see the answer here on how to include Objective-C code in your swift project (very good post btw).

Then, check out the IOMPowerSource class. It should include everything you need to report the status of the computer's power information.

Community
  • 1
  • 1
Jordan
  • 2,992
  • 2
  • 20
  • 29
1

Swift 2 Version of the answer of @Just A Minnion

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var label: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        label.stringValue = String(getBatteryState().flatMap{$0})
    }

    func getBatteryState() -> [String?] {     
        let task = NSTask()
        let pipe = NSPipe()

        task.launchPath = "/usr/bin/pmset"
        task.arguments = ["-g", "batt"]
        task.standardOutput = pipe
        task.launch()

        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
        let batteryArray = output.componentsSeparatedByString(";")
        let source = output.componentsSeparatedByString("'")[1]
        let state = batteryArray[0].stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).capitalizedString
        let percent = String.init(batteryArray[0].componentsSeparatedByString(")")[0].stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()))
        var remaining = String.init(batteryArray[0].characters.dropFirst().split(" ")[1])

        if (remaining == "(no") {
            remaining = "Calculating"
        }
        return [source, state, percent, remaining]
    }
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220