Skip to content

Instantly share code, notes, and snippets.

@cisoun
Last active August 13, 2024 11:57
Show Gist options
  • Save cisoun/765f807e78a9fe151fe5c26f1d463fb8 to your computer and use it in GitHub Desktop.
Save cisoun/765f807e78a9fe151fe5c26f1d463fb8 to your computer and use it in GitHub Desktop.
Implementing a keyboard

Implementing a keyboard

Recommendations

General

  • Use the text provider from the OS to handle the texts within the apps from the keyboard.
    • TextDocumentProxy on iOS.
    • InputMethodService on Android.
  • Loading must be fast (ressources might not be reused each time the keyboard appears).
  • Always dispose objects you don't need at runtime.

Logic

  • Consider extendable predictions system.
    • Allows a developer to add many systems.
    • Allows to enable/disable a predictions system on the fly.
  • Consider running the predictions computation in threads (or thread pool).
    • Use cancellable threads to stop predictions computation on new input.
    • Always wait (joining threads) for all predictions threads to finish before showing the results to the user.
  • SQLite dictionaries to store words are fine.
    • 20k words per language is enough on mobile.
    • If needed, load words for only one language at at time.

User Interface/experience

  • At startup, show the keyboard even if the predictions systems are still loading. The user will type and predictions will show up when ready.
  • For a good user experience, predictions should not take more than 200 ms to compute.
  • On mobile/tablet, proposing 5 predictions is enough.
  • Consider multiple layouts (qwertz/azerty/...).
  • Consider theming.
  • Build your layout by code and not use a resource file to define it. It will often be lighter in memory and it is espcially recommended to do so in iOS.
  • Consider supporting multiple screen orientations (landscape/portrait) and sizes.
    • Use relative sizes if possible.

OS Specificities

iOS

  • Memory usage for keyboard extensions is usually limited to around 30 Mb in memory. The system will trigger a warning when the extension reaches this limit. This threshold is not fixed and depends on what the system can provide.
  • Each time the keyboard appears and dissappears, all the ressources are loaded and disposed.

Lifecycle

WARNING: This section is a work in progress!

  1. Main thread (UI) launches.
    1. Load preferences.
    2. Load and show interface.
  2. Launch second thread.
    1. Load dictionary.
    2. Load predictions systems.
    3. Set keyboard as ready.
  3. User types an input.
    1. A timer waits 200 ms and is reseted each time a key is pressed.
    2. When the 200 ms have elapsed, pass the input to the predictions systems.
  4. Run the predictions.
    1. Cancel the running predictions if necessary.
    2. Run the predictions in threads with the last input.
    3. Join the prediction threads (wait them to finish).
    4. Return all results.
  5. Sort the predictions by
    1. Occurencies.
    2. Frequency.
    3. ...
  6. Show the predictions.
  7. User selects a prediction.
    1. Increment its frequency in the dictionary.
    2. Replace the current word by the selected prediction.
  8. The users quit the application (close the keyboard).
    1. Normalize the frequency of the words in the dictionary.
    2. Free all ressources.
    3. Exit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment