5

I am building a custom suggestion/autocorrection feature in an iOS app. It must detect accidental adjacent keypresses and compare this to a known word list to suggest the word it thinks the user intended to type.

For example, if the custom word list contains cat, dog, monkey, and the user types cst, the app can determine that the most likely word was cat (because s is adjacent to the a key)

QWERTY keyboard showing cst

This will work on a standard QWERTY keyboard, but what happens if the user is using an AZERTY keyboard?

enter image description here

For the autocorrect/suggest to work reliably, the app must be able to detect the keyboard layout in use.

In iOS, it is possible to obtain a UITextInputMode object from a UITextField. This object has a primaryLanguage (string) property, which will display the locale (e.g. en-GB), but this does not contain enough granularity to distinguish between English (Australia) QWERTY and English (Australia) AZERTY. In both cases, the primaryLanguage is en-AU.

Is it possible to detect the keyboard layout in iOS?

Wheelie
  • 3,866
  • 2
  • 33
  • 39

3 Answers3

1

I have not been able to find a clean solution to this problem. Maybe this would be worth a TSI ticket to discuss it with Apple employees.

I know that this will not be a satisfying answer, but I would still like to share my thoughts here for future readers:

  1. Private API of UITextInputMode:

    textField.textInputMode?.value(forKey: "identifierWithLayouts")

    This will return a string like de_DE@sw=QWERTZ-German;hw=Automatic from which you can infer the keyboard layout.

  2. UserDefaults

    UserDefaults.standard.object(forKey: "AppleKeyboards")

    This will return a list of all keyboards that the user has installed. In most cases, this will only be one language (besides the emoji keyboard). For example:

    Optional(<__NSCFArray 0x600003b8e6c0>(en_US@sw=QWERTY;hw=Automatic,emoji@sw=Emoji))

    You could also iterate over UserDefaults.standard.dictionaryRepresentation() and search for QWERTZ/QWERTY/AZERTY within the values.

  3. With much manual effort, you could maybe encode UITextInputModes to binary data in all ambiguous cases like en_AU. Something like NSKeyedArchiver.archivedData(withRootObject:textField.textInputMode, requiringSecureCoding: false) can then be used to compare binary encodings of the user's textInputMode at runtime.

jraufeisen
  • 3,005
  • 7
  • 27
  • 43
0

I have found this old question that may have a solution for you. No sure it's still working, but it shows in the question how to get the current instaled keyboards, and someone provided a "gray area" solution, as it seems that there is no direct way to achieve what you intend to do. Hope this help.

OthmanT
  • 223
  • 3
  • 13
0

AppleLanguages object at index 0 is common way to get input language. Instead of trying to determinate which language users are using and default layout, as far I worked with custom keyboard extension, I used one of recommended ways from Apple: use separate keyboard layout for each language. In other way I don't think you will have a stable and productive prediction, auto correct, by the way. As for auto correct I used SymSpell (https://github.com/AmitBhavsarIphone/SymSpell) and different dictionaries from https://github.com/wolfgarbe/SymSpell/tree/master/SymSpell.FrequencyDictionary to make my own RealmDb for each language. So far it was a little work to do, but finally my keyboard extension was publisehd in App Store. [Note: I am not related with SynSpell owners or coders] See images enter image description here

enter image description here

enter image description here

ares777
  • 3,590
  • 1
  • 22
  • 23