Skip to content

rock run:ios fails to open the simulator on Xcode 27 (Simulator.app replaced by Device Hub) #730

Description

@lukas-preply

Environment

  • rock / @rock-js/platform-apple-helpers: 0.12.8 (same code on main, 0.15.1)
  • macOS 27, Xcode 27
  • Reproduced with rock run:ios after selecting a simulator (both fresh boot and already-booted)

Description

launchSimulator in packages/platform-apple-helpers/src/lib/commands/run/runOnSimulator.ts hardcodes

await spawn('open', [
  `${activeDeveloperDir}/Applications/Simulator.app`,
  '--args', '-CurrentDeviceUDID', device.udid,
]);

Xcode 27 no longer ships Simulator.app. It is replaced by Device Hub (DeviceHub.app, bundle id com.apple.dt.Devices), which also moves from <Xcode>/Contents/Developer/Applications/ to <Xcode>/Contents/Applications/. open fails on the missing path, spawn rejects, and because launchSimulator runs in a Promise.all with the build, the whole run:ios aborts:

The file /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app does not exist.

Device listing, install and launch (simctl list / simctl install / simctl launch) are unaffected. This is the only place in Rock that references Simulator.app.

Prior art

Rock's platform-apple-helpers is a port of cli-platform-apple, so the same fix applies.

Related: -CurrentDeviceUDID alert on an already booted simulator (same lines)

react-native-community/cli#2820 describes a second problem in the same code, which Rock also has on Xcode ≤ 26: open Simulator.app --args -CurrentDeviceUDID <udid> is passed unconditionally, before the device.state !== 'Booted' guard. For a device that is already booted, Simulator.app re-attempts the boot and shows a modal alert "Unable to boot device in current state: Booted" on every run:ios until the simulator is shut down. The run still succeeds, but the alert has to be dismissed by hand. The Device Hub path is not affected because it never passes -CurrentDeviceUDID.

Proposed fix

  1. If <developerDir>/Applications/Simulator.app exists: open it, passing -CurrentDeviceUDID only when the device is not already booted.
  2. Else if <developerDir>/../Applications/DeviceHub.app exists: open "devices://device/open?id=<udid>", falling back to opening DeviceHub.app directly if the URL scheme is rejected.
  3. Else: warn and continue. The app can still be installed and launched headless via simctl, so a missing GUI should not abort the run.

Currently working around this with a local patch of @rock-js/platform-apple-helpers; PR to follow.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions