Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get IOBluetoothDevice's battery level, using Swift and AppKit (Xcode for MacOS)

I am using Xcode to develop a MacOS app, based on Cocoa & AppKit, written in Swift.

I am using IOBluetoothDevice objects throughout my app, and I want to be able to display the devices' battery levels, if accessible.

I expect that devices which battery levels are visible on the OS's Bluetooth settings (see image below), to be also accessible programmatically (e.g., AirPods, Magic Keyboard, etc.). However, I could not find this anywhere.

I have also thought about executing a terminal command and found this thread, but it did also not work.

Thanks

Bluetooth device battery level available to the OS

like image 317
Ori Avatar asked Apr 21 '19 18:04

Ori


1 Answers

You can get the battery level of Bluetooth devices from the IORegistry with IOKit.

This is a simple example to get the battery level for the Magic Trackpad 2

import IOKit

var serialPortIterator = io_iterator_t()
var object : io_object_t
let masterPort: mach_port_t = kIOMasterPortDefault
let matchingDict : CFDictionary = IOServiceMatching("AppleDeviceManagementHIDEventService")
let kernResult = IOServiceGetMatchingServices(masterPort, matchingDict, &serialPortIterator)

if KERN_SUCCESS == kernResult {
    repeat {
        object = IOIteratorNext(serialPortIterator)
        if object != 0, let percent = IORegistryEntryCreateCFProperty(object, "BatteryPercent" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Int {
            print(percent)
            break
        }
    } while object != 0
    IOObjectRelease(object)
}    
IOObjectRelease(serialPortIterator)

For other devices you have to replace AppleDeviceManagementHIDEventService and Trackpad2 with the appropriate values. You can display the entire IORegistry in Terminal.app with ioreg -l.

like image 82
vadian Avatar answered Sep 22 '22 12:09

vadian