iOS应用中如何获取蓝牙外接物理键盘的唯一标识符?
解决蓝牙键盘唯一标识符获取问题
针对非BLE、非MFi的蓝牙键盘,通过GCKeyboard无法获取唯一ID的情况,可以借助IOKit框架枚举HID设备的方式来获取设备唯一标识,再与GCKeyboard实例关联。
核心思路
GCKeyboard属于GameController框架,对非MFi设备的支持有限,无法提供稳定的唯一ID。而所有输入类蓝牙键盘都属于HID(人机接口设备)范畴,IOKit可以直接枚举这类设备并提取唯一标识(如序列号、设备唯一ID),再通过厂商名称等特征与GCKeyboard实例匹配关联。
具体实现(Swift)
- 导入所需框架
import GameController import IOKit.hid
- 枚举连接的蓝牙键盘并获取唯一ID
func fetchConnectedKeyboardUniqueIDs() -> [String] { var uniqueIDs = [String]() // 创建HID管理器 guard let manager = IOHIDManagerCreate(kCFAllocatorDefault, IOOptionBits(kIOHIDManagerOptionNone)) else { return uniqueIDs } // 匹配键盘类设备(通用桌面页,键盘用途) let matchingCriteria = [ kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop, kIOHIDDeviceUsageKey: kHIDUsage_GD_Keyboard ] as CFDictionary IOHIDManagerSetDeviceMatching(manager, matchingCriteria) IOHIDManagerOpen(manager, IOOptionBits(kIOHIDManagerOptionNone)) // 获取所有匹配的设备 guard let devices = IOHIDManagerCopyDevices(manager) as? [IOHIDDevice] else { IOHIDManagerClose(manager, IOOptionBits(kIOHIDManagerOptionNone)) return uniqueIDs } for device in devices { // 优先提取序列号,其次提取设备唯一ID if let serialNumber = IOHIDDeviceGetProperty(device, kIOHIDSerialNumberKey) as? String { uniqueIDs.append(serialNumber) } else if let deviceUniqueID = IOHIDDeviceGetProperty(device, kIOHIDDeviceUniqueIDKey) as? String { uniqueIDs.append(deviceUniqueID) } } IOHIDManagerClose(manager, IOOptionBits(kIOHIDManagerOptionNone)) return uniqueIDs }
- 关联
GCKeyboard与唯一ID
通过GCKeyboard.coalesced获取键盘实例后,将其vendorName与IOKit设备的kIOHIDManufacturerKey属性匹配,即可对应到唯一ID:
func associateKeyboardWithUniqueID() { guard let keyboard = GCKeyboard.coalesced else { return } let keyboardVendor = keyboard.vendorName ?? "" guard let manager = IOHIDManagerCreate(kCFAllocatorDefault, IOOptionBits(kIOHIDManagerOptionNone)) else { return } let matchingCriteria = [ kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop, kIOHIDDeviceUsageKey: kHIDUsage_GD_Keyboard ] as CFDictionary IOHIDManagerSetDeviceMatching(manager, matchingCriteria) IOHIDManagerOpen(manager, IOOptionBits(kIOHIDManagerOptionNone)) if let devices = IOHIDManagerCopyDevices(manager) as? [IOHIDDevice] { for device in devices { if let vendor = IOHIDDeviceGetProperty(device, kIOHIDManufacturerKey) as? String, vendor == keyboardVendor { if let serial = IOHIDDeviceGetProperty(device, kIOHIDSerialNumberKey) as? String { print("当前键盘唯一ID:\(serial)") } else if let uid = IOHIDDeviceGetProperty(device, kIOHIDDeviceUniqueIDKey) as? String { print("当前键盘唯一ID:\(uid)") } break } } } IOHIDManagerClose(manager, IOOptionBits(kIOHIDManagerOptionNone)) }
注意事项
- 权限要求:macOS下需要开启「输入监控」隐私权限;iOS下需确保应用有访问外部设备的权限。
- 匹配容错:若存在同厂商多键盘的情况,可结合更多特征(如设备产品名称
kIOHIDProductKey)优化匹配逻辑。
内容的提问来源于stack exchange,提问作者Sergio Magoo Quintero
相关产品推荐
相关产品推荐

