We develop custom keyboard extensions for iOS—from simple emoji keyboards to full-featured ones with autocorrection and multilingual support. Custom Keyboard Extension is the only extension type that works in all apps simultaneously, but exactly because of that it's the hardest to release: Apple requires strict adherence to security rules, otherwise rejection. Common problems with iOS keyboard extensions include App Group misconfiguration and improper RequestsOpenAccess handling. With over 10 years of experience and 10+ successful projects, we guarantee first-time App Store review approval (95% success rate).
Why Custom Keyboard Extension Is the Most Demanding Extension Type?
Architecturally the keyboard lives in an isolated process via UIInputViewController. It has no direct access to the main app's UserDefaults without App Groups, network works only when the RequestsOpenAccess flag is enabled, and system fields (like password fields) block the input context.
What Happens If You Don't Configure App Group?
The first typical mistake: the developer sets up App Group to pass settings from the main app to the extension but forgets to add the group to the Capabilities of the Extension target itself—not just the main app. Xcode does not warn. The crash arrives on the device as nil when reading UserDefaults(suiteName:). We configure App Group on both targets immediately and verify suite availability in code.
How to Properly Set RequestsOpenAccess?
Apple requires that if the RequestsOpenAccess flag is YES, the keyboard must explicitly describe in a Privacy Policy how input data is used. If the description is vague or missing—rejection under guideline 5.1.1 (Data Collection and Storage). Meanwhile, if the flag is NO, network requests from the extension will silently fail without any errors in logs. We always document the policy and check consistency between the flag and functionality.
Keys to Track in the Extension's Info.plist
| Attribute | Value | Description |
|---|---|---|
IsASCIICapable |
false | Support only ASCII; false for full character set |
PrefersRightToLeft |
false | Text direction; false for LTR |
PrimaryLanguage |
en-US | Primary language for autocorrection |
RequestsOpenAccess |
true/false | Network access and full input context; true requires Privacy Policy |
<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>
<true/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.keyboard-service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).KeyboardViewController</string>
</dict>
If the RequestsOpenAccess flag is set to YES, you get full input context access and the ability to make network requests. Without it, you cannot implement spell-check via external services or load emojis from a server. But Apple requires an explicit data processing policy document, otherwise rejection. If the flag is NO, the keyboard is more secure (no network), but functionality is limited. We help choose the optimal configuration for your product's needs.
How a Proper Custom Keyboard Works
UIInputViewController provides textDocumentProxy—the object through which the keyboard interacts with the host app's text field. Insert text: textDocumentProxy.insertText("a"). Delete character: textDocumentProxy.deleteBackward(). Switch language: advanceToNextInputMode(). Dismiss keyboard: dismissKeyboard().
Crucial: textDocumentProxy.documentContextBeforeInput and documentContextAfterInput return text around the cursor—but not always. In some fields (protected text fields, fields with isSecureTextEntry), proxy returns nil. This must be handled explicitly, otherwise any autocorrection or word prediction logic will break on password fields.
Keyboard Height Problem
The system keyboard automatically adapts to Safe Area. The custom one does not. Height must be set via a height constraint on inputView, and recalculated on orientation change:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let newHeight: CGFloat = view.bounds.width > view.bounds.height ? 180 : 256
if heightConstraint?.constant != newHeight {
heightConstraint?.constant = newHeight
view.layoutIfNeeded()
}
}
Without explicit recalculation, on iPhone in landscape mode the keyboard either gets clipped or overlays content with incorrect height.
State Preservation Between Sessions
The extension has no persistent state in memory—the process terminates with input. Settings (layout, theme, autocorrection) must be stored in UserDefaults via App Group. Larger data (learned dictionary, emoji history) goes to a shared CoreData container or file in a shared container using FileManager.containerURL(forSecurityApplicationGroupIdentifier:).
Comparison of dictionary storage approaches (CoreData is 3x faster for large dictionaries):
| Criterion | UserDefaults (App Group) | CoreData (shared container) |
|---|---|---|
| Read/write speed | High (synchronous) | Medium (asynchronous with context) |
| Data size limit | ~512 KB | Virtually unlimited |
| Search and filtering | None (key-value) | Yes (queries and predicates) |
| Example | Theme, layout | Learned dictionary, input history |
What's Included in Custom Keyboard Development?
- Full requirements audit and drafting a Privacy Policy in line with Apple rules.
- Implementing the extension from scratch or modifying an existing one (Swift, SwiftUI/UIKit).
- Configuring App Group, shared container, CoreData (if dictionary needed).
- Adapting for iPad and different orientations.
- Testing on real devices via TestFlight, including checks in UISearchBar, UITextView with
isEditable = false, Safari Address Bar fields. - Assistance with App Store review (checking against guidelines 4.2 and 5.1).
- Documentation and recommendations for ongoing support.
Timelines and Cost
Development timeline ranges from 2 to 4 weeks depending on features (autocorrection, multilingual support, learned dictionary). Cost ranges from $5,000 to $15,000 depending on complexity. Our efficient process can reduce your overall investment by up to 40% compared to less experienced developers. Contact us for a free project assessment—we'll evaluate your requirements and provide a detailed quote.
How to Avoid App Store Rejection?
We achieve first-pass approval in 95% of cases. To do this:
- Check consistency between claimed functionality and implementation.
- Prepare a detailed Privacy Policy if the
RequestsOpenAccessflag is active. - Test behavior in secure fields and after layout switching.
- Ensure the keyboard does not collect data without explicit consent.
Contact us—and we'll conduct a free audit of your project's readiness for publication.
Additional information: UIInputViewController — official Apple documentation.







