Design decisions, platform constraints, and known limitations for developers building similar keyboard extensions.
"Keep your stick on the ice. We're all in this together." — Red Green
iOS keyboard extensions run in a sandboxed process. Full Access is an elevated entitlement that allows the extension to make network requests and share data with its containing app. When a user installs a third-party keyboard, iOS presents a warning that the keyboard "may be able to access everything you type." This warning is shown for all third-party keyboards regardless of whether they actually log anything.
SciMath does not request Full Access and will not. No keystrokes are logged or transmitted. The consequence is that several iOS features are unavailable:
| Feature | Why it requires Full Access |
|---|---|
| Autocorrect / predictive text | iOS passes text context to the correction engine via a mechanism that requires Full Access. |
| Dictation | Audio is routed through Apple's servers. The entitlement to make that network call requires Full Access. |
| Translation | Same network entitlement requirement as dictation. |
The microphone button is present in SciMath's iPad toolbar as a visual placeholder only. See Section 9.
SciMath also omits an emoji key by design. Users who need emoji can hold the globe key, switch to a stock system keyboard, insert the emoji, and switch back. This is documented in the user manual as the supported workaround.
Stock iOS keyboards show a magnified balloon preview above a key while the user's finger is down. This is implemented in Apple's private keyboard framework and is not directly available to keyboard extensions.
Extensions can approximate the behavior by rendering a popup view within their own view hierarchy. The architectural constraint is that a keyboard extension's view cannot render outside its own bounds. This means:
SciMath implements key flash: when a key is tapped, its background briefly brightens. This is distinct from the balloon preview and serves a complementary purpose.
Key flash is an explicit UIColor change triggered on touchesBegan, not a system animation. The key brightens immediately on first contact and restores after a short interval. It does not use gesture recognition and therefore has no recognition delay.
.began before they appear.Key flash is user-toggleable. The preference is stored in App Groups shared defaults so the keyboard extension and the containing app stay in sync without Full Access.
In iOS 26.x (May 2026), Apple introduced a regression affecting gesture detection in keyboard extensions. UIPanGestureRecognizer no longer transitions to .began on stationary contact — it waits for the finger to move. Key preview balloons depend on detecting first contact immediately; the regression broke them entirely.
This is a confirmed Apple bug, acknowledged by an Apple engineer. Filed as FB19394663 and FB19405284.
Subclass UIPanGestureRecognizer and override touchesBegan to force state = .began on first contact:
class ImmediatePanGestureRecognizer: UIPanGestureRecognizer {
override func touchesBegan(_ touches: Set<UITouch>,
with event: UIEvent) {
super.touchesBegan(touches, with: event)
state = .began
}
}
Use this subclass wherever you would have used UIPanGestureRecognizer for balloon triggering. This is a supported API call, not a hack. It will continue to work after Apple fixes the underlying bug, because forcing .began on contact is valid behavior for a pan recognizer with zero minimum distance.
DragGesture(minimumDistance: 0) with .simultaneousGesture(). The UIKit subclass approach above is for UIKit keyboard extensions only.
SciMath forked at v0.400 to isolate and test this workaround before forward-porting it to the full feature set.
SciMath's ABC, 123, and #+= layers match stock Apple layouts on both platforms. The sci layer is SciMath's own, with no stock equivalent to reference.
Three rows: 10 keys, 10 keys, 7 keys. The shorter third row reflects the narrower iPhone form factor and the space taken by the toggle and backspace keys.
Three rows: 10 keys + backspace, 10 keys + return, 10 keys with toggles at both ends. The iPad's wider layout accommodates additional keys that cannot fit on iPhone without the keys becoming too small to tap reliably.
These match stock iPadOS layout, which differs from stock iOS layout. In particular, the iPad 123 layer includes superscript hint characters above the letter keys on the ABC layer, which drove the decision to adopt the iPadOS layout rather than carrying the iPhone layout across both platforms. The layouts were kept separate rather than attempting a one-size-fits-both approach.
SciMath's long-press diacritical set is a strict superset of the stock iOS English keyboard. The stock keyboard covers the most common French and German variants. SciMath extends this to cover:
The extension is deliberate: SciMath targets technical and scientific users who frequently write in multiple languages or use scholarly romanization systems. The additional diacriticals are present because they could be added without cost to users who don't need them, and they address real gaps in the stock English keyboard.
The long-press popup respects shift state: with shift active, all alternates appear in uppercase.
| Key | Alternates | Rationale |
|---|---|---|
| ? | ⸮ ¿ ‽ | Percontation point for rhetorical questions; Spanish inverted; interrobang |
| ! | ¡ | Spanish inverted |
| - | – — • | En dash, em dash, bullet |
Apple does not publish the RGB values for stock keyboard key colors. The semantic system colors available to extensions (UIColor.systemBackground and friends) do not match the keyboard's actual appearance — they are designed for app UI, not keyboard chrome.
SciMath uses explicit hardcoded RGB values tuned by hand against the stock keyboard in both light and dark mode. The values were arrived at empirically.
Some apps use custom text rendering pipelines rather than standard UIKit text input (Google Docs is a documented example). In these apps, third-party keyboard keys may appear with different contrast than in standard UIKit text fields. This is a host-app issue and cannot be corrected from within the keyboard extension.
The pressed-state background for action keys (return, backspace, shift) is also hardcoded. In dark mode, the pressed state lightens the key; in light mode, it goes to near-white. The values used in SciMath:
// Dark mode pressed UIColor(red: 0.42, green: 0.42, blue: 0.44, alpha: 1.0) // Light mode pressed UIColor.white
Stock Apple keyboards integrate the globe (keyboard switcher) into the bottom row using private layout code unavailable to extensions. SciMath handles the globe differently on each platform.
SciMath does not draw a globe key on iPhone. iOS injects the globe automatically when needsInputModeSwitchKey returns true. The injected globe appears outside the main keyboard area rather than inline in the bottom row. This is visually distinct from stock but is the correct supported behavior — attempting to draw your own globe button and call advanceToNextInputMode() directly is unreliable and has caused issues in earlier versions.
SciMath draws its own globe on iPad using Apple's documented API: a native globe SF Symbol button, short-tap calls advanceToNextInputMode(), long-press calls handleInputModeList(from:with:) to show the language picker. This is the only supported path for iPad keyboard switcher integration.
needsInputModeSwitchKey to check whether iOS will inject the globe, and leave the slot empty if so. On iPad, use the documented SF Symbol + API path above.
SciMath shows a dimmed, non-interactive microphone button in the iPad toolbar. It does nothing when tapped.
The rationale: stock iPad keyboards show a microphone button in this position. Users who switch to SciMath have muscle memory for the surrounding key positions. An absent mic button shifts every other key in the toolbar, causing misses on adjacent keys during the adjustment period. The visual placeholder preserves spatial layout at zero functional cost.
Dictation is not available in SciMath because it requires Full Access to route audio through Apple's servers. See Section 1.