iOS 26.4 — How to return from main app to host app after a keyboard-extension dictation round-trip, without private APIs?

I'm building a custom keyboard extension that offers voice dictation. Because keyboard extensions are constrained (memory cap ~30–48 MB, restricted audio session access), I delegate recording to my container app:

  1. User in a host app (e.g., Safari) taps the mic in my keyboard extension.
  2. The keyboard calls extensionContext.open(URL("myapp://dictation")) to launch the container app.
  3. The container app records audio via AVAudioEngine + SFSpeechRecognizer, writes the final transcript to the App Group, and signals

completion via a Darwin notification. 4. The user is expected to be returned to the original host app (Safari) automatically so they can keep typing.

The problem (step 4): On iOS 26.4 I can no longer identify which app was the host. Every previously-known path returns nil for the keyboard extension's host:

  • parent.value(forKey: "_hostBundleID") → returns the literal string <null>
  • parent.value(forKey: "_hostApplicationBundleIdentifier") → returns NSNull
  • xpc_connection_copy_bundle_id on the underlying XPC connection (via PKService.defaultService.personalities[…]) → returns NULL
  • NSXPCConnection.processBundleIdentifier on extensionContext._extensionHostProxy._connection → returns nil
  • proc_pidpath(hostPID, …) → EPERM from the keyboard sandbox
  • LSApplicationWorkspace.frontmostApplication → selector unavailable from the extension
  • RBSProcessHandle.handleForIdentifier:error: → returns an RBSServiceErrorDomain error

Without the host's bundle ID, the container app has no way to call LSApplicationWorkspace.openApplicationWithBundleID: (the technique that worked on iOS 25 and earlier). UIApplication.suspend() correctly sends the container to background, but iOS treats us as a "fresh launch" — it returns the user to the Home Screen instead of Safari, because the container app was launched by an extension, not directly by Safari.

KeyboardKit's maintainer reached the same conclusion (issue #1014) and shipped 10.4 without the feature.

My questions:

  1. Is there a public, App-Store-safe API in iOS 26+ for a custom keyboard extension to identify its host application, or for the

container app (launched via the extension's openURL) to identify which app initially hosted the extension that opened it? UIOpenURLContext.options.sourceApplication reports the extension's own container, not the actual host. 2. Is there a public mechanism for "return to source app" when the container app was launched by an extension's openURL? Equivalent to the ← Source affordance iOS shows for normal inter-app openURL, but triggered programmatically by the launched app. 3. Some popular keyboards (e.g., 微信输入法 / WeChat Keyboard) still appear to round-trip through their container app on iOS 26.4 and return the user to the original host — including the iOS ← WeChat back affordance in the host's status bar afterward. What's the recommended approach to achieve this? If it requires a specific scene-activation flow, NSUserActivity pattern, or extension-context configuration, please point at the relevant docs. 4. If there is no public path today, is FB22247647 (or a related radar) the right place to track this? Should developers in this position migrate to in-extension audio capture (which has its own significant constraints in keyboard extensions)?

I'd much rather not rely on private APIs. Concrete guidance — or even an acknowledgment of which direction Apple intends — would help thousands of custom-keyboard developers who currently have a degraded voice-input experience on iOS 26.4+.

Tested on iPhone 12 Pro Max running iOS 26.4.2 (build 23E261), Xcode 26.x, Swift 5.

Thanks!

iOS 26.4 — How to return from main app to host app after a keyboard-extension dictation round-trip, without private APIs?
 
 
Q