DEV Community

Cover image for Input said OK, nothing happened: Xcode 27, Device Hub and a flag that eats your taps
Valentine Tikhomirov
Valentine Tikhomirov

Posted on

Input said OK, nothing happened: Xcode 27, Device Hub and a flag that eats your taps

If you drive the iOS simulator from scripts, test tools or AI agents, this one can cost you an afternoon: every tap is acknowledged, every command returns ok, and nothing happens on screen.

I hit it while building a tool that lets an agent and me work on the same running React Native app. Here's what's going on, how to tell you're in it, and how to get out.

All of this is on Xcode 27.0 with iOS 26.3 simulators, on one Mac. If you're on a different setup, your mileage may vary, and I'd love to hear if you see it too.

First, the change: no more Simulator.app

Xcode 27 doesn't ship a separate Simulator.app anymore. You look at simulators through Device Hub inside Xcode.

Two side effects worth knowing:

  • Closing the viewer can shut the device down. If you were relying on "the window is open, so the simulator is running", that's no longer a safe assumption.
  • You don't need a viewer at all. xcrun simctl boot <udid> brings the simulator up without any window, and anything that streams the screen or sends input to it keeps working. For automation this is actually nicer: nothing to keep open, nothing for a human to close by accident.

The bug: input that says yes and does nothing

One day input to one simulator simply stopped working. Not failing: stopped working while reporting success.

I measured it on a local test page that logs every pointer event:

  • 5 taps and one typed word sent to the simulator;
  • every single one acknowledged by the input layer in 52–113 ms, no errors;
  • 0 events reached the page.

Home and App Switcher commands also answered ok. The screen didn't move.

A second simulator on the same machine, same Xcode, same everything, worked fine.

The cause: a flag Device Hub leaves behind

The difference between the two simulators turned out to be one Darwin notification state inside the simulator:

com.apple.coredevice.dtuhidd.active
Enter fullscreen mode Exit fullscreen mode
  • On the broken simulator it was 1, while no Device Hub process was running at all.
  • On the healthy one it was 0.

It's not a defaults key or a plist, it's a notify state held by the simulator's backboardd. As far as I can tell, it means "Device Hub attached to this simulator's input during this boot". While Device Hub is attached, input goes through its channel. When Device Hub goes away, the state stays at 1, and input from any other source is quietly ignored.

Just opening Device Hub and showing the simulator didn't set it in my tests; it stayed 0. Interacting with it from Device Hub seems to be what does. The name isn't documented anywhere I could find (I first saw it in the source of an open-source simulator tool), so treat the mechanism as my best reading of the evidence, not Apple's description.

The state survives closing Device Hub. It survives closing Xcode. It goes away only when the simulator reboots.

After a reboot: flag 0, input reaches the app again.

How to check yours

Two read-only commands. First, the state inside a booted simulator:

xcrun simctl spawn <udid> notifyutil -g com.apple.coredevice.dtuhidd.active
Enter fullscreen mode Exit fullscreen mode

It prints com.apple.coredevice.dtuhidd.active 0 or ... 1.

Then, whether Device Hub is actually running:

pgrep -x DeviceHub >/dev/null && echo "Device Hub running" || echo "no Device Hub process"
Enter fullscreen mode Exit fullscreen mode

How to read the pair:

State Device Hub process Meaning
0 any Free, input from your tools works
1 running Device Hub is attached right now, expected
1 not running Stale: input will be silently dropped

Use notifyutil -g only. -s sets the state, which you don't want to do on a whim. The simulator has to be booted for simctl spawn to work.

The symptom is also easy to recognise once you know it:

  1. Input commands succeed with no errors.
  2. Nothing on screen reacts, including system gestures like Home.
  3. Another simulator on the same machine works.
  4. You (or a teammate, or a tool) used that simulator from Device Hub at some point since it was booted.

If you're in the stale state, reboot the simulator before you debug anything else:

xcrun simctl shutdown <udid>
xcrun simctl boot <udid>
Enter fullscreen mode Exit fullscreen mode

Why this is worse for agents than for people

A person notices within seconds that taps don't do anything. An automated check often doesn't, for two reasons:

  • The acknowledgement is a lie. If your tool treats "input accepted" as "input delivered", every step passes.
  • "The screen changed" can lie too. The simulator's video stream keeps sending frames even when nothing moves, so "a frame arrived after the tap" proves nothing. My own heuristic that looks at frame sizes to decide whether a tap landed said "confirmed" once while in this state, because a page happened to load at the same moment.

So an agent can walk through a whole flow, report success, and never have touched the app.

What I ended up doing in my tool:

  • detect the stale flag (key set, no Device Hub process) and show the human a one-line note under the picture;
  • mark input as unverified instead of confirmed while the simulator is in that state;
  • add a warning to the agent's tool replies: input is likely blocked by a flag Device Hub left on this simulator; ask the user to reboot the simulator.

The last one matters most. The agent can't fix this itself, but it can stop pretending everything worked and ask the human for the one action that does.

Takeaways

  1. On Xcode 27, a simulator doesn't need a window. simctl boot is enough for streaming and input.
  2. Device Hub can leave a state that silently swallows input until the simulator reboots. One notifyutil -g plus one pgrep tells you if you're in it.
  3. "Input accepted" is not "input delivered". If you automate the simulator, verify against what the app actually received.
  4. When the tool can't fix something, it should say so. An honest warning to the agent beats a green check.

Have you run into this, or something like it, on Xcode 27? I'd like to know whether it's my setup or more common than it looks.

Top comments (0)