#!/usr/bin/env bash set -euo pipefail # Require container type if [ "$#" -lt 1 ]; then echo "Usage: $0 [bundle-id]" >/dev/stderr echo "Examples: $0 data | caches | app [com.example.app]" >/dev/stderr exit 1 fi CONTAINER_TYPE="$1" # Optional bundle id (defaults to Pocket Casts) if [ "$#" -ge 2 ]; then BUNDLE_ID="$2" else BUNDLE_ID="au.com.shiftyjelly.podcasts" fi list="$( xcrun simctl list devices 2>/dev/null | { runtime="" while IFS= read -r line; do case "$line" in # Header lines: -- iOS 18.5 -- --\ *\ --) runtime="$(printf '%s\n' "$line" | sed -E 's/^-- (.*) --$/\1/')" continue ;; esac # Device lines: ... (Booted) case "$line" in *"(Booted)"*) # Skip Watch/TV case "$line" in *Watch*|*TV*) continue ;; esac # Trim leading whitespace trimmed="$(printf '%s\n' "$line" | sed -E 's/^[[:space:]]+//')" name="$(printf '%s\n' "$trimmed" | sed -E 's/^([^()]+) \(([0-9A-Fa-f-]{36})\) \(Booted\).*$/\1/')" udid="$(printf '%s\n' "$trimmed" | sed -nE 's/.*\(([0-9A-Fa-f-]{36})\).*/\1/p')" if [ -n "$name" ] && [ -n "$udid" ] && [ -n "$runtime" ]; then printf '%s (%s) (%s)\n' "$name" "$runtime" "$udid" fi ;; esac done } )" # Count non-empty lines count="$(printf '%s\n' "$list" | sed '/^[[:space:]]*$/d' | wc -l | tr -d ' ')" if [ "$count" -eq 0 ]; then echo "No booted iOS simulators found." >/dev/stderr exit 1 fi # Pick with fzf if multiple if [ "$count" -gt 1 ]; then selection="$(printf '%s\n' "$list" | fzf --prompt='Select Simulator: ' --height=10 --reverse || true)" [ -z "$selection" ] && exit 130 else selection="$(printf '%s\n' "$list" | head -n1)" fi # UDID is the final (...) group udid="$(printf '%s\n' "$selection" | sed -nE 's/.*\(([0-9A-Fa-f-]{36})\)$/\1/p')" # Resolve container and open container="$(xcrun simctl get_app_container "$udid" "$BUNDLE_ID" "$CONTAINER_TYPE" 2>/dev/null || true)" if [ -z "$container" ]; then echo "App '$BUNDLE_ID' does not have a '$CONTAINER_TYPE' container on: $selection" >/dev/stderr exit 2 fi open "$container"