4

I've read through the documentation and can't seem to find any method of how can I detect if a custom keyboard has been installed in settings>general>keyboards?

Does anyone know of any?

Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195
  • 1
    NDA isn't relevant to this question. http://meta.stackoverflow.com/questions/260734/are-we-permitted-to-discuss-software-under-nda-if-the-nda-is-partly-lifted – CrimsonChris Aug 16 '14 at 22:19
  • @CrimsonChris Even if it were, there is no evidence that I ever signed the NDA, I could just be asking in general... and the people that are answering could also be answering just with their knowledge without have ever coming into an NDA with Apple. :) – Albert Renshaw Aug 18 '14 at 04:26
  • 1
    Couldn't agree more. Bugs me to no end when questions are flagged because the platform in question is still in beta. This question may be a suitable for a bounty. – CrimsonChris Aug 18 '14 at 04:55
  • Why do you need to know if a custom keyboard is installed? Are you sure you don't just need it's height or something? – CrimsonChris Aug 18 '14 at 04:56
  • You could force the keyboard to show _without_ user interaction. Then immediately dismiss it. – CrimsonChris Aug 18 '14 at 13:51
  • @CrimsonChris How do I force a custom keyboard to show? :o – Albert Renshaw Aug 18 '14 at 13:59
  • Add a hidden `UITextView` to the view hierarchy and then call `becomeFirstResponder` on it. This will show _the currently selected_ keyboard. – CrimsonChris Aug 18 '14 at 14:09
  • @CrimsonChris That calls Apple's default iOS keyboard... I'm trying to call my custom keyboard app-extension. – Albert Renshaw Aug 18 '14 at 14:10
  • You want to check if they have the keyboard installed but _not necessarily_ selected? – CrimsonChris Aug 18 '14 at 14:11
  • Looks like you could use `NSUserDefaults` to communicate between your keyboard and companion app. http://stackoverflow.com/questions/24943657/can-a-custom-keyboard-extension-communicate-with-the-companion-app-at-runtime?rq=1 – CrimsonChris Aug 18 '14 at 14:15
  • @CrimsonChris Yes, but in order to do that the custom keyboard must be selected hahaha! Otherwise the custom keyboard code never loads in the first place :) I am currently using NSUserDefaults to communicate haha! – Albert Renshaw Aug 18 '14 at 14:20
  • You should probably update your question clarifying this. It seems you are trying to do something outside of the normal custom keyboard workflow. – CrimsonChris Aug 18 '14 at 14:26
  • @CrimsonChris Uh... how would you reword the question to be more clear? Haha! – Albert Renshaw Aug 18 '14 at 16:38
  • You should clarify that you want to check if a particular keyboard has been _installed_ but **not** _selected_. – CrimsonChris Aug 18 '14 at 16:46
  • @CrimsonChris That's already what the question says? – Albert Renshaw Aug 18 '14 at 16:46

2 Answers2

8

This is possible with NSUserDefaults. Just retrieve the standardUserDefaults object which contains an array of all the keyboards the user has installed for key "AppleKeyboards". Then check if the array contains the bundle identifier for your keyboard extension.

NSArray *keyboards = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleKeyboards"];
NSLog(@"keyboards: %@", keyboards);

// check for your keyboard
NSUInteger index = [keyboards indexOfObject:@"com.example.productname.keyboard-extension"];

if (index != NSNotFound) {
    NSLog(@"found keyboard");
}
Matt
  • 2,329
  • 1
  • 21
  • 23
1

This works for me

func isKeyboardExtensionEnabled() -> Bool {
    guard let appBundleIdentifier = Bundle.main.bundleIdentifier else {
        fatalError("isKeyboardExtensionEnabled(): Cannot retrieve bundle identifier.")
    }

    guard let keyboards = UserDefaults.standard.dictionaryRepresentation()["AppleKeyboards"] as? [String] else {
        // There is no key `AppleKeyboards` in NSUserDefaults. That happens sometimes.
        return false
    }

    let keyboardExtensionBundleIdentifierPrefix = appBundleIdentifier + "."
    for keyboard in keyboards {
        if keyboard.hasPrefix(keyboardExtensionBundleIdentifierPrefix) {
            return true
        }
    }

    return false
}
harryngh
  • 1,789
  • 1
  • 13
  • 6