fix(scripts): run-ios-simulator.sh exits silently when no Booted sim found

When no simulator is booted, grep -oE finds no UUID and exits 1. With
set -euo pipefail, that non-zero exit propagates through the command
substitution and kills the script at the UDID= assignment before it can
fall through to the boot-one branch.

Fix: add || true to both find_sim and sim_name pipelines so they always
return 0 regardless of whether a match was found.

Also replace sleep 2 with xcrun simctl bootstatus <UDID> -b, which blocks
until the simulator is fully booted — more reliable than a fixed delay
and faster when the simulator starts quickly.

Update docs/building.md §9 to show the bootstatus command.
This commit is contained in:
2026-06-19 02:33:14 +02:00
parent bf37fe8f0f
commit e2616b60b4
2 changed files with 11 additions and 7 deletions

View File

@@ -445,6 +445,7 @@ Under the hood the script uses `xcrun simctl` commands:
# Boot a simulator (if not already running): # Boot a simulator (if not already running):
xcrun simctl boot <UDID> xcrun simctl boot <UDID>
open -a Simulator open -a Simulator
xcrun simctl bootstatus <UDID> -b # wait until boot is complete before installing
# Install the built .app: # Install the built .app:
xcrun simctl install <UDID> clients/apple/iOS/build/Debug-iphonesimulator/VoiceCatiOS.app xcrun simctl install <UDID> clients/apple/iOS/build/Debug-iphonesimulator/VoiceCatiOS.app

View File

@@ -67,21 +67,23 @@ vc_log "app: $APP"
find_sim() { find_sim() {
# Each line from simctl looks like: # Each line from simctl looks like:
# " iPhone 16 (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Shutdown)" # " iPhone 16 (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Shutdown)"
# The || true at the end prevents set -e from killing the script when no
# matching device exists (grep -oE exits 1 on no match).
local filter="${1:-}" state="${2:-}" local filter="${1:-}" state="${2:-}"
local pattern="iPhone" local pattern="iPhone"
[[ -n "$filter" ]] && pattern="$filter" [[ -n "$filter" ]] && pattern="$filter"
xcrun simctl list devices available 2>/dev/null \ xcrun simctl list devices available 2>/dev/null \
| grep -E "[[:space:]]$pattern" \ | grep -E "$pattern" \
| { [[ -n "$state" ]] && grep "$state" || cat; } \ | { [[ -n "$state" ]] && grep "$state" || cat; } \
| head -1 \ | head -1 \
| grep -oE '[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}' \ | grep -oE '[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}' \
| head -1 | head -1 || true
} }
sim_name() { sim_name() {
xcrun simctl list devices available 2>/dev/null \ xcrun simctl list devices available 2>/dev/null \
| grep "$1" | head -1 \ | grep "$1" | head -1 \
| sed 's/[[:space:]]*('"$1"').*//' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*('"$1"').*//' | sed 's/^[[:space:]]*//' || true
} }
if [[ -n "$DEVICE_UDID" ]]; then if [[ -n "$DEVICE_UDID" ]]; then
@@ -100,16 +102,17 @@ else
vc_step "booting simulator: $NAME ($UDID)" vc_step "booting simulator: $NAME ($UDID)"
xcrun simctl boot "$UDID" xcrun simctl boot "$UDID"
open -a Simulator open -a Simulator
# Give Simulator.app a moment to display the device. # Wait for the simulator to finish booting before installing.
sleep 2 vc_log "waiting for simulator to boot…"
xcrun simctl bootstatus "$UDID" -b
fi fi
fi fi
NAME="$(sim_name "$UDID")" NAME="$(sim_name "$UDID")"
vc_log "simulator: $NAME ($UDID)" vc_log "simulator: $NAME ($UDID)"
# If the simulator exists but Simulator.app isn't open, open it. # Bring Simulator.app to the foreground (no-op if already open).
open -a Simulator &>/dev/null || true open -a Simulator
# ── Install ─────────────────────────────────────────────────────────────────── # ── Install ───────────────────────────────────────────────────────────────────
vc_step "installing VoiceCatiOS" vc_step "installing VoiceCatiOS"