By hand, Device Hub does everything: its Closed, Book and Open buttons fold the iPhone Duo simulator, Rotate turns it, and holding Option over the pose buttons shows a slider for any hinge angle.23 Its Screenshot and Record buttons capture what’s on screen.7
From a script, CI job or coding agent, Apple gives you less. simctl has no pose or hinge command, and Apple hasn’t offered a supported way to fold the simulator from simctl or XCTest.12 Community tools fill the gap. They use private simulator interfaces, so pin their versions and expect them to break with a new Xcode.
Create and boot a Duo simulator
You need Xcode 27.1 and the iOS 27.1 simulator runtime.2
xcodebuild -downloadPlatform iOS
UDID=$(xcrun simctl create ci-duo "iPhone Duo" com.apple.CoreSimulator.SimRuntime.iOS-27-1)
xcrun simctl boot "$UDID"
xcrun simctl bootstatus "$UDID" -b
The device boots closed, on the outer display.2
Fold and turn it
Two open-source command-line tools send the same event as Device Hub’s hinge slider:
- hinge sets an angle (
hinge 120), sweeps between angles over time (hinge sweep 180 0 2), and rotates. It also ships as an agent skill for Claude Code, Codex and others.4 - duoctl folds (
duoctl open,close,half), rotates, takes screenshots, and taps the inner display, and is built for CI.5
brew install artemnovichkov/tap/hinge # or: brew install skarol/tap/duoctl
hinge 180 # open flat: the inner display takes over
hinge 127 # roughly Device Hub's Book pose
hinge posture # angle, orientation, and which display is active
Device Hub’s Book pose sits near 127°, so don’t write tests that only pass at that angle.2
Check that it worked
Several commands exit successfully without changing anything. Check the state after every step:
- Rotation. On a foldable,
devicectl device orientation setandXCUIDevice.shared.orientationreport success and leave the simulator as it was.45 Use a tool that sends Device Hub’s orientation event. - The display switch lags. The active display changes 1 to 2.5 seconds after the angle does. Wait before you capture.4
- The path matters. Jumping from 0° to 90° moves the app to the inner display; stepping there slowly can leave it on the outer one. Now and then the simulator stops following the hinge altogether; shut it down and boot it again.4
- Orientation names. Tools name either device or interface orientations, and the open phone’s natural interface orientation is landscape. Read the tool’s documentation before you script a turn.45
Screenshots of the right display
The simulator has one framebuffer per display, so simctl io screenshot needs --display. The display that’s off still captures, as a black image.24
Display names have changed between Xcode builds, so list them and pick by size: the outer display is 1398 × 2034 pixels, the inner one 2007 × 2853.24
xcrun simctl io "$UDID" enumerate
xcrun simctl io "$UDID" screenshot --display=<inner display> inner.png
Then check the picture before you trust it. A black frame, a launch screen and an empty list all produce a valid PNG.
Taps on the inner display
Tools that tap through the simulator’s usual input path, including AXe, XcodeBuildMCP and RocketSim, send every touch to the outer display. On an open Duo the tap reports success and nothing happens.5 duoctl tap sends touches to whichever display is active, by coordinates or accessibility label.5
Don’t power displays on or off
simctl io screenConfig can turn a display off, but it doesn’t open the phone. In one test it crashed the simulator’s system shell, and only a shutdown and reboot brought it back.2
Coding agents
To let Claude Code or Codex build and run your project through Xcode, turn on “Allow external agents to use Xcode tools” in Xcode > Settings > Intelligence, then add Xcode’s MCP server:6
claude mcp add --transport stdio xcode -- xcrun mcpbridge
codex mcp add xcode -- xcrun mcpbridge
Pair that with Apple’s App Resizability skill to find the code to fix (see where to start), and with hinge or duoctl so the agent can fold the simulator and check its own work. Tell the agent in AGENTS.md or CLAUDE.md to check the active display after every fold, and to look at each screenshot.
A CI run
export DUOCTL_UDID="$UDID"
xcrun simctl install "$UDID" build/MyApp.app
xcrun simctl launch "$UDID" com.example.myapp
duoctl screenshot closed.png
duoctl open --duration 1.5 && duoctl screenshot open.png
duoctl half && duoctl screenshot book.png
duoctl rotate portrait && duoctl screenshot open-portrait.png
Compare the captures with reference images, or have someone look at them. Neither tool works on a physical device, and the simulator has no cameras.458 Finish with the pose-by-pose test plan on hardware.
Sources
- Apple Developer Forums: Unfolding the simulator with simctl or XCTest
- Blake Crosley: The iPhone Duo simulator in Xcode 27.1
- SwiftLee: iPhone Duo simulator
- hinge, by Artem Novichkov
- duoctl
- Apple Developer: Giving external agents access to Xcode
- Apple Developer: Capturing screenshots and videos from devices
- Frank Schlegel: iPhone Duo Group Labs, consolidated Q&A