Skip to content

Instantly share code, notes, and snippets.

@myell0w
Last active October 31, 2023 11:21
Show Gist options
  • Save myell0w/d8dfabde43f8da543f9c to your computer and use it in GitHub Desktop.
Save myell0w/d8dfabde43f8da543f9c to your computer and use it in GitHub Desktop.
Detect if there's an external keyboard attached (iOS)
// direct check for external keyboard
+ (BOOL)_isExternalKeyboardAttached
{
BOOL externalKeyboardAttached = NO;
@try {
NSString *keyboardClassName = [@[@"UI", @"Key", @"boa", @"rd", @"Im", @"pl"] componentsJoinedByString:@""];
Class c = NSClassFromString(keyboardClassName);
SEL sharedInstanceSEL = NSSelectorFromString(@"sharedInstance");
if (c == Nil || ![c respondsToSelector:sharedInstanceSEL]) {
return NO;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
id sharedKeyboardInstance = [c performSelector:sharedInstanceSEL];
#pragma clang diagnostic pop
if (![sharedKeyboardInstance isKindOfClass:NSClassFromString(keyboardClassName)]) {
return NO;
}
NSString *externalKeyboardSelectorName = [@[@"is", @"InH", @"ardw", @"areK", @"eyb", @"oard", @"Mode"] componentsJoinedByString:@""];
SEL externalKeyboardSEL = NSSelectorFromString(externalKeyboardSelectorName);
if (![sharedKeyboardInstance respondsToSelector:externalKeyboardSEL]) {
return NO;
}
externalKeyboardAttached = ((BOOL ( *)(id, SEL))objc_msgSend)(sharedKeyboardInstance, externalKeyboardSEL);
} @catch(__unused NSException *ex) {
externalKeyboardAttached = NO;
}
return externalKeyboardAttached;
}
// observe change of external keyboard
+ (void)_registerForExternalKeyboardChangeNotification
{
CFNotificationCenterRef notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
if (notificationCenter != NULL) {
CFNotificationCenterAddObserver(notificationCenter, NULL, MNExternalKeyboardStatusDidChange, CFSTR("GSEventHardwareKeyboardAttached"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
}
}
static void MNExternalKeyboardStatusDidChange(CFNotificationCenterRef notificationCenter, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
// external keyboard state changed…
}
@jhersh
Copy link

jhersh commented Feb 2, 2015

I've just had an app using a modified version of this code accepted into Apple Testflight. That's no app store, but a good sign...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment