Custom Keyboard
A custom keyboard replaces the system keyboard for users who want capabilities such as a novel text input method or the ability to enter text in a language not otherwise supported in iOS. The essential function of a custom keyboard is simple: Respond to taps, gestures, or other input events and provide text, in the form of an unattributed NSString
object, at the text insertion point of the current text input object.
After a user chooses a custom keyboard, it becomes the keyboard for every app the user opens. For this reason, a keyboard you create must, at minimum, provide certain base features. Most important, your keyboard must allow the user to switch to another keyboard.
Understand User Expectations for Keyboards
To understand what users expect of your custom keyboard, study the system keyboard—it’s fast, responsive, and capable. And it never interrupts the user with information or requests. If you provide features that require user interaction, add them not to the keyboard but to your keyboard’s containing app.
Keyboard Features That iOS Users Expect
There is one feature that iOS users expect and that every custom keyboard must provide: a way to switch to another keyboard. On the system keyboard, this affordance appears as a button called the Globe key. In iOS 8 and later, the system provides a specific API for your “next keyboard” key, described in Providing a Way to Switch to Another Keyboard.
The system keyboard presents an appropriate key set or layout based on the UIKeyboardType
trait of the current text input object. With the insertion point in the To: field in Mail, for example, the system keyboard period key changes: When you press and hold that key, you can pick from among a set of top-level domain suffixes. Design your custom keyboard with keyboard type traits in mind.
iOS users also expect autocapitalization: In a standard text field, the first letter of a sentence in a case-sensitive language is automatically capitalized.
These features and others are listed next.
Appropriate layout and features based on keyboard type trait
Autocorrection and suggestion
Automatic capitalization
Automatic period upon double space
Caps lock support
Keycap artwork
Multistage input for ideographic languages
You can decide whether or not to implement such features; there is no dedicated API for any of the features just listed, so providing them is a competitive advantage.
System Keyboard Features Unavailable to Custom Keyboards
Your custom keyboard does not have access to most of the general keyboard settings in the Settings app (Settings > General > Keyboard), such as Auto-Capitalization and Enable Caps Lock. Nor does your keyboard have access to the dictionary reset feature (Settings > General > Reset > Reset Keyboard Dictionary). To give your users flexibility, create a standard settings bundle, as described in Implementing an iOS Settings Bundle in Preferences and Settings Programming Guide. Your custom settings then appear in the Keyboard area in Settings, associated with your keyboard.
There are certain text input objects that your custom keyboard is not eligible to type into. First is any secure text input object. Such an object is defined by its secureTextEntry
property being set to YES
true
and is distinguished by presenting typed characters as dots.
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.
Your custom keyboard is also ineligible to type into so-called phone pad objects, such as the phone number fields in Contacts. These input objects are exclusively for strings built from a small set of alphanumeric characters specified by telecommunications carriers and are identified by having one or another of the following two keyboard type traits:
When a user taps in a phone pad object, the system temporarily replaces your keyboard with the appropriate, standard system keyboard. When the user then taps in a different input object that requests a standard keyboard via its type trait, your keyboard automatically resumes.
An app developer can elect to reject the use of all custom keyboards in their app. For example, the developer of a banking app, or the developer of an app that must conform to the HIPAA privacy rule in the US, might do this. Such an app employs the application:shouldAllowExtensionPointIdentifier:
method from the UIApplicationDelegate
protocol (returning a value of NO
false
), and thereby always uses the system keyboard.
Because a custom keyboard can draw only within the primary view of its UIInputViewController
object, it cannot select text. Text selection is under the control of the app that is using the keyboard. If that app provides an editing menu interface (such as for Cut, Copy, and Paste), the keyboard has no access to it. A custom keyboard cannot offer inline autocorrection controls near the insertion point.
Custom keyboards, like all app extensions in iOS 8.0, have no access to the device microphone, so dictation input is not possible.
Finally, 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.
API Quick Start for Custom Keyboards
This section gives you a quick tour of the APIs for building a keyboard. Figure 8-1 shows some of the important objects in a running keyboard and where they come from in a typical development workflow.
The Custom Keyboard template (in the iOS “Application Extension” target template group) contains a subclass of the UIInputViewController
class, which serves as your keyboard’s primary view controller. The template also includes a basic implementation of the “next keyboard” key, which calls the advanceToNextInputMode
method of the UIInputViewController
class. Add objects such as views, controls, and gesture recognizers to the input view controller’s primary view (in its inputView
property), as suggested in Figure 8-1. As with other app extensions, there is no window in the target, and, therefore, no root view controller per se.
The template’s Info.plist
file comes preconfigured with the minimal values needed for a keyboard. See the NSExtensionAttributes
dictionary key in the keyboard target’s Info.plist
file. The keys for configuring a keyboard are described in Configuring the Info.plist file for a Custom Keyboard.
By default, a keyboard has no network access and cannot share a container with its containing app. To enable these things, set the value of the RequestsOpenAccess
Boolean key in the Info.plist
file to YES
true
. Doing this expands the keyboard’s sandbox, as described in Designing for User Trust.
An input view controller conforms to various protocols for interacting with the content of a text input object:
To insert or delete text in response to touch events, employ the
UIKeyInput
protocol methodsinsertText:
anddeleteBackward
. Call these methods on the input view controller’stextDocumentProxy
property, which represents the current text input object and which conforms to theUITextDocumentProxy
protocol. For example:[self.textDocumentProxy insertText:@"hello "]; // Inserts the string "hello " at the insertion point
[self.textDocumentProxy deleteBackward]; // Deletes the character to the left of the insertion point
[self.textDocumentProxy insertText:@"\n"]; // In a text view, inserts a newline character at the insertion point
To get the data you need to determine how much text is appropriate to delete when you call the
deleteBackward
method, obtain the textual context near the insertion point from thedocumentContextBeforeInput
property of thetextDocumentProxy
property, as follows:NSString *precedingContext = self.textDocumentProxy.documentContextBeforeInput;
You can then delete the appropriate text—for example, a single character, or everything back to a whitespace character. To delete by semantic unit, such as by word, sentence, or paragraph, employ the functions described in CFStringTokenizer Reference and refer to related documentation. Note that each language has its own tokenization rules.
To control the insertion point position, such as to support text deletion in a forward direction, call the
adjustTextPositionByCharacterOffset:
method of theUITextDocumentProxy
protocol. For example, to delete forward by one character, use code similar to this:- (void) deleteForward {
[self.textDocumentProxy adjustTextPositionByCharacterOffset: 1];
[self.textDocumentProxy deleteBackward];
}
To respond to changes in the content of the active text object, or to respond to user-initiated changes in the position of the insertion point, implement the methods of the
UITextInputDelegate
protocol.
To present a keyboard layout appropriate to the current text input object, respond to the object’s UIKeyboardType
property. For each trait you support, change the contents of your primary view accordingly.
To support more than one language in your custom keyboard, you have two options:
Create one keyboard per language, each as a separate target that you add to a common containing app
Create a single multilingual keyboard, dynamically switching its primary language as appropriate
To dynamically switch the primary language, use the
primaryLanguage
property of theUIInputViewController
class.
Depending on the number of languages you want to support and the user experience you want to provide, pick the option that makes the most sense.
Every custom keyboard (independent of the value of its RequestsOpenAccess
key) has access to a basic autocorrection lexicon through the UILexicon
class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon
object contains words from various sources, including:
Unpaired first names and last names from the user’s Address Book database
Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list
A common words dictionary
You can adjust the height of your custom keyboard’s primary view using Auto Layout. 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. To adjust a custom keyboard’s height, change its primary view's height constraint.
The following code lines show how you might define and add such a constraint:
CGFloat _expandedHeight = 500;
NSLayoutConstraint *_heightConstraint = [NSLayoutConstraint constraintWithItem: self.view attribute: NSLayoutAttributeHeight relatedBy: NSLayoutRelationEqual toItem: nil attribute: NSLayoutAttributeNotAnAttribute multiplier: 0.0 constant: _expandedHeight];
[self.view addConstraint: _heightConstraint];
Development Essentials for Custom Keyboards
There are two development essentials for every custom keyboard:
Trust. Your custom keyboard gives you access to what a user types, so trust between you and your user is essential.
A “next keyboard” key. The affordance that lets a user switch to another keyboard is part of a keyboard’s user interface; you must provide one in your keyboard.
Designing for User Trust
Your first consideration when creating a custom keyboard must be how you will establish and maintain user trust. This trust hinges on your understanding of privacy best practices and knowing how to implement them.
For keyboards, the following three areas are especially important for establishing and maintaining user trust:
Safety of keystroke data. Users want their keystrokes to go to the document or text field they’re typing into, and not to be archived on a server or used for purposes that are not obvious to them.
Appropriate and minimized use of other user data. If your keyboard employs other user data, such as from Location Services or the Address Book database, the burden is on you to explain and demonstrate the benefit to your users.
Accuracy. Accuracy in converting input events to text is not a privacy issue per se but it impacts trust: With every word typed, users see the accuracy of your code.
To design for trust, first consider whether to request open access. Although open access makes many things possible for a custom keyboard, it also increases your responsibilities (see Table 8-1).
Open access |
Capabilities and restrictions |
Privacy considerations |
---|---|---|
Off (default) |
|
|
On |
|
|
If you build a keyboard without open access, the system ensures that keystrokes cannot be sent back to you or anywhere else. Use a nonnetworked keyboard if your goal is to provide normal keyboard functionality. Because of its restricted sandbox, a nonnetworked keyboard gives you a head start in meeting Apple’s data privacy guidelines and in gaining user trust.
If you enable open access (as described Configuring the Info.plist file for a Custom Keyboard), a variety of possibilities open up but your responsibilities increase as well.
Each keyboard capability associated with open access carries responsibilities on your part as a developer, as indicated in Table 8-2. In general, treat user data with the greatest possible respect and do not use it for any purpose that is not obvious to the user.
Capability |
Example user benefit |
Developer responsibility |
---|---|---|
Shared container with containing app |
Management UI for keyboard’s autocorrect lexicon |
Consider the autocorrect lexicon to be private user data. Do not send it to your servers for any purpose that is not obvious to the user. |
Sending keystroke data to your server |
Enhanced touch-event processing and input prediction via developer’s computing resources |
Do not store received keystroke or voice data except to provide services that are obvious to the user. |
Dynamic autocorrect lexicon based on network supplied data |
Names of people, places, and current events in the news added to autocorrection lexicon |
Do not associate the user’s identity with their use of trending or other network-based information, for any reason that is not obvious to the user. |
Address Book access |
Names, places, and phone numbers relevant to the user added to autocorrection lexicon |
Do not use Address Book data for any purpose that is not obvious to the user. |
Location Services access |
Nearby place names added to autocorrection lexicon |
Do not use Location Services in the background. Do not send location data to your servers for any purpose that is not obvious to the user. |
An open-access keyboard and its containing app can send keystroke data to your server, which enables you to apply your computing resources to such features as touch-event processing and input prediction. If you employ this capability, do not store received keystroke or voice data beyond the time needed to provide text back to the user or to provide features that you explain to the user. Refer to Table 8-2 for additional responsibilities you have when using open-access-keyboard capabilities.
Providing a Way to Switch to Another Keyboard
When more than one keyboard is enabled, the system keyboard includes a Globe key (see Figure 8-2) that lets the user switch keyboards. Your custom keyboard may require a similar “next keyboard” key.
To determine whether your custom keyboard needs to display a “next keyboard” key, check the needsInputModeSwitchKey
property on the input view controller. If true, your keyboard should include this key.
To ask the system to switch to another keyboard, call the advanceToNextInputMode
method of the UIInputViewController
class. The system picks the appropriate “next” keyboard from the list of user-enabled keyboards; there is no API to obtain a list of enabled keyboards or for picking a particular keyboard to switch to.
The Xcode Custom Keyboard template includes the advanceToNextInputMode
method as the action of its Next Keyboard key. For best user experience, place your “next keyboard” key close to the same screen location as the system keyboard’s Globe key.
Getting Started with Custom Keyboard Development
In this section you learn how to create a custom keyboard, configure it according to your goals, and run it in iOS Simulator or on a device. You’ll also learn about some UI factors to bear in mind when replacing the system keyboard.
Using the Xcode Custom Keyboard Template
The steps to create a keyboard and its containing app differ slightly from those for other app extensions. This section walks you through getting a basic keyboard up and running.
To create a custom keyboard in a containing app
In Xcode, choose File > New > Project, and in the iOS Application template group choose the Single View Application template.
Click Next.
Name the project (for example, “ContainingAppForKeyboard”), then click Next.
Navigate to the location you want to save the project in, then click Create.
At this point, you have an empty app for your project to serve the simple role, for now, of containing the keyboard target. Before you submit a containing app to the App Store, it must perform some useful function. See App Store Review Guidelines, linked from Apple’s App Review Support page.
Choose File > New > Target, and in the iOS “Application Extension” target template group choose the Custom Keyboard template, then click Next.
Name the target as you’d like the keyboard’s name to appear in the iOS user interface (for example, Custom Keyboard).
Ensure that the Project and the “Embed in Application” pop-up menus display the name of the containing app, then click Finish.
If you are prompted to activate the scheme for the new keyboard target, click Activate.
You can now optionally customize the keyboard group name as it appears in the Purchased Keyboards list in Settings, as described next.
To customize the keyboard group name
In the Xcode project navigator, choose the containing app’s
Info.plist
file, located in the app’s Supporting Files folder. The property list editor opens, showing the contents of the file.Hover the cursor over the “Bundle name” row, then click the “+” button that appears. This creates a new, empty property list row and selects its Key field.
Start typing
Bundle display name
and when the name autocompletes, press Return.Double-click in the Value field in the same row to obtain a cursor there, then enter the keyboard group name you want.
Choose File > Save to save your changes to property list file.
Table 8-3summarizes the UI strings for your custom keyboard that you can configure in the Info.plist
files for the keyboard and its containing app.
iOS user interface text |
|
---|---|
|
Bundle display name in containing app’s |
|
Bundle display name in custom keyboard target’s |
Now you can run the template-based keyboard in iOS Simulator, or on a device, to explore its behavior and capabilities.
To run the custom keyboard and attach the Xcode debugger
In Xcode, set a breakpoint in your view controller implementation.
For example, set a breakpoint in the
viewDidLoad
method.Use the Xcode toolbar to ensure that the active scheme popup menu specifies the keyboard’s scheme and an iOS Simulator or attached device.
Choose Product > Run, or click the Play button at the upper left of the Xcode project window.
Xcode prompts you to select a host app. Select an app with a readily-available text field, such as Contacts or Safari.
Click Run.
Xcode runs your specified host app. If this is your first time deploying your keyboard extension to iOS Simulator or a device, use Settings to add and enable the keyboard, as follows:
Go to Settings > General > Keyboard > Keyboards.
Tap Add New Keyboard.
In the Purchased Keyboards group, tap the name of your new keyboard. A modal view appears with a switch to enable your keyboard.
Tap the switch to enable your keyboard. A warning alert appears.
In the warning alert, tap Add Keyboard to finish enabling your new keyboard. Then tap Done.
In iOS Simulator or on the attached device, invoke your custom keyboard.
To do this, tap to place the insertion point in a text field—in any app, or in the Spotlight field in Springboard—to display the system keyboard. Then press and hold the Globe key and choose your custom keyboard.
Now you can explore your custom keyboard’s behavior, but the debugger is not yet attached. The bare-bones keyboard built from the template has only one behavior, indicated by its Next Keyboard button: allowing you to switch back to the previously used keyboard.
Before continuing, ensure that your custom keyboard is active.
Dismiss your keyboard (so that in step 8 you can hit the
viewDidLoad
breakpoint by again invoking the keyboard).In Xcode, choose Debug > Attach to Process > By Process Identifier (PID) or Name.
In the sheet that appears, enter the name of your keyboard extension (including spaces) as you specified it when creating it. By default, this is the name for the app extension’s group in the project navigator.
Click Attach.
Xcode indicates in the Debug navigator that it is waiting to attach.
In any app in iOS Simulator or the device (depending on which you are using), invoke the keyboard by tapping in a text field.
As your keyboard’s main view begins to load, the Xcode debugger attaches to your keyboard and Xcode hits your breakpoint.
Configuring the Info.plist file for a Custom Keyboard
The information property list (Info.plist
file) keys that are specific to a custom keyboard let you statically declare the salient characteristics of your keyboard, including its primary language and whether it requires open access.
To examine these keys, open an Xcode project to which you’ve added a Custom Keyboard target template. Now select the Info.plist
file in the Project navigator (the Info.plist
file is in the Supporting Files folder for the keyboard target).
In source text form, the keys for a custom keyboard are as follows:
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IsASCIICapable</key>
<false/>
<key>PrefersRightToLeft</key>
<false/>
<key>PrimaryLanguage</key>
<string>en-US</string>
<key>RequestsOpenAccess</key>
<false/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.keyboard-service</string>
<key>NSExtensionPrincipalClass</key>
<string>KeyboardViewController</string>
</dict>
Each of these keys is explained in App Extension Keys. Use the keys in the NSExtensionAttributes
dictionary to express the characteristics and needs of your custom keyboard, as follows:
IsASCIICapable
—This Boolean value, NO
false
by default, expresses whether a custom keyboard can insert ASCII strings into a document. Set this value to YES
true
if you provide a keyboard type specifically for the UIKeyboardTypeASCIICapable
keyboard type trait.
PrefersRightToLeft
—This Boolean value, also NO
false
by default, expresses whether a custom keyboard is for a right-to-left language. Set this value to YES
true
if your keyboard’s primary language is right-to-left.
PrimaryLanguage
—This string value, en-US
(English for the US) by default, expresses the primary language for your keyboard using the pattern <language>-<REGION>
. You can find a list of strings corresponding to languages and regions at http://www.opensource.apple.com/source/CF/CF-476.14/CFLocaleIdentifier.c.
RequestsOpenAccess
—This Boolean value, NO
false
by default, expresses whether a custom keyboard wants to enlarge its sandbox beyond that needed for a basic keyboard. If you request open access by setting this key’s value to YES
true
, your keyboard gains the following capabilities, each with a concomitant responsibility in terms of user trust:
Access to Location Services, the Address Book database, and the Camera Roll, each requiring user permission on first access
Option to use a shared container with the keyboard’s containing app, which enables features such as providing a custom lexicon management UI in the containing app
Ability to send keystrokes, other input events, and data over the network for server-side processing
Ability to use the
UIPasteboard
classAbility to play audio, including keyboard clicks using the
playInputClick
methodAccess to iCloud, which you can use, for example, to ensure that keyboard settings and your custom autocorrect lexicon are up to date on all devices owned by the user
Access to Game Center and In-App Purchase, via the containing app
Ability to work with managed apps, if you design your keyboard to support mobile device management (MDM)
When considering whether to set the RequestsOpenAccess
key’s value to YES
true
, be sure to read Designing for User Trust, which describes your responsibilities for respecting and protecting user data.
Copyright © 2018 Apple Inc. All rights reserved. Terms of Use | Privacy Policy | Updated: 2017-10-19