Zum Inhalt

scripts/shoot-appstore-ui.sh

#!/usr/bin/env bash
# Captures UI-IN-USE App Store stills: the live player WITH the app's controls visible
# (editor sheet, library, capture sheet, topbar) so screenshots show the app genuinely in
# use — Apple 2.3.3 / 4.2. Complements shoot-appstore-stills.sh (chrome-free hero visuals).
#
# DEBUG hooks (RootView.onAppear): PHYSARUM_BOOT_PRESET=<i>, PHYSARUM_SHOW_EDITOR/LIBRARY/CAPTURE=1.
# Output: docs/appstore/screenshots/<device>/ui-NN-<motif>.png
# Usage:  scripts/shoot-appstore-ui.sh [iphone-6.9 ipad-13 ipad-13-landscape ...]
#         default: iphone-6.9 ipad-13
# Requires: Xcode + simulators (6.9" iPhone Pro Max, 13" iPad Pro). Run with NO other xcodebuild active.
#
# NOTE on iPad landscape (the 3-column Library|Canvas|Editor workspace — the strongest iPad shot):
# the app enters split-columns only in landscape (width>height). simctl cannot set orientation,
# and the Simulator menu shortcut needs Accessibility permission. So: rotate the iPad simulator
# to landscape MANUALLY (Simulator ▸ Device ▸ Rotate Left, or Cmd+←), then run the
# `ipad-13-landscape` target — the app boots straight into the docked-panel workspace.
set -euo pipefail
cd "$(dirname "$0")/.."

SCHEME="Physarum"
PROJ="apple/PhysarumApp/Physarum.xcodeproj"
BUNDLE_ID="de.jkaindl.physarum"
OUT="docs/appstore/screenshots"
SETTLE="${SETTLE:-12}"   # let the pattern form + the sheet animate in before the shot

( cd apple/PhysarumApp && xcodegen generate )

build_install() {   # sim-regex sdk  -> stdout: udid
  local sim="$1" sdk="$2" udid dd app
  udid=$(xcrun simctl list devices available | grep -E "$sim" | grep -oiE '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}' | head -1 || true)
  [ -n "$udid" ] || { echo "skip: no sim /$sim/" >&2; return 1; }
  xcrun simctl boot "$udid" 2>/dev/null || true
  xcrun simctl bootstatus "$udid" -b >&2
  dd="${TMPDIR:-/tmp}/physarum-ui-$sdk"
  xcodebuild -project "$PROJ" -scheme "$SCHEME" -destination "id=$udid" -derivedDataPath "$dd" build >/dev/null 2>&1
  app=$(find "$dd/Build/Products" -name 'Physarum.app' -path "*$sdk*" | head -1)
  [ -n "$app" ] || { echo "skip: no app built" >&2; return 1; }
  xcrun simctl install "$udid" "$app" >&2
  echo "$udid"
}

# shoot udid dir out preset [HOOK=VAL ...]
shoot() {
  local udid="$1" dir="$2" out="$3" preset="$4"; shift 4
  mkdir -p "$OUT/$dir"
  xcrun simctl terminate "$udid" "$BUNDLE_ID" >/dev/null 2>&1 || true
  sleep 1
  local prefixed=( "SIMCTL_CHILD_PHYSARUM_BOOT_PRESET=$preset" ) kv
  for kv in "$@"; do prefixed+=( "SIMCTL_CHILD_$kv" ); done
  env "${prefixed[@]}" xcrun simctl launch "$udid" "$BUNDLE_ID" >/dev/null 2>&1 || true
  sleep "$SETTLE"
  xcrun simctl io "$udid" screenshot "$OUT/$dir/$out" >/dev/null 2>&1 || true
  echo "    wrote $dir/$out"
}

# Four UI-in-use motifs over the compact (sheet) layout — iPhone, or iPad in portrait.
shoot_sheets() {
  local udid="$1" dir="$2"
  shoot "$udid" "$dir" ui-01-editor.png  0 PHYSARUM_SHOW_EDITOR=1
  shoot "$udid" "$dir" ui-02-library.png 2 PHYSARUM_SHOW_LIBRARY=1
  shoot "$udid" "$dir" ui-03-capture.png 1 PHYSARUM_SHOW_CAPTURE=1
  shoot "$udid" "$dir" ui-04-topbar.png  5
}

for d in ${@:-iphone-6.9 ipad-13}; do
  case "$d" in
    iphone-6.9)
      udid=$(build_install "iPhone 1[5-9] Pro Max" "iphonesimulator") || continue
      echo "==> iphone-6.9 (compact / sheets)"; shoot_sheets "$udid" iphone-6.9 ;;
    ipad-13)
      udid=$(build_install "iPad Pro 13-inch" "iphonesimulator") || continue
      echo "==> ipad-13 (portrait / sheets)"; shoot_sheets "$udid" ipad-13 ;;
    ipad-13-landscape)
      # Sim must ALREADY be rotated to landscape (see header note). Both panels dock by default.
      udid=$(build_install "iPad Pro 13-inch" "iphonesimulator") || continue
      echo "==> ipad-13 landscape (split-columns workspace)"
      shoot "$udid" ipad-13 ui-05-workspace.png  0
      shoot "$udid" ipad-13 ui-06-workspace2.png 5 ;;
    *) echo "unknown device: $d" >&2 ;;
  esac
done
echo "Done. Review $OUT/*/ui-*.png"