Implement Autocorrect in iOS 8 Keyboard Extension - ios

I'm creating a custom iOS 8 keyboard as a pet project.
I'm trying to replicate the system keyboard as accurately as possible, but building it from the ground up.
I'm largely done with this. The final hurdle I'm encountering is with adding autocorrect to my keyboard. Is there a way I can have the autocorrect behave as it would on the regular system keyboard?
The UILexicon documentation is quite sparse.
EDIT:
Making some progress with this. UILexicon's requestSupplementaryLexiconWithCompletion: method appears to only be returning results from my device's Contacts and keyboard shortcuts. I then went on to see how to autocorrect an NSString and found the UITextChecker class, which has been available since iOS 3.2.
Using this approach I can achieve autocorrect suggestions on individual words, but I'm still investigating the ability to add context-aware autocorrect (e.g. correcting "arctic monkeys" to "Arctic Monkeys").

From the documentation, it seems that UILexicon is to help you to create your own autocorrect, UILexicon has a bunch of UILexiconEntry entries which contain String pairs, the entry contains a userInput String which I assume its supposed to be what the user entered, and documentText which I assume is what you should be replacing that input with. You use func requestSupplementaryLexiconWithCompletion(_ completionHandler: ((UILexicon!) -> Void)!) From UIInputViewController to get this UILexicon.
I am assuming that the UIInputViewController knows what has been written to the documentProxy since it is the one relaying those messages, and thats how it knows what the user has input and in return what to put in the UILexicon..
This is what I gathered from reading the documentation, I have not tested it, though it should not be very hard to test this to verify..
I hope it helps
Daniel

Check out this simple but very effective auto correct implementation
http://norvig.com/spell-correct.html
For auto completion you can implement a trie.

Related

iOS detect keyboard layout (e.g. QWERTY, AZERTY)

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)
This will work on a standard QWERTY keyboard, but what happens if the user is using an AZERTY keyboard?
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?
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:
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.
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.
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.
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.
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

iOS custom keyboard base?

I need to create a custom keyboard that looks/feels pretty much the same like the system keyboards but is for a language that iOS doesn't have:
whenever I have to type using the system keyboard, I'm subject to the autocorrect, which not only gives wrong options, but also learns wrong words for that keyboard's language.
the language I need doesn't use 3 of the 26 Latin letters but it does need diacritics in some others as well as the ' quite often, so it would be nice to repurpose 3 of the keys for that.
My problem is that I'm not interested in creating a keyboard from bare UIViews just to do what in my opinion amount to tweaks to the existing system keyboards. I was dumbstruck when I found out that apparently I do have to recreate the whole experience myself instead of having some Apple-provided basis to build upon. I also can't see most developers being thrilled, so I began to think I may be wrong and there is something we can use after all. Can anyone enlighten me?

Autocorrection and Suggestion for custom keyboard

I want to add Autocorrection and Suggestion to my custom keyboard.
There are already several similar questions on Stack, but there is only said about UILexicon which as I understood is only used to get user's shortcuts and that there is no way to acces Apple Autocorrection and Suggestion library.
I also saw some questions regarding UITextChecker but don't know if it has an access to Apple's native sugesstion library?
May be there are some new classes for that?
I use four different systems for my keyboard:
I have a list of the top 30,000 or so words, ranked in order of the most used to the least used. You can pay for lists, I just got a free one of about 42,000 and edited it down a lot.
guessesForWordRange is provided by Apple. It will guess words that are close to what you have typed. It does a fairly good job, but I had to filter out some things. The top guess sometimes has quotation marks around it, but other then that it works great.
completionsForPartialWordRange is also provided by Apple. It will return completed words, but in alphabetical order, not ranked by usage. Not much good on it's own, but is a great supplement to 1 and 2. (if this worked correctly #1 wouldn't be needed)
Special cases. Mainly for contractions. When someone types didnt, I wanted it to auto choose didn't. So I have almost all contractions specifically programmed in.
So my word suggestions and autocorrection aren't perfect, but it does a decent job.
Hope this helps.
Edit: As of iOS 16 it seems completionsForPartialWordRange is working correctly, so having your own list of words shouldn't be needed anymore.

Custom text field autocorrection

Is it possible to customize the autocorrection of the keyboard when entering text into a text field?
In my app, I have a text field where rather long technical terms have to be entered. If I could provide an additional dictionary with frequent terms, it would incredibly help my users.
I've searched the documentation of the current iOS version and had a peek at the new iOS 8 documentation. QuickType seems similar to what I'm looking for. But is it configurable?
I hope it's doable without creating a custom keyboard. I don't think that's the way to go.
No, at the moment of writing it is simply not possible to add or alter the autocompletion or autocorrect library that Apple uses in combination with it's keyboards. Apple just doesn't allow "tampering" with it's autocompletion/correction and probably for good reason since they are context aware and self learning.
Alternatives you can consider:
1. Create your own keyboard with your own "quick type"
Probably not the best option, since you don't want to alter the keyboard but only autocompletion.
2. Add some kind of autocompletion in your app
There are some autocomplete libraries you could look into like HTAutoCompleteTextField and there are probably other CocoaPods you could look into. I think this would be your best option.
You could also write some sort of autocomplete yourself that shows the options while you type in a table or other kind of UI if you can't find a library that suits you. Not trivial, but could be worth it for your users.

Can one provide a custom source of word suggestions for a UITextField?

I am wondering if it is possible to have a custom dictionary of suggestions when editing in a certain text field in iOS 4.2
As you can see in the picture below, the default dictionary of suggestions is the english dictionary. What I would like to know is that if it is possible to give it, for example, an array of strings so that the text field would only give out those strings as suggestions.
Not easily, unfortunately.
It seems like you have two options if you want to do this and neither look easy.
1. Roll your own suggestion overlay code and disable Apples stuff.
2. (Really sketchy) See if you can leverage the fact that iOS includes names of contacts when entering text. I believe it does this at least to capitalize names, but it may also use this to autocomplete them.

Resources