Как я могу получить уровень заряда батареи IOBluetoothDevice, используя Swift и AppKit (Xcode для macOS)

#swift #macos #cocoa #appkit

#swift #macos #какао #appkit

Вопрос:

Я использую Xcode для разработки приложения для macOS на основе Cocoa amp; AppKit, написанного на Swift.

Я использую объекты IOBluetoothDevice во всем своем приложении, и я хочу иметь возможность отображать уровни заряда батареи устройств, если они доступны.

Я ожидаю, что устройства, уровень заряда батареи которых отображается в настройках Bluetooth ОС (см. Изображение Ниже), Также будут доступны программно (например, AirPods, Magic Keyboard и т. Д.). Однако я нигде не смог этого найти.

Я также думал о выполнении команды терминала и нашел этот поток, но он также не сработал.

Спасибо

Уровень заряда батареи устройства Bluetooth, доступный для ОС

Комментарии:

1. не вижу, чтобы кто-то еще искал это, но это то, что я нашел как частный api github.com/w0lfschild/macOS_headers/blob /…

Ответ №1:

Вы можете получить уровень заряда батареи устройств Bluetooth из IORegistry с помощью IOKit.

Это простой пример получения уровня заряда батареи для Magic Trackpad 2

 import IOKit

var serialPortIterator = io_iterator_t()
var object : io_object_t
let port: mach_port_t
if #available(macOS 12.0, *) {
    port = kIOMainPortDefault // New name in macOS 12 and higher
} else {
    port = kIOMasterPortDefault // Old name in macOS 11 and lower
}
let matchingDict : CFDictionary = IOServiceMatching("AppleDeviceManagementHIDEventService")
let kernResult = IOServiceGetMatchingServices(port, matchingDict, amp;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)
  

Для других устройств вы должны заменить AppleDeviceManagementHIDEventService и Trackpad2 соответствующие значения. Вы можете отобразить всю IORegistry в Terminal.app с ioreg -l помощью .

Комментарии:

1. Спасибо! Указан ли где-нибудь список всех возможных имен устройств? Или как определить, подключены ли у меня, например, два геймпада одной и той же модели (скажем, они поддерживают отчеты о заряде батареи), что BatteryPercent относится к этому конкретному геймпаду?

2. Нет, это много исследований и проб и ошибок. Например, в Terminal.app отфильтруйте строки, содержащие BatteryPercent , с grep помощью или awk и найдите узел дерева и класс окружающего объекта. И для различения устройств есть другие свойства, такие как поставщик или, возможно, серийный номер.

3. Я удивлен, что нет лучшего API, поэтому вы можете подписаться на batteryPercentChanged или что-то в этом роде. Я сомневаюсь, что виджет строки меню Bluetooth просто проверяет уровень заряда батареи внутри цикла for каждые 5 секунд.

4. Я уверен, что есть API для наблюдения за свойствами в IOReg. Довольно низкоуровневые C-обратные вызовы

5. @meneroush Я имею в виду, что меню, вероятно, просто запрашивает значение, когда открывается подменю. Зачем ему нужно соблюдать значение?