Limitations of custom iOS keyboards

by Krzysztof Pelczar— iOS Developer

Apple makes it possible to integrate apps with the system even more by introducing their newest technologies like application extensions, force touch, split view, Spotlight. They allow to extend custom functionality and content beyond application.

One of the biggest features introduced in iOS8 are custom keyboards. There are already a lot of custom third-party keyboards available in the App Store which provide a new text entry types (e.g. swipe) the iOS users were waiting for.

Custom keyboards can offer a lot more than the obvious text input functionality. There are keyboards with sets of emoticons, animated GIFs and even providing application like functionalities.

In this article I will share my experience and try to answer frequently asked questions about limitations of custom keyboards.

1. Text input limitations

1. No access to general system keyboard settings (Settings > General > Keyboard).

Custom keyboard can’t get information about user preferences like Auto-Capitalization, Enable Caps Lock Status.

You can implement your own settings which will appear in system Settings bundle. For more information refer to Implementing an iOS Settings Bundle

The biggest disadvantage is no access to language features like: Auto-Correction, Spell-Checking, Predictive text. You must implement those features yourself or use third-party solutions in order to provide good text input functionality.

If you need to provide a test prediction mechanism, there are three classes worth mentioning:

► UILexicon contains dictionary with text shortcuts defined by the user (Settings > General > Keyboard > Shortcuts list) and other common words. It can be fetched using method requestSupplementaryLexiconWithCompletion of UIInputViewController.
- UITextChecker method guessesForWordRange offers simple spell checking functionality.
- UIReferenceLibraryViewController object provides a dictionary service to look up the definition of terms.

► UITextChecker method guessesForWordRange offers simple spell checking functionality.

► UIReferenceLibraryViewController object provides a dictionary service to look up the definition of terms.

2. Custom keyboard is disabled by so-called secure text fields. When 
a user taps in a secure text input object, the system temporarily replaces your custom keyboard with the system keyboard. When the user then taps in a nonsecure text input object, your keyboard automatically resumes.

UITextInputTraits properties set by secure input object:

● secureTextEntry: Bool — used mainly for entering passwords and other confidential data.

● keyboardType: UIKeyboardType — entering phone number, such as phone number field in Contacts. Keyboard type traits: .PhonePad and .NamePhonePad.

3. All third-party keyboards can be blocked entirely by implementing method from UIApplicationDelegate:

4. Text selection is not possible. It’s under control of the application using keyboard, therefore editing menu options like cut, copy and paste are inaccessible. Furthermore, third-party keyboards can’t select text inside the input field, so it’s not possible to imitate system keyboard text input method used to enter Asian languages.

2. Keyboard view limitations

► Showing and hiding keyboard animation quality. 
This is the first thing you will notice while switching between system keyboard and third-party keyboards. Unlike system keyboard which animation is very smooth and pleasing, the custom keyboards have no animation at all or it’s very rough. Sometimes keyboard disappears and appears after short period of time. Let’s hope it will be fixed in the next iOS releases.

► Drawing area is strictly limited to the custom keyboard size.
It is not possible to display key artwork above the top edge of a custom keyboard’s primary view, as the system keyboard does on iPhone when you tap and hold a key in the top row. This can be masked by the smart keyboard design f.e. by adding auto complete bar at the top of the keyboard.

► Keyboard can’t be transparent. Keyboard background is always solid, so it’s not possible to mimic iPad’s split keyboard

► Custom keyboard height can be adjusted at any time using Auto Layout as described in App Extension Programming Guide.
By default, a custom keyboard is sized to match the system keyboard, according to screen size and device orientation. A custom keyboard’s width is always set by the system to equal the current screen width. Keyboard height can be adjusted at any time even if keyboard is already visible.

There’s no limit to keyboard height. It can be full screen, 
but there are few limitations:

● Changing keyboard height can’t be animated.

● Keyboard has no control over system status bar, only the application which launched keyboard does. Full screen keyboard works in a little bit different way depending on the iOS version. In iOS8 status bar is visible and displayed over the keyboard, but in iOS9 status bar is hidden. You must consider those two cases and handle them in the keyboard user interface.

● UIAlertView and UIAlertController are prohibited for keyboards. You must implement your own controls or think of a different way in getting user’s input.

● Even if you can’t use UIAlertView and UIAlertController they still can be launched by the system in cases such as: requesting for permissions to access system resources like photo gallery or incoming push notifications. System alerts get squashed while being displayed over full screen keyboard. There’s no way to accept, cancel or dismiss them. The only solution is to kill application in the task bar which is an unacceptable user experience. This problem does not occur when keyboard height is around half of the screen height or less. Unfortunately there’s no workaround for this. It can be partially solved by requesting access for system resources before opening keyboard in a full screen mode. Unfortunately there’s no workaround for incoming push notifications displayed in Alert mode.

3. Resources access limitations

1. No access to microphone and camera. Dictation input is not possible.

