After doing some further research, I have not yet found a way to accomplish this.
But if anyone is in the same situation, here's a workaround I employed for the time being.
1. Detect keyboard change
Your keyboard will not automatically be the active keyboard after installation, and so if you prompt the user to swap keyboards you can detect such a change with the UITextInputCurrentInputModeDidChangeNotification
. There's no guarantee that the user swapped to your keyboard, as opposed to for example the Emoji keyboard, but that's an assumption I chose to make.
You can use it as such:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChange:) name:UITextInputCurrentInputModeDidChangeNotification object:nil];
}
- (void)keyboardDidChange:(NSNotification *)notification {
// keyboard changed, do your thing here
}
2. Shared app group
Another way to do this would be to set up a shared app group, and write to the Shared User Defaults
from your keyboard once it's activated. Then in your containing application, you can set up a NSTimer
to function as a runloop where you check to see whether the user defaults has been written to. This can for example be something like the current date, and you check to see that it's recent enough (within a few seconds) to indicate a recent change.
I did not employ this because it adds some overhead, but it would be a much more foolproof solution (from the user's point of view) than the keyboard change notification.
Here's an example of how it can be done.
KeyboardViewController.m
:
- (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.bundleID"];
[sharedDefaults setObject:[NSDate date] forKey:@"lastOpenDate"];
[sharedDefaults synchronize];
}
CompanionViewController.m
:
- (void)viewDidLoad {
[super viewDidLoad];
NSTimer *runloop = [NSTimer scheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.bundleID"];
[sharedDefaults synchronize];
NSDate *lastOpenDate = [sharedDefaults objectForKey:@"lastOpenDate"];
if (lastOpenDate != nil && [lastOpenDate timeIntervalSinceNow] > -1.0) {
[timer invalidate];
// keyboard changed, do your thing here
}
}
[runloop fire];
}