새벽 4시 Apple 리젝 메일 — 2.1 Information Needed 대응기
바이브코딩 뉴스레터 Ep.8 — 인디 개발자의 앱 심사 대응 자동화기
2026-05-08
새벽 4시에 폰 진동이 울렸다.
보통 그 시간엔 다시 덮고 자는데, Apple 이메일 알림이라는 걸 눈치채고 화면을 켰다. 제목에 “App Review Update”가 보이는 순간 잠이 달아났다.
이 뉴스레터는 1인 인디 개발자가 Claude Code 두 세션(Mac·WSL)과 함께 의사결정을 내리는 흐름의 기록이다. Ep.1 은 만들기, Ep.2 는 죽이기, Ep.3 는 빼기, Ep.4 는 잇기, Ep.5 는 돌리기, Ep.6 은 나누기 였다. 이번 Ep.8 은 막히기 — 심사에서 막혔을 때 어떻게 뚫는지의 이야기다.
새벽 4시에 오는 메일
앱 심사 결과는 언제 올지 모른다. 제출하고 12시간 만에 온 적도 있고, 3일 넘게 걸린 적도 있다. 대기 중일 때는 이상하게 핸드폰을 더 자주 보게 된다. 마치 배달 현황 화면을 켰다 껐다 하는 것처럼.
이번에 제출한 건 포모도로였다. Flutter로 만든 타이머 앱이다. 기능은 단순하다. 25분 집중 + 5분 휴식 사이클을 알람과 함께 반복해 주는 것. 앱 자체는 복잡하지 않아서 심사도 빨리 통과할 거라고 막연히 기대했다.
틀렸다.
메일을 열었더니 제목이 “Your submission was rejected” 였다. 거절 이유는 Guideline 2.1 - Information Needed 였다.
잠이 완전히 달아났다.
2.1 Information Needed 란 무엇인가
앱 심사 리젝에는 여러 종류가 있다. 개발자들이 가장 무서워하는 건 2.1 Performance — 앱이 크래시 나거나 기능이 완전히 망가져 있다는 뜻이다. 코드를 뜯어 고쳐야 한다.
그런데 2.1 Information Needed 는 다르다.
앱이 문제 있는 게 아니다. 심사관이 앱을 제대로 테스트하지 못했다는 뜻이다.
Apple의 앱 심사 팀은 전 세계 수십만 개의 앱을 검토한다. 심사관은 앱을 처음 보는 사람이다. 로그인이 필요한 앱인지, 특정 기기에서만 동작하는 기능이 있는지, 테스트용 계정이 있어야 하는지 — 이런 걸 모르는 상태로 앱을 받는다. 충분한 정보가 없으면 심사를 완료할 수 없고, 그 상태로 리젝을 보낸다.
심사관이 보낸 메일을 그대로 옮기면 보통 이런 식이다:
“We were unable to review your app because the demo account credentials you provided did not work, or you did not provide a demo account.”
또는:
“We were unable to review your app because it is not clear how to complete the core functionality. Please provide detailed information on how to use your app.”
포모도로 앱의 경우, 메일 내용은 더 단순했다. 어떻게 앱을 사용하는지 알 수 없었다는 것. 첫 화면이 설정 화면으로 시작하는데, 거기서 뭘 해야 하는지 심사관 입장에서는 불분명했다는 뜻이다.
Apple이 요청하는 6가지 정보
2.1 Information Needed 리젝에서 Apple은 보통 다음 중 하나 이상을 요청한다.
- 데모 계정 — 로그인이 필요한 앱이라면 테스트용 아이디/비밀번호
- 테스트 방법 — 앱의 핵심 기능을 어떻게 실행하는지 단계별 설명
- 기기/OS 정보 — 특정 기기나 iOS 버전에서만 재현되는 경우
- 네트워크 조건 — WiFi 필수인지, 특정 지역에서만 동작하는지
- 재현 단계 — 문제가 있는 기능의 재현 절차
- 스크린 레코딩 — 앱 실제 사용 화면을 녹화한 영상
이 중 가장 자주 요청받는 건 테스트 방법과 스크린 레코딩 이다. 특히 앱이 조금 독특한 UX를 갖고 있거나, 첫 진입이 직관적이지 않을 때 요청이 많이 온다.
In-App Purchase가 있는 앱도 자주 걸린다. “이 기능이 유료인지, 어떻게 테스트하나요?” 하는 질문이다. 구매 완료 화면까지 심사관이 볼 수 있어야 하기 때문에, 샌드박스 계정 정보나 테스트 방법을 미리 적어두지 않으면 막히는 경우가 많다.
대응 방법: App Review Information 탭
해결 방법은 사실 간단하다. App Store Connect에 정보를 더 적으면 된다.
App Store Connect에 앱을 제출할 때 “App Review Information” 이라는 탭이 있다. 여기에:
- Notes 필드: 심사관에게 전달할 자유 양식 메모
- Demo Account 필드: 로그인 테스트용 계정 정보
- Attachment 섹션: 영상이나 문서 첨부
이 탭을 빈칸으로 두고 제출한 게 문제였다.
Notes에 뭘 쓰면 되나
심사관 입장에서 생각하면 쉽다. 처음 이 앱을 받는 사람이 혼자 5분 안에 핵심 기능을 테스트할 수 있으려면 어떤 정보가 필요할까.
포모도로 앱이라면:
이 앱은 포모도로 타이머 앱입니다.
테스트 방법:
1. 앱을 실행하면 타이머 화면이 나타납니다.
2. 화면 중앙의 시작 버튼을 탭하면 25분 집중 타이머가 시작됩니다.
3. 상단의 설정 아이콘을 탭하면 집중/휴식 시간을 조정할 수 있습니다.
4. 타이머가 종료되면 알림이 발생합니다.
알림 권한: 타이머 종료 시 알림을 받으려면 알림 권한을 허용해 주세요.
특별한 네트워크 조건은 필요하지 않습니다.
이런 식으로 단계별로 적어주면 된다. 딱 3~5줄이면 충분하다. 심사관이 앱을 켜고 5분 안에 모든 주요 기능을 돌려볼 수 있게 만들면 된다.
simctl로 시뮬레이터 녹화하기
글만으로 부족할 때는 영상을 붙이면 훨씬 강력하다. 실제로 심사관이 볼 화면을 그대로 보여주는 것이다.
macOS 에서 iOS 시뮬레이터 영상을 녹화하는 가장 간편한 방법은 xcrun simctl 명령어다.
# 현재 부팅된 시뮬레이터 화면 녹화 시작
xcrun simctl io booted recordVideo ~/demo.mov
터미널에서 이 명령을 실행한 뒤, 시뮬레이터에서 앱을 직접 사용해 보면 된다. 녹화를 멈추려면 Ctrl+C. 그러면 ~/demo.mov 파일에 MP4가 저장된다.
이 파일을 App Store Connect > App Review Information > Attachment에 업로드하면 심사관이 바로 확인할 수 있다.
영상에 담으면 좋은 것들:
- 앱 첫 실행 화면부터 시작
- 핵심 기능 1~2개 순서대로 사용하는 장면
- 로그인이 필요하면 로그인 과정도 포함
- 2~3분 이내로 간결하게
자동화로 풀어낸 방법
이번 리젝을 받고 나서, 수동으로 App Store Connect에 들어가서 Notes를 입력하고 영상을 첨부했다. 그리고 재제출했다.
재심사는 4시간 만에 통과했다. 앱 자체의 문제가 아니었으니까.
그런데 마음에 걸리는 게 있었다. 이걸 다음에 또 빠뜨릴 수 있다는 것이다. 지금은 앱이 6개다. 앱마다 심사 제출할 때마다 App Review Information을 체크하는 건 반복 노동이다. 빠뜨리면 리젝 → 재제출 → 다시 대기 루프에 빠진다.
그래서 자동화했다.
Playwright MCP로 App Store Connect 자동 채우기
App Store Connect는 공식 API에서 App Review Information Notes 수정을 완전히 지원하지 않는다. 일부 필드는 API가 있지만, Notes 같은 자유 텍스트 필드는 웹 UI를 직접 써야 한다.
여기서 Playwright MCP가 등장한다. Claude Code에 Playwright MCP를 연결하면 브라우저를 코드로 제어할 수 있다. Mac 본진에서 이미 App Store Connect 로그인 세션이 유지되고 있기 때문에, Playwright로 직접 그 세션에 붙어서 폼을 채우는 게 가능하다.
전체 흐름은 이렇다:
- App Store Connect의 해당 앱 페이지로 이동
- App Review Information 탭 클릭
- Notes 필드 찾아서 기존 내용 지우고 새 내용 입력
- 영상 파일 경로 알고 있으면 Attachment 섹션에 업로드
- Save 버튼 클릭
Claude Code에 “포모도로 앱 App Review Information Notes 업데이트해줘, 내용은 이거야: …” 하고 지시하면, Playwright가 브라우저를 열고 App Store Connect에 접속해서 자동으로 폼을 채워준다.
수동으로 하면 5분짜리 작업이다. 자동화되어 있으면 지시 한 줄이다.
iOS 시뮬레이터 자동 녹화 + 첨부
시뮬레이터 녹화도 자동화했다. 흐름은:
xcrun simctl boot <device-id>로 특정 시뮬레이터 기동xcrun simctl install booted <app-path>로 앱 설치xcrun simctl io booted recordVideo ~/review-demo.mov &로 백그라운드 녹화 시작xcrun simctl launch booted <bundle-id>로 앱 실행- 앱 조작 (applesimutils나 시뮬레이터 UI 이벤트)
- 일정 시간 후 녹화 프로세스 종료
- 생성된
.mov파일을 App Store Connect에 업로드
이걸 Claude Code에서 bash 명령 순서대로 실행하면 된다. 녹화 자동화가 완전히 매끄럽진 않다 — 시뮬레이터 UI 이벤트를 자동으로 보내는 게 까다롭기 때문이다. 지금은 녹화 시작만 자동화하고, 실제 앱 조작은 사람이 직접 하는 방식으로 운영 중이다.
다음 목표: 제출 전 자동 체크 훅
지금 당장 만들고 싶은 건 제출 전 자동 체크 다.
심사 제출 루틴이 실행될 때, App Review Information Notes가 비어있으면 자동으로 경고를 띄우거나 멈추는 훅이다.
submit-app 스킬 안에 다음 로직을 추가할 예정이다:
- App Store Connect API로 현재 App Review Information 상태 조회
- Notes 필드가 비어있으면 “Notes 채우지 않으면 제출 안 됩니다” 차단
- 또는 미리 준비한 기본 템플릿을 자동으로 채우고 확인 요청
이 훅 하나가 있으면 2.1 Information Needed 리젝을 거의 100% 막을 수 있다. 리젝 → 재제출 루프에 드는 시간이 최소 4~5시간이다. 앱이 6개면 총 리젝 비용이 꽤 된다.
교훈: 리젝은 실패가 아니라 프로세스의 일부
처음 개발자 생활을 시작했을 때, 앱 리젝은 꽤 충격적으로 느껴졌다. Apple이 내 앱을 거절했다는 게 개인적인 판단처럼 들렸다.
지금은 다르게 생각한다.
2.1 Information Needed 리젝은 절차상의 누락 이다. 코드 문제가 아니다. 심사관에게 충분한 맥락을 전달하지 않은 것이다. 고칠 수 있다. 빠르게 고칠 수 있다.
앱 심사에서 중요한 건 리젝을 안 받는 게 아니라, 리젝을 받았을 때 빠르게 대응하는 것 이다. 턴어라운드 타임을 줄이는 것. 이번 포모도로 앱은 리젝 → 재제출 → 승인까지 5시간도 안 걸렸다.
몇 가지 배운 것들:
처음 제출할 때 Notes는 반드시 채울 것. 앱이 단순해 보여도 채운다. 심사관은 이 앱을 처음 보는 사람이다. 5분 안에 핵심 기능을 테스트할 수 있게 만들어줘야 한다.
In-App Purchase가 있으면 더 꼼꼼하게. 유료 기능이 있는 앱은 심사관이 그 기능을 어떻게 테스트해야 하는지 알아야 한다. 샌드박스 계정 정보나 “이 기능은 테스트 환경에서 무료로 작동합니다” 같은 메모가 있으면 훨씬 매끄럽다.
영상 한 편이 글 열 줄보다 낫다. simctl 녹화는 2분도 안 걸린다. 한 번 해두면 재제출할 때 바로 쓸 수 있다.
대응 자동화를 미리 만들어두면 리젝도 두렵지 않다. Playwright로 App Store Connect 폼을 자동으로 채우는 파이프라인이 있으면, 리젝 메일 받고 커피 한 잔 마시는 사이에 재제출이 가능하다.
마무리
이른 시간에 리젝 메일을 확인하는 건 여전히 기분 좋은 경험은 아니다. 그래도 이제는 어떻게 해야 할지 안다.
App Store Connect 켜고, App Review Information 탭 열고, Notes 채우고, 필요하면 시뮬레이터 영상 붙이고, 재제출. 빠르면 같은 날 통과된다.
1인 개발자의 앱 심사 프로세스가 이렇게 생겼다. 리젝은 막을 수 없지만, 리젝에 무너지지 않게 루틴을 만들어두는 건 할 수 있다.
다음 회에서는: 맥미니를 24시간 AI 워커로 만들며 OpenClaw에서 Codex로 두 번 갈아탄 이야기.
— 강대종 (1인 바이브코더, Claude Code 동반자) / @ssamssae