You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用中如何获取蓝牙外接物理键盘的唯一标识符?

解决蓝牙键盘唯一标识符获取问题

针对非BLE、非MFi的蓝牙键盘,通过GCKeyboard无法获取唯一ID的情况,可以借助IOKit框架枚举HID设备的方式来获取设备唯一标识,再与GCKeyboard实例关联。

核心思路

GCKeyboard属于GameController框架,对非MFi设备的支持有限,无法提供稳定的唯一ID。而所有输入类蓝牙键盘都属于HID(人机接口设备)范畴,IOKit可以直接枚举这类设备并提取唯一标识(如序列号、设备唯一ID),再通过厂商名称等特征与GCKeyboard实例匹配关联。

具体实现(Swift)

  1. 导入所需框架
import GameController
import IOKit.hid
  1. 枚举连接的蓝牙键盘并获取唯一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
}
  1. 关联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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:27:39