FYI that we’ve seen the iOS 26 simulator device hang indefinitely on startup roughly ~10% of the time. We have filed a support ticket with Apple. In the meantime, here is a workaround:
-
The
boot-simulator
command takes in three parameters:- device (“iPhone 17 Pro”)
- platform (“iOS”)
- version (“26.0”) NOTE: this must be quoted to coerce it to a string data type in yaml
-
Using homebrew, add the coreutils package. This installs the
timeout
command. -
Using the parameters, a device UDID is determined. if one can’t be found, the step fails
-
The simulator is booted. If it hasn’t succeeded (the boot command returns without exit) in 60 seconds, then the simulator is force shutdown. After a brief timeout it will retry.
For this to work, any tools or frameworks that connect to simulators will need to ensure they are set up to boot the same device that this workaround starts up.
Here’s the command that can be added to a CircleCI YML config and further customized:
commands:
boot-simulator:
parameters:
# i.e. "iPhone 17 Pro"
device:
type: string
# i.e. "iOS"
platform:
type: string
# i.e. "26.0" (ensure quoted to coerce value to string)
version:
type: string
steps:
- run:
name: install coreutils (provides timeout utility)
command: brew install coreutils
- run:
environment:
SIM_VERSION: <<parameters.version>>
SIM_DEVICE: <<parameters.device>>
SIM_PLATFORM: <<parameters.platform>>
name: Get Simulator Device UUID - <<parameters.platform>>-<<parameters.device>>
command: |
ESCAPED_VER=$(echo "$SIM_VERSION" | tr '.' '-')
SIMREQ="${SIM_PLATFORM}-${ESCAPED_VER}"
SIMLIST=$(xcrun simctl list -j)
UDID_not_found() {
# arguments: requested simulator, device
SIMS=$(xcrun simctl list devices | tail -n +2)
echo "ERROR!: UDID not found, check Platform, Version and Device"
echo "Requested: Simulator: ${1}, Device: ${2}"
echo "Available:"
echo "${SIMS}"
exit 1
}
SIMREQ_not_found() {
# arguments: requested simulator runtime
echo "ERROR!: Simulator runtime not found"
echo "Requested: Simulator Runtime: ${1}"
echo "Available Runtimes:"
echo "${SIMLIST}" | jq -r '.devices | keys[] | select(startswith("com.apple.CoreSimulator.SimRuntime."))'
exit 1
}
if ! echo "${SIMLIST}" | jq -e ".devices | has(\"com.apple.CoreSimulator.SimRuntime.${SIMREQ}\")" > /dev/null; then
SIMREQ_not_found "${SIMREQ}"
fi
UDID=$(echo "${SIMLIST}" | jq -r ".devices.\"com.apple.CoreSimulator.SimRuntime.${SIMREQ}\"[] | select(.name==\"${SIM_DEVICE}\").udid")
if [[ -z "${UDID}" ]]; then
UDID_not_found "${SIMREQ}" "${SIM_DEVICE}"
fi
echo "export UDID=${UDID}" >> "${BASH_ENV}"
- run:
name: Launch Simulator
background: true
command: |
max_attempts=10
attempt=1
while [ $attempt -le $max_attempts ]; do
echo "Launching Simulator (Attempt $attempt/$max_attempts)"
if timeout -s SIGKILL 60s xcrun simctl bootstatus "${UDID}" -b; then
echo "Simulator Booted Successfully"
exit 0
else
echo "Sim boot stalled. Powering down..."
xcrun simctl shutdown "${UDID}"
echo "Retrying in 5s..."
attempt=$((attempt + 1))
sleep 5
fi
done
echo "Simulator Boot failed after $attempt attempts"
exit 1