2. Switch Keyboard button.
It is mandatory to provide a way to switch to another keyboard.

On the system keyboard, this affordance appears as a button called the globe key. You tap once to switch to the next keyboard and long press it to view available keyboards.

Third-party keyboard can’t get list of available keyboards, so it’s not possible to implement it as system keyboard does. You can only advance to the next input mode using advanceToNextInputMode() method of UIInputViewController. The keyboard order is managed by the system. 
It becomes very inconvenient if you are using few custom keyboards on 
a daily basis.

3. Full access. By default third-party keyboard is working within it’s own sandbox which is enough for the text input functionality. Doing anything more requires to enable full access (Settings > General > Keyboards > Keyboard). Custom keyboard defines if it needs full access by setting key RequestsOpenAccess in Info.plist file of the application extension.

Full access gives keyboard the following capabilities:

► network connection, complete iCloud functionality,

► access to Location Services, Address Book, Gallery,

► sharing data with it’s containing application,

► access to Game Center and In-App Purchase via the containing application.

Third-party keyboard must handle a situation when full access is disabled thus disabling/limiting its functionality

There’s no direct method to check if full access is enabled, but you can use 
a workaround and check if keyboard has access to UIPasteBoard.

4. Playing audio also requires full access. You can handle audio and video playback (including streaming) inside keyboard which surprisingly works very well. Audio is useful for playing button click sound which can be done using the following method:

The dispatch_async block is necessary, otherwise keyboard will stop working if full access is disabled.

5. No access to UIApplication, therefore some functions are inaccessible, like openURL(url: NSURL) for redirecting user to system Settings in order to enable Full access, or opening other applications. It’s worth mentioning that actually UIApplication reference can actually be obtained by iterating through the responder chain:

However this is prohibited by Apple and your application is likely to be rejected. Only Today widget is allowed to use openURL: method.

4. Info.plist file settings

1. Bundle display name.

The third party keyboard name will be different depending on the place where it is presented.

The standalone extension name is visible in Settings > General > Keyboard > Keyboards > Add New Keyboard.

After adding keyboard it becomes visible in the keyboards list and under the globe key as: “AppName — ExtensionName”.

Secondary text shows the keyboard language.

The base keyboard name is defined under a CFBundleDisplayName key in the Info.plist file of the application extension.

If your extension name is different from application name it will be displayed in the form of “AppName — ExtensionName” and there’s no workaround for it. In order to display single name you must change the extension name to have the exactly the same name as your application. After that it will be presented as “AppName”.

Application and extension name can be localised.

Secondary text is optional and based on the PrimaryLanguage key of Info.plist file. It’s default value is en-US language code. There’s no way to provide custom secondary text nor localise it.

2. IsASCIICapable — determines if keyboard supports ASCII characters.

3. PrefersRightToLeft — preferred direction of default keyboard language.

4. RequestsOpenAccess — allows access to functionalities outside of text input such as network, system resources etc.

5. NSExtensionPrincipalClass — It’s the starting point of the application extension. Third-party keyboard must be a subclass of UIInputViewController.

5. Implementation tips

1. Don’t use Interface Builder, Storyboards, xib files.

For unknown reason creating user interface from resource files takes a lot of time inside custom keyboard extension. Loading view controller from Storyboard can take up to 1 second (depending on it’s subviews and constraints complexity) which causes noticeable glitch and is unacceptable from the end user perspective. There is no workaround for this other than creating user interface using code only.

You can make very complex user interface composed of view controllers, child view controllers, animations and using auto layout.

It’s even possible to embed view controllers inside UINavigationController and make an application alike navigation including UINavigationBar. 
In terms of UIViewControllers there are no limitations at all.

All features of UINavigationController are working perfectly including back gesture and resizing after screen orientation changed.

2. Sometimes it’s better to rely on screen size rather than UIViewController orientation especially during changing keyboard orientation. This can be achieved by:

3. Problems with text input fields.

Interaction with UITextField and UITextView is breaking the UIResponder chain of custom keyboard.

The pointer to UITextDocumentProxy seems to be valid but you won’t be able to insert text anymore.

It is possible to implement a custom control that mimics UITextView behaviour. It is a subclass of UILabel and has an animated cursor which looks almost the same as original one.

4. Memory limitations.

Memory is very limited for custom keyboards (up to 30MB, but it’s not exactly mentioned in documentation). You must pay attention and release objects immediately if they are not needed.

What's interesting is that you can allocate even few hundred of megabytes for a short period of time in order to make some operations and release it after a while.

Once allocated, keyboard is held in memory until system decides to release resources. We can benefit from that, it will be loaded and open instantly after tapping input field.

6. Summary

Third-party keyboards are almost as powerful as other types of application extensions. On the other hand they have a lot of limitations and most likely you will face problems with memory management and performance while building something more than the text input itself.

However using some workarounds and smart keyboard design you can embed even a small application inside.