App Store 스크린샷을 16개 로케일로 자동 캡처합니다. 표준적인 방법은 launch 인자로 언어를 넘기는 것이죠.
xcrun simctl launch "$UDID" "$BID" -AppleLanguages "(ja)" -AppleLocale "ja_JP"이 방식이 iOS 26 시뮬레이터에서 깨졌습니다. 앱이 그 언어로 안 뜹니다.
실패가 조용하다
명령은 성공하고, 앱은 뜨고, 스크린샷도 찍힙니다. 다만 시뮬레이터의 현재 언어 또는 지연된 이전 언어로 렌더됩니다.
결과가 최악의 형태로 나옵니다 — 폴더명은 ja인데 안에 든 이미지는 영어이거나 직전 로케일 언어입니다. 파일 구조상으로는 완벽하게 정상이라 열어봐야만 틀린 걸 압니다. 16개 로케일을 돌리면 대부분이 엉뚱한 언어로 찍힙니다.
iOS 1.0/1.1 시절까지는 이 방식이 먹혔습니다. iOS 26 / Xcode 26에서 회귀했습니다. 즉 몇 년간 잘 돌던 파이프라인이 어느 날 조용히 틀린 결과를 내기 시작한 겁니다.
유일하게 신뢰할 수 있는 방법은 글로벌 prefs를 쓰고 리부트하는 것이었습니다.
xcrun simctl spawn "$UDID" defaults write -g AppleLanguages -array "$lang"
xcrun simctl spawn "$UDID" defaults write -g AppleLocale -string "$region"
xcrun simctl shutdown "$UDID"; sleep 2; xcrun simctl boot "$UDID"; sleep 6
xcrun simctl launch "$UDID" "$BID" -SCREENSHOT_MODE # 언어 인자 없이로케일당 리부트 1회, 16로케일에 약 10분. 느리지만 이건 맞는 결과를 줍니다.
크기 게이트는 이 문제를 못 잡는다
리부트 방식으로 바꾸니 새 실패 모드가 생겼습니다. 리부트 직후 첫 launch와 레이스가 나서, 앱이 포그라운드로 오기 전에 캡처하면 검정 화면(약 70KB) 또는 홈 스프링보드(약 3,700KB, 배경 사진이라 크다) 가 찍힙니다. 파일 크기 게이트로 재시도를 걸어 우회했습니다 — 정상 앱 화면은 대략 120KB~1,500KB입니다.
검정 화면 ≈ 70KB
정상 앱 화면 ≈ 120KB ~ 1,500KB
홈 스프링보드 ≈ 3,700KB
→ 벗어나면 relaunch + recapture, sleep 늘려가며 재시도그런데 크기 게이트는 근본 해결이 아닙니다. 검정 화면·스프링보드처럼 크기가 명백히 벗어나는 것만 잡습니다. "앱 화면인데 언어가 틀린 것"은 크기가 정상이라 못 잡습니다. 이 파이프라인의 원래 문제를 크기 게이트로는 검출할 수 없다는 뜻입니다. 결국 눈으로 확인하는 단계가 필요합니다 — 자매 글 스크린샷에 페이월이 찍혔다와 정확히 같은 결론입니다. 자동 캡처의 산출물은 자동으로 검증할 수 없고, 전수 시각 QA가 유일한 안전망입니다.
등장 앱: Resolv.
정직하게
nohup ... &백그라운드 실행이 빌드 직후 조기 종료돼 포그라운드로 돌리고, 타임아웃을 피하려 로케일을 8개씩 쪼갰습니다. 원인은 안 팠고 쪼개기로 우회했습니다.- 왜 launch 인자가 무시되는지는 모릅니다. Apple 쪽 회귀로 보이지만 확인할 방법이 없었고, 다음 Xcode 버전에서 다시 동작할 수도 있습니다. 그 경우 지금 방식은 필요 이상으로 느린 채 남습니다.
- 크기 게이트는 원래 문제(언어 오류)가 아니라 리부트가 만든 부작용(검정/스프링보드)만 잡습니다. 두 문제를 같은 도구로 잡는다고 착각하기 쉽습니다.
몇 년 잘 돌던 파이프라인이 "명령 성공 + 파일 생성 + 크기 정상"을 계속 보고하는데 결과가 틀렸다면, 플랫폼이 조용히 회귀했을 수 있습니다. 당신의 자동 산출물, 마지막으로 눈으로 열어본 게 언제입니까?