Expo App Store 스크린샷: EAS Submit이 처리하지 않는 이유와 빠르게 준비하는 방법 (2026)
.ipa/.aab를 App Store Connect와 Play Console에 업로드해요 — 그게 전부예요. 스토어 스크린샷을 생성하거나 업로드하거나 관리하지 않아요. 따라서 Expo 개발자는 별도의 스크린샷 파이프라인이 필요해요. dev/preview 빌드에서 프레임을 캡처하고(시뮬레이터, 에뮬레이터, 또는 Maestro/Detox), 그 원본 프레임을 기기 프레임이 있는 마케팅 패널로 합성하고 현지화해야 해요. 이 글은 캡처 명령어를 솔직하게 다루고, 합성 도구가 어디에 맞는지 설명해요 — 합성 도구는 캡처를 대신해주지 않아요.Expo 앱을 출시할 때 릴리즈 경로는 아마 한 줄로 끝날 거예요: eas submit. EAS가 빌드한 결과물을 Apple 또는 Google에 전달해요. 깔끔하고, 평범하고, 안정적이죠. 그런데 App Store Connect를 열어 빌드를 라이브로 전환하려는 순간 — 스크린샷 슬롯이 비어 있어요. 매번.
EAS가 모든 것을 다 해준다는 느낌 때문에 많은 분이 당황해요. 빌드하고, 서명하고, 제출하잖아요. 스크린샷도 당연히 처리해주지 않을까? 하지 않아요. 공식 문서에도 명확히 나와 있어요. 버그나 누락된 기능이 아니라, EAS Submit의 범위 밖이라는 거예요.
EAS Submit이 실제로 하는 일(과 하지 않는 일)
EAS Submit은 바이너리 전달 서비스예요. 정확히 한 가지만 업로드해요: 컴파일된 앱 아카이브 — iOS는 .ipa, Android는 .aab — 를 스토어의 처리 파이프라인에 넣어요. Expo 공식 문서는 그 경계를 명확히 밝히고 있어요:
"EAS Submit은 바이너리를 업로드하지만 스토어 리스팅 메타데이터, 스크린샷, 출시 노트는 관리하지 않습니다."
자매 도구인 EAS Metadata는 앱 이름, 부제목, 현지화된 설명, 키워드, 지원 URL 등 App Store 리스팅 일부를 설정 파일로 자동화할 수 있어요. 정말 유용하고 설정할 가치가 있어요. 하지만 범위를 꼼꼼히 읽어보세요: 스크린샷은 포함되지 않아요. EAS Metadata는 텍스트를 올려요, 이미지가 아니에요. 두 스토어 모두 스크린샷은 여전히 직접 만들어 업로드해야 해요.
따라서 Expo의 스크린샷 문제는 서로 다른 두 작업으로 나뉘어요. 머릿속에서도 분리해두는 게 도움이 돼요:
- 캡처 — 빌드에서 앱의 실제 화면을 날 프레임으로 가져오기.
- 합성 및 현지화 — 날 프레임을 기기 프레임, 캡션, 다국어 마케팅 패널로 만들어 스토어에 실제로 표시되도록 만들기.
EAS는 두 가지 모두 하지 않아요. Expo의 스토어 에셋 가이드에서는 프레임을 직접 캡처하고 Figma 같은 도구에서 패널을 디자인하도록 안내해요. 구체적인 명령어와 함께 두 작업을 살펴볼게요.
작업 1: dev 또는 preview 빌드에서 프레임 캡처하기
실제 앱의 스크린샷이 필요하므로 앱이 어딘가에서 실행 중이어야 캡처할 수 있어요. Expo에서는 dev client 또는 preview 빌드를 써야 해요 — Expo Go는 Expo 래퍼 UI를 보여주고 네이티브 설정이 다를 수 있으니 안 돼요. 표준 Expo 명령어로 로컬에서 빌드하고 실행하세요:
npx expo run:ios— 네이티브 iOS를 prebuild하고, 컴파일하고, iOS Simulator에서 앱을 실행해요.npx expo run:android— Android 에뮬레이터(또는 연결된 기기)에서 동일하게 실행해요.
iOS Simulator에서 앱이 화면에 표시된 상태에서, Mac 터미널 명령어 하나로 캡처할 수 있어요:
xcrun simctl io booted screenshot home.png
booted는 현재 실행 중인 시뮬레이터를 대상으로 하고, 픽셀 정확한 PNG를 작업 디렉터리에 저장해요. 스토어 작업에서 중요한 플래그가 두 개 있어요: --type=png(기본값이며 스토어가 원하는 형식)와 --mask=ignored 대 --mask=black — mask는 노치와 둥근 모서리를 이미지에 렌더링할지 여부를 제어해요. App Store 업로드에는 보통 평평한 직사각형 픽셀이 필요하고 합성 단계에서 기기 프레임을 나중에 추가하므로, 마스크 없이 캡처하는 게 보통 올바른 출발점이에요.
Android에서는 adb로 에뮬레이터(또는 기기)에서 직접 캡처해요:
adb exec-out screencap -p > home.png
exec-out을 사용하세요, shell screencap은 안 돼요. 일반 shell 경로는 PNG를 pseudo-terminal을 통해 파이프하는데 일부 환경에서 바이너리를 손상시켜요(캐리지 리턴이 섞인 깨진 파일이 나와요). exec-out은 바이트를 그대로 스트리밍해서 안정적이에요. 여러 에뮬레이터를 실행 중이라면 adb devices에서 확인한 adb -s <serial>로 하나를 지정하세요.
이게 수동 캡처 도구 전부예요: 명령어 두 개, 플랫폼마다 하나씩, Expo 네이티브 빌드에 이미 있는 Xcode와 Android SDK 외에 추가 의존성 없음.
작업 1, 자동화: Maestro 또는 Detox
원하는 화면으로 직접 탭해서 이동하고 명령어를 손으로 실행하는 건 몇 장 정도는 괜찮아요. 8개 화면에 두 기기 클래스가 있거나, UI와 절대 어긋나지 않도록 매 릴리즈마다 스크린샷을 재생성하고 싶다면, 앱을 조작하고 동시에 프레임을 찍을 수 있는 엔드투엔드 테스트 도구로 캡처를 자동화해요.
Maestro는 Expo가 공식 EAS Workflows 예제에서 사용하는 도구예요. Flow는 간단한 YAML로 작성해 진입 장벽이 낮아요. 화면으로 이동해 캡처하는 flow는 이런 식이에요:
appId: com.you.yourapp --- - launchApp - tapOn: "Get started" - assertVisible: "Your dashboard" - takeScreenshot: dashboard
maestro test flows/home.yaml로 실행해요. takeScreenshot 명령어는 테스트 출력 디렉터리에 PNG를 저장해요(MAESTRO_TESTS_DIR로 에셋이 저장될 위치를 지정해요). 동일한 flow를 EAS Workflows의 CI에서도 실행할 수 있어요 — Expo의 공식 예제는 e2e-test 빌드 프로파일로 .apk를 빌드하고 그 위에 .maestro/ flow를 실행하므로, e2e 스위트와 동일한 작업에서 스크린샷 캡처를 연결할 수 있어요.
Detox는 또 다른 검증된 선택지로, 더 빡빡하고 프로그래밍적인 JavaScript API를 제공해요:
const path = await device.takeScreenshot('dashboard');
하지만 Expo에서 Detox 설정에 대해 솔직하게 생각해봐야 해요. Detox는 Expo를 공식 지원하지 않아요. 실제로는 npx expo prebuild로 네이티브 프로젝트를 생성하고 JS 번들이 내장된 릴리즈 방식 클라이언트를 빌드한 뒤(dev client 아님) Detox가 그 바이너리를 가리키게 하면 작동해요. Maestro의 YAML보다 움직이는 부품이 많고, Detox의 엄격한 동기화와 어설션 API가 그 대가예요. 이미 Detox를 쓰고 있다면 캡처에 재활용하세요. 새로 선택하는 상황이고 목표가 스토어 스크린샷이라면, Maestro가 더 가벼운 경로예요.
작업 1, 수동: 드문 릴리즈에는 올바른 선택
자동화는 자주 출시할 때 본전을 찾아요. 연 1~3회 릴리즈한다면 — 대부분의 인디 Expo 앱이 그렇죠 — Maestro flow나 Detox 설정으로 스크린샷 캡처를 자동화하는 건 한 번 내고 거의 회수 못 하는 비용이에요. 그 주기라면 그냥:
- 빌드 실행.
npx expo run:ios/run:android으로 실행하고 현실적인 데모 데이터를 넣어요. - 각 핵심 화면으로 직접 이동.
- 위의
simctl/adb명령어로 캡처.
20분 클릭이 반나절 테스트 하네스 구축보다 나아요 — 다음 릴리즈 때 어떻게 유지하는지 잊어버릴 게 뻔하니까요. 수동 캡처를 부끄러워할 필요 없어요 — 스토어는 PNG가 어떻게 만들어졌는지 모르니까요.
작업 2: 합성과 50개 언어 현지화
이제 캡처 도구들이 의도적으로 건드리지 않는 부분이에요. 그리고 스토어가 실제로 평가하는 부분이기도 해요. simctl로 캡처한 날 PNG는 흰 배경 위의 앱 UI일 뿐이에요. 검색에서 노출되고 제품 페이지에서 전환을 이끄는 건 마케팅 패널이에요: 기기 프레임 안의 스크린샷, 브랜드 배경, 화면이 왜 중요한지 설명하는 한 줄 캡션 — 보통 좌에서 우로 읽히는 멀티 패널 캐러셀 형태로요. App Store에서는 스크린샷이 기기 크기와 언어별로 현지화되므로, 진지한 출시라면 다섯 개가 아닌 수십 개의 변형이 필요해요.
이게 바로 Mokbi가 자리잡는 지점이에요. 경계를 정확히 말해볼게요. Mokbi는 앱을 캡처하지 않아요 — 위의 Expo 명령어로 소스 프레임을 직접 만들어야 해요. Mokbi가 하는 건 그 프레임을 받아서 브라우저에서 이렇게 할 수 있게 해줘요: 실제 기기 프레임에 드롭하고, 캡션과 그라디언트 배경을 추가하고, 멀티 패널 캐러셀을 구성하고, 원클릭으로 캡션 텍스트를 50개 언어로 번역하고, App Store와 Play Store의 모든 크기를 한 번에 일괄 내보내기해요. 워터마크 미리보기로 무료 디자인이 가능하고, 무제한 내보내기는 구독으로 제공돼요 — Solo €29.99/mo(앱 1개) 또는 Studio €49.99/mo(앱 최대 5개), 일회성 결제 없음. Expo 가이드가 대충 언급하고 넘어가는 Figma 템플릿 단계를 대체해요 — 그 이상도 이하도 아니에요.
현실적인 통합 워크플로
- dev/preview 클라이언트 빌드.
npx expo run:ios와npx expo run:android로 실행하고 좋은 데모 데이터를 넣어요. - 소스 프레임 캡처.
xcrun simctl io booted screenshot과adb exec-out screencap -p로 수동 캡처하거나, MaestrotakeScreenshot/ Detoxdevice.takeScreenshot으로 자동화 — 매 릴리즈마다 재생성되도록 EAS Workflows에서 실행하면 이상적이에요. - 마케팅 패널 합성. 날 프레임에 기기 프레임, 캡션을 추가하고 캐러셀을 배치해요.
- 현지화 및 일괄 내보내기. 대상 언어 전체로 캡션을 번역하고 두 스토어에 필요한 모든 크기를 내보내요.
- 리스팅 에셋 업로드. App Store Connect와 Play Console에 스크린샷 업로드. EAS Metadata를 쓴다면 텍스트 필드도 함께.
- 바이너리 제출.
eas submit— EAS가 담당하는 유일한 단계. - 다음 릴리즈: 변경된 화면을 다시 캡처하고, 저장된 합성 프로젝트를 열어 프레임을 교체하고 다시 내보내요. 캡션과 번역은 그대로 유지돼요.
자동화를 건너뛸 수 있는 경우
스크린샷 차이가 실제 비용이 될 때 Maestro나 Detox 캡처를 쓰세요: 주 단위로 출시하거나, UI가 계속 바뀌거나, 여러 앱을 관리해 오래된 스토어 이미지를 방치할 수 없을 때요. 그럴 때는 CI에서 자동 재생성되는 프레임이 본전을 찾고, React Native 스크린샷 도구 이야기(Expo도 여기에 해당돼요)도 투자할 가치가 있어요.
그 외의 경우 — 분기별 한 번 출시하는 팀 — 건너뛰세요. 터미널 명령어 두 개로 수동 캡처하고, 브라우저에서 합성과 현지화를 하면 유지 비용 없이 오후 한나절에 다국어 리스팅을 완성할 수 있어요. 도구는 멋있어 보이는 CI 대시보드가 아닌 내 출시 주기에 맞춰야 해요.
어떤 방식을 선택하든 바이너리 절반은 해결돼요: eas submit이 처리해요. 업로드 전에 현재 스토어 요구사항에 맞게 스크린샷을 확인하세요 — Apple은 픽셀 하나라도 어긋나면 리스팅을 거절해요 — 나머지 출시는 그냥 디자인이에요.