0

As part of my user on-boarding experience for a custom keyboard I'm developing, I'd like to know whether my custom keyboard is currently active for text entering from within the containing (parent) application.

Is there any way to do this, similar to how you can discover whether the keyboard is installed?

Community
  • 1
  • 1
Aleksander
  • 2,735
  • 5
  • 34
  • 57

1 Answers1

0

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];
}
Aleksander
  • 2,735
  • 5
  • 34
  • 57