babipanote·
#앱스토어 심사#lesson#리젝#iOS#GentleDo

앱스토어 리젝 대응기 — 거절 메일을 받고 한 일

Your app has been rejected. 그 한 줄에 처음엔 심장이 내려앉았다. 세 번의 리젝을 거치며 거절 메일이 어떻게 체크리스트가 됐는지, 사유별 대응과 리뷰어와의 소통법을 그대로 적은 회고.

읽는 시간 8

Your app has been rejected.

그 한 줄에 처음엔 심장이 내려앉았다. App Store Connect에 빨간 점이 뜨고, 메일 제목에 rejected가 박혀 있던 그날 밤, 나는 무엇을 잘못했는지도 모른 채 노트북을 덮었다 다시 열었다.

GentleDo의 첫 심사는 2일 만에 통과했다. 그래서 더 방심했다. 출시 이후 업데이트를 올리면서 나는 세 번 리젝을 맞았다. 그리고 이상하게도, 세 번째쯤 되니 그 메일이 더는 무섭지 않았다. 심장이 내려앉던 한 줄이, 어느새 체크리스트가 됐다.

오늘은 그 세 번의 거절과, 각각에 내가 한 일을 그대로 적는다.

어떤 사유로 리젝됐나 — 흔한 케이스 3개

세 번의 리젝은 신기하게도 전부 다른 가이드라인 조항이었다. Apple의 App Store Review Guidelines를 그제서야 처음부터 끝까지 읽었다. 그동안 나는 코드만 봤지, 이 문서를 본 적이 없었다.

회차리젝 사유 (Guideline)한 줄 원인내가 한 대응
1차2.3.3 — 메타데이터 부정확스크린샷이 구버전 UI라 실제 화면과 불일치스크린샷 5장 전부 최신 빌드로 재촬영·교체
2차5.1.1 — 권한 사유 불충분알림 권한 요청 텍스트가 너무 일반적NSUserNotification 설명을 기능 맥락으로 다시 작성
3차2.1 — 기능 동작 미확인리뷰어 기기에서 특정 화면이 빈 채로 떴다빈 상태(empty state) 처리 + 재현 영상 첨부

표로 적고 나니 허무할 만큼 사소한 것들이다. 세 번 다 "기능이 나쁘다"가 아니라 "설명이 부족하다" 쪽이었다. 심사는 내 앱의 품질을 보는 게 아니라, 내가 얼마나 정직하고 명확하게 설명했는가를 본다는 걸 그제야 알았다.

각 대응 — 메타데이터·권한 설명·가이드라인

1차, 메타데이터. 가장 쉬웠다. 출시 후 UI를 한 번 갈아엎었는데 스크린샷을 깜빡했다. 리뷰어 입장에선 스토어에 올라온 그림실제 앱이 다른 것이고, 그건 곧 사용자 기만이다. 최신 빌드로 5장을 다시 찍어 올렸다. 30분 걸렸다.

2차, 권한 설명. 여기서 진짜 배웠다. 나는 알림 권한 요청 문구를 "알림을 받으시겠습니까?" 수준으로 막연하게 적어뒀다. 리뷰어는 "이 권한이 왜 필요한지 사용자가 알 수 없다"고 했다. 그래서 Info.plist의 usage description을 *"태스크 시작·마감 시간에 맞춰 알림을 보내기 위해 사용합니다"*처럼 기능 맥락으로 다시 썼다. 권한은 받는 게 목적이 아니라, 왜 받는지를 설명하는 게 목적이었다.

3차, 기능 동작. 가장 까다로웠다. 내 기기·시뮬레이터에선 멀쩡한데 리뷰어 기기에서만 특정 화면이 비어 보였다. Flutter 패키지 버전 하나로 크래시를 겪었던 때처럼, 내 환경에서 재현 안 되는 버그가 제일 무섭다. 데이터가 없을 때의 empty state를 제대로 그려넣고, Resolution Center에 재현 영상을 첨부해 "이렇게 동작합니다"를 보여줬다.

GentleDo App Store Connect Resolution Center — 리뷰어 메시지와 재현 영상 첨부, 리젝 사유별 대응 메모

리뷰어와 소통하는 법

세 번을 겪으며 가장 크게 바뀐 건 리뷰어를 적으로 보지 않게 된 것이다.

처음엔 리젝 메일을 받으면 억울했다. "왜 이걸 문제 삼지?" 싶었다. 그런데 Resolution Center에서 또박또박 답을 쓰다 보니 알았다. 리뷰어는 내 앱을 처음 보는 사용자다. 그가 막힌 지점은 곧 진짜 사용자가 막힐 지점이다.

그래서 답변 방식을 바꿨다. 변명하지 않고, 무엇을 어떻게 고쳤는지만 적었다. "지적해주신 X 화면은 데이터가 없을 때 빈 상태로 보였습니다. empty state를 추가했고, 재현 영상을 첨부합니다." 짧고 사실만. 이렇게 쓰니 다음 심사가 더 빨리 통과됐다.

다음 제출에서 미리 막은 것

세 번의 시체가 쌓이니 제출 전 셀프 체크리스트가 생겼다. 코드를 다 짜고 나면, 빌드를 올리기 전에 이걸 본다.

  • 스크린샷이 지금 빌드의 화면과 같은가
  • 모든 권한 요청 문구가 왜 필요한지를 한 문장으로 말하는가
  • 데이터가 0개일 때 모든 화면이 빈 채로 안 깨지는가
  • 계정·로그인이 필요하면 리뷰어용 테스트 계정을 메모에 적었는가
  • 리뷰 노트에 핵심 기능을 한 줄로 설명했는가

6개 프로젝트를 말아먹으며 배운 것과 똑같은 구조다. 실패는 체크리스트로 번역될 때만 자산이 된다. 그냥 아픈 채로 두면 다음에 또 같은 곳에서 넘어진다.

다음 계획

다음 업데이트는 cross-day 태스크 지원이다. 기능이 커진 만큼 심사도 한 번에 통과하긴 어려울 거라 생각한다. 다만 이번엔 리젝을 전제로 제출한다. 통과하면 좋고, 막히면 위 체크리스트에 한 줄을 더한다.

리젝은 실패가 아니라 아직 설명이 부족하다는 신호다. 처음 그 한 줄에 심장이 내려앉았던 나에게, 지금의 나는 이렇게 말해주고 싶다. "그건 네 앱을 거절한 게 아니라, 조금 더 친절해지라는 메모였다."


이 글은 GentleDo 빌더 저널의 한 편이다. 위에 링크한 첫 심사 통과기·Claude Code 개발기·부업 1년 실패기와 함께 읽으면 같은 길의 앞뒤가 보인다.

관련 글