Skip to content

app-store-screenshots

Capture native-resolution screenshots on the simulator, downscale to the other required sizes, upload via helm-asc.

Sizes (only TWO files per screen are actually needed)

Section titled “Sizes (only TWO files per screen are actually needed)”
Display Pixels Device
6.9” 1320×2868 iPhone 16/17 Pro Max (capture native here)
6.7” 1290×2796 downscale from 6.9”
6.5” 1242×2688 downscale from 6.9”

Aspect ratios differ <0.4%, so downscaling 6.9”→6.7”/6.5” is visually lossless. If the app’s deployment target is iOS 26+, no real 6.5”-class device can run it — those sizes MUST be derived from a 6.9” capture, never captured natively.

  1. Boot the largest Pro Max sim and build/install: flowdeck simulator boot <udid>; flowdeck run -S <udid> -d ios/DerivedData-shots. Find the UDID with flowdeck simulator list (pick an iPhone 17/16 Pro Max).
  2. Clean status bar: flowdeck simulator status-bar override -S <udid> --time "9:41" --data-network 5g --wifi-mode active --wifi-bars 3 --cellular-mode active --cellular-bars 4 --battery-state charged --battery-level 100. Re-assert it before each capture (navigation can reset it).
  3. Capture at NATIVE resolution — use flowdeck simulator frames --images -S <udid> -t 1s --fps 2 -o <dir>, then take frame-000-*.png (1320×2868). ⚠️ Do NOT use flowdeck ui simulator screen --screenshot for the deliverable — it returns POINT resolution (440×956 @1x), which ASC rejects. frames --images is the native-res path.
  4. Navigate with flowdeck ui simulator screen --json (read the a11y tree) + flowdeck ui simulator tap "<label>" or tap --point x,y (point coords from the tree). Re-assert status bar, capture each screen.
  5. Downscale to the other sizes: sips -z 2796 1290 6.7/NN.png and sips -z 2688 1242 6.5/NN.png (note sips -z is height-then-width).

helm-asc is sandboxed — it can’t read arbitrary paths. Stage the tree in its inbox:

INBOX=$(helm-asc paths --agent | python3 -c "import json,sys;print(json.load(sys.stdin)['uploadsInbox'])")
# Build <path>/<locale>/<deviceType>/NN_name.png e.g. en-US/APP_IPHONE_67/01_home.png
helm-asc version <version-id> screenshots upload --path "$INBOX/<dir>" --dry-run # validate first
helm-asc version <version-id> screenshots upload --path "$INBOX/<dir>"
  • Device types: APP_IPHONE_67 (6.7”), APP_IPHONE_65 (6.5”). helm-asc does not support APP_IPHONE_69 — the 6.9” native set must be added through the ASC web UI if wanted (the 6.5” tier satisfies Apple’s required iPhone size, so 67+65 is a valid submittable set).
  • The NN_ filename prefix sets display order in ASC.
  • Custom Product Pages can’t be created or populated by helm-asc — those are ASC-web-UI only; reuse the same .shots/ folders there.
  • You cannot CLI-screenshot a physical device. Network-connected devices route through CoreDevice; idevicescreenshot/libimobiledevice only speak legacy usbmuxd and won’t see them, and the RocketSim/flowdeck CLIs are simulator-only. For real-device shots (e.g. a signed-in premium account), have the user take them on-device and AirDrop them (they land in ~/Downloads, native 1320×2868).
  • Gated screens: in signed-out “Explore”/guest mode the player shows a premium error and Stats/streaks does nothing. The paywall is reachable signed-out via Settings → Subscribe. A clean “playing” player and real Stats need a signed-in account — either sign one into the sim or use AirDropped device shots.
  • Real-device shots carry a real status bar (time/battery), not 9:41 — acceptable for App Store, but note the inconsistency vs the sim’s 9:41 shots; RocketSim’s GUI can overlay a clean status bar on device captures if needed.