iOS 14下Objective-C连接多个GCKeyboard的技术求助
解决iOS 14中同时连接两个GCKeyboard设备的问题
我来帮你搞定同时连接两个蓝牙数字键盘的需求,先梳理下现有代码里的几个小问题,再给你完整的实现方案:
现有代码的核心问题
- 断开逻辑不准确:之前的断开处理没有判断具体是哪个键盘断开,只是按顺序置空,会导致误判(比如断开右键盘时可能错误清空左键盘引用)
- 缺少启动时已连接设备的检测:只能靠连接通知捕获新设备,App启动前已经连接的键盘无法被识别
- 变量管理不规范:直接在方法外声明的
leftKeyboard/rightKeyboard应该改为类属性,避免作用域问题
完整修正后的代码实现
首先在你的类中添加属性声明(建议在.m的分类里或者.h中):
@interface YourViewController () @property (nonatomic, strong) GCKeyboard *leftKeyboard; @property (nonatomic, strong) GCKeyboard *rightKeyboard; @end
然后是核心实现:
- (void)viewDidLoad { [super viewDidLoad]; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; // 注册键盘连接/断开通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasConnected:) name:GCKeyboardDidConnectNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasDisconnected:) name:GCKeyboardDidDisconnectNotification object:nil]; // 启动时检查已连接的键盘(解决冷启动时已连接设备无法识别的问题) [self checkPreConnectedKeyboards]; } // 检查App启动前已连接的键盘 - (void)checkPreConnectedKeyboards { for (GCController *controller in [GCController controllers]) { if (controller.keyboard) { [self handleNewConnectedKeyboard:controller.keyboard]; } } } // 统一处理键盘连接逻辑(复用初始化和通知触发的场景) - (void)keyboardWasConnected:(NSNotification *)notification { GCKeyboard *keyboard = (GCKeyboard *)notification.object; [self handleNewConnectedKeyboard:keyboard]; } - (void)handleNewConnectedKeyboard:(GCKeyboard *)keyboard { if (!self.leftKeyboard) { self.leftKeyboard = keyboard; NSLog(@"Left Keyboard connected: %@", keyboard.description); [self updateStatusLabel:[NSString stringWithFormat:@"Left Keyboard CONNECTED:\n%@", keyboard.description]]; } else if (!self.rightKeyboard) { self.rightKeyboard = keyboard; NSLog(@"Right Keyboard connected: %@", keyboard.description); [self updateStatusLabel:[NSString stringWithFormat:@"Right Keyboard CONNECTED:\n%@", keyboard.description]]; } else { // 超过两个设备时的提示 NSLog(@"Third keyboard ignored: %@", keyboard.description); [self updateStatusLabel:@"Only two keyboards are supported!"]; } // 为新连接的键盘设置输入监听 [self setupKeyboardInputHandler:keyboard]; } // 修正后的键盘断开逻辑(准确判断断开的设备) - (void)keyboardWasDisconnected:(NSNotification *)notification { GCKeyboard *disconnectedKeyboard = (GCKeyboard *)notification.object; if (self.leftKeyboard == disconnectedKeyboard) { NSLog(@"Left Keyboard disconnected: %@", disconnectedKeyboard.description); [self updateStatusLabel:[NSString stringWithFormat:@"Left Keyboard DISCONNECTED:\n%@", disconnectedKeyboard.description]]; self.leftKeyboard = nil; } else if (self.rightKeyboard == disconnectedKeyboard) { NSLog(@"Right Keyboard disconnected: %@", disconnectedKeyboard.description); [self updateStatusLabel:[NSString stringWithFormat:@"Right Keyboard DISCONNECTED:\n%@", disconnectedKeyboard.description]]; self.rightKeyboard = nil; } } // 为键盘设置输入事件处理(区分左右键盘) - (void)setupKeyboardInputHandler:(GCKeyboard *)keyboard { keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *input, GCKey key, BOOL pressed) { if (!pressed) return; // 只处理按下事件,忽略抬起 NSString *keyText = [self convertGCKeyToString:key]; if (keyboard == self.leftKeyboard) { NSLog(@"Left Keyboard pressed: %@", keyText); // 这里添加左键盘的输入处理逻辑 } else if (keyboard == self.rightKeyboard) { NSLog(@"Right Keyboard pressed: %@", keyText); // 这里添加右键盘的输入处理逻辑 } }; } // 辅助方法:将GCKey转换为可读字符串 - (NSString *)convertGCKeyToString:(GCKey)key { switch (key) { case GCKey0: return @"0"; case GCKey1: return @"1"; case GCKey2: return @"2"; case GCKey3: return @"3"; case GCKey4: return @"4"; case GCKey5: return @"5"; case GCKey6: return @"6"; case GCKey7: return @"7"; case GCKey8: return @"8"; case GCKey9: return @"9"; // 可根据需求添加更多按键映射 default: return [NSString stringWithFormat:@"Unknown Key: %lu", (unsigned long)key]; } } // 安全更新UI(确保在主线程执行) - (void)updateStatusLabel:(NSString *)text { dispatch_async(dispatch_get_main_queue(), ^{ self.statusLabel.text = text; }); } // 记得在销毁时移除通知观察者 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
关键优化点说明
- 启动时检测已连接设备:利用
GCController的controllers方法遍历所有已连接的控制器,取出其中的keyboard属性,解决冷启动时已连接键盘无法被识别的问题 - 准确判断断开设备:通过对象引用直接比较,确保断开操作只影响对应的键盘实例
- 复用连接逻辑:把连接处理抽成独立方法,避免初始化和通知触发的场景重复写代码
- 区分设备输入:在按键回调中通过比较键盘对象,明确区分左右键盘的输入事件
内容的提问来源于stack exchange,提问作者Val Nenov
相关产品推荐
相关产品推荐

