Hey @DTS Engineer, I apologize for the delay. Feature dev got in the way :)
The guidelines PDF and the macOS-first advice were exactly what I needed. Here's where I ended up, plus three things the document doesn't cover.
First, the descriptor audit. I compared our keyboard collection byte-by-byte against the example in 14.2.1 (p.105). Differences: we carry a report ID, our modifiers come before the LED items, there's a reserved constant byte, a 6-slot key array instead of 5, and five LED usages instead of Caps Lock only. To rule those out I built a keyboard-only firmware whose keyboard collection is byte-identical to the composite's, all of those differences included. That build types perfectly on the same iPhone, Shift honored, shifted symbols correct, software keyboard suppressed. So the collection internals are fine; the same bytes work the moment the mouse is gone.
The full differential on one iPhone 16 Plus: Magic Keyboard works. My keyboard-only build works. The composite (same keyboard bytes plus mouse and consumer collections, mouse appearance) types lowercase, Cmd+Space works, but Shift is dropped in text input, there's no Hardware Keyboard settings row, and the on-screen keyboard stays up while it types. A commercial USB mouse+keyboard combo fails identically on this phone, so it's not my firmware.
Then the isolation test. I split the roles into two separate HID services on the same device: a keyboard-only service byte-equivalent to the working build, plus a mouse-only service, advertising as a keyboard. iOS binds both - the cursor works - and Shift is still dropped. So descriptor structure, report IDs, appearance, consumer usages: none of it matters. The one variable that flips the behavior in both directions is whether any mouse role exists on the accessory.
Finally the macOS approach you suggested, and it's clean. Pairing brings up the Keyboard Setup Assistant, so macOS classifies the composite as a keyboard. The raw input report carries modifier 0x02 with keycode 0x04, CGEventTap shows SHIFT=1 on the keyDown, and capitals land fine in TextEdit. Same firmware, same descriptor, same reports iOS strips Shift from. Since it works on macOS and fails on iOS, I've filed a bug per your suggestion: FB24023642, with the descriptor dump, both captures, the capture tool sources, and the two-service firmware diff attached.
The three questions:
Is "no pointer role anywhere on the accessory" effectively a requirement for iOS to admit a device to the hardware-keyboard text path? From the isolation above, any mouse role - even on a fully separate HID service with a keyboard appearance - keeps the keyboard's modifiers off text composition while plain keys and global shortcuts still work. Is that expected behavior, or is the Feedback above a real bug? The guidelines cover keyboards (ch.14) and trackpads (ch.15) but say nothing about how iOS treats the keyboard half of a pointer-carrying accessory.
Chapter 15 gates accessory trackpads to "supported starting in iPadOS 14.5" and never mentions iPhone. You suggested keyboard+trackpad integration - does iPhone (iOS 26) bind a chapter-15-conformant Digitizer/Touch Pad collection at all? And if it does, is the trackpad role exempt from whatever disqualifies mouse-carrying accessories, given 15.1.1 requires holding modifier keys while dragging?
Bottom line for my product: is there any supported way today to ship pointer + keyboard on one radio that preserves text-path modifiers on iPhone? I've now falsified the two obvious shapes (one composite report map, and two separate HID services). If the real answer is "two accessories or a trackpad", knowing that saves me months....or just tons of time
Thanks you so much again :) Everything above is reproducible from the attached captures below. PS I turned them into txt files since i guess they aren't allowed to be uploaded? That way they're safer? hope that makes sense. Lmk if there's a better way to get you these things:
two-service-split-firmware.patch.txt
tool-hidmon.swift.txt
tool-eventtap.swift.txt
tool-decode_descriptor.py.txt
tool-bletype.swift.txt
README.txt
macos-raw-hid-reports.log
macos-eventtap.log
hid-descriptor-raw.txt
hid-descriptor-decoded.txt
Topic:
App & System Services
SubTopic:
Hardware
Tags: