앱스토어 2회 반려가 진짜로 말한 것 — 심사가 코드 대신 사용자를 묻는 이유
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
- 1편 떠오른 생각을 Notion에 박제하고 싶었다 발행
- 2편 다 만들고도 제출조차 못 한 첫 버전 발행
- 3편 준비 중독, 그리고 마케팅 공포 발행
- 4편 그래서 나는 또 도망쳤다 — v2 전면 재작성 발행
- 5편 Claude Code로 앱을 다시 짓다 발행
- 6편 앱스토어 2회 반려가 진짜로 말한 것 현재 편
- 7편 너무 느려서 내가 안 썼다 — 온디바이스 STT 피벗 발행
- 8편 매출 $0에서 다시 정한 우선순위 발행
앱스토어 심사 반려가 늘 제품 결함 때문은 아닙니다. 5편에서 적었듯이 v2는 v1보다 분명히 더 좋은 앱이 됐습니다. 위젯도 있고, 딥링크도 되고, 테스트도 단단했습니다. 그래서 저는 이번엔 다를 거라고 믿었습니다.
제출 버튼을 누른 날 밤, 저는 처음으로 심사 대기열을 새로고침하지 않았습니다. 예전 v1 때는 제출도 못 해봤고, 이번 v2는 기술적으로 흠잡을 데가 없었으니까요. Xcode 경고 0개, TestFlight 베타 사용자 0명이지만 단위 테스트 87개 통과, 메모리 프로파일링도 깨끗했습니다. 그래서 저는 심사 통보를 기다리는 대신 잠자리에 들었습니다.
앱스토어는 v2를 두 번 반려했습니다. 지금도 그 반려를 보완해 재제출을 준비하는 중입니다. 처음엔 억울했습니다. "이만큼 잘 만들었는데 뭐가 문제냐." 그런데 반려 사유를 차분히 곱씹어보면, 애플이 사실 제 앱이 아니라 제 전략을 반려하고 있었습니다. 이 편에서는 두 번의 반려가 어떻게 왔는지, 각각 무엇을 물었는지, 그리고 제가 그것을 어떻게 잘못 읽었다가 어떻게 제대로 읽게 됐는지를 씁니다.
반려는 기술 결함이 아니었다
1차 반려 통보는 제출 후 사흘 만에 왔습니다. 화면에 "Your submission has been rejected"가 뜨는 순간, 저는 즉각 Xcode 콘솔을 켰습니다. 크래시 로그부터 찾으려 했습니다. 당연히 코드 문제일 거라고 생각했으니까요. 하지만 반려 사유에는 에러 메시지도, 스택 트레이스도 없었습니다. 심사관이 쓴 문장은 짧고 건조했습니다. 요지는 이 앱이 제공하는 기능이 이미 기존 앱들과 구분되지 않으며, 스토어에서의 가치가 명확하지 않다는 것이었습니다.
처음 읽었을 때 저는 그 문장을 잘못 번역했습니다. "UI가 더 세련돼야 한다"거나 "기능이 더 많아야 한다"는 뜻으로 받아들인 것입니다. 그래서 저는 곧장 앱의 Notion 연동 화면을 개선하기 시작했습니다. 자동 분류 UI를 더 직관적으로 고쳤고, 최초 온보딩 플로를 단순화했습니다. 새로운 기능 하나를 더 붙이는 것도 검토했습니다. 코드를 고치면 다음 심사에서 통과할 수 있다고 믿었습니다.
크래시도 아니고, 가이드라인 위반도 핵심이 아니었습니다. 반려의 본질을 제 식대로 정리하면 이런 질문들이었습니다.
- 이 앱은 왜 필요한가?
- 누가 쓰는가?
- 기존의 수많은 음성 → 텍스트 앱과 무엇이 다른가?
이건 코드로 답할 수 있는 질문이 아닙니다. 더 깔끔한 UI, 더 빠른 응답, 더 많은 기능으로 답해지지 않습니다. 이 질문에 답하려면 실제로 이 앱을 쓰고 있는 사람이 있어야 합니다. 그런데 제겐 그게 0명이었습니다. TestFlight에 등록된 외부 테스터도 없었고, 지인에게 깔아달라고 부탁한 적도 없었습니다. 앱을 쓰는 사람이 한 명도 없는 상태에서, 왜 이 앱이 세상에 필요한지를 저는 심사관에게 말로만 설명하려 했습니다.
1차 반려 이후 저는 2주를 코드 개선에 썼습니다. 화면 전환 애니메이션을 다듬었고, 설정 화면 레이아웃을 재배치했으며, Notion API 호출 실패 시 사용자에게 보여주는 오류 메시지를 더 구체적으로 바꿨습니다. 어떤 변경도 틀리지는 않았습니다. 그것들은 실제로 앱을 더 낫게 만들었습니다. 하지만 반려 사유가 물은 것과는 전혀 다른 방향의 작업이었습니다. 2차 제출을 앞두고 저는 그 사실을 몰랐습니다.
2차 반려 통보는 1차 수정 제출 후 나흘 만에 왔습니다. 이번에도 크래시 없이, 이번에도 같은 맥락의 사유였습니다. 심사관의 표현은 조금 달랐지만 질문은 동일했습니다. 시장에서 이 앱이 필요한 사람이 누구인지, 그리고 그 사람이 현재 사용하는 솔루션 대신 이 앱을 선택할 이유가 무엇인지. 두 번째 반려장을 읽는 순간 저는 처음으로 질문을 잘못 읽고 있었다는 걸 알아챘습니다.
심사는 시장 검증의 대리인이었다
여기서 머리를 한 대 맞았습니다. 애플 심사자는 의도치 않게 제 자가진단(3편)과 똑같은 말을 하고 있었습니다.
"더 나은 앱을 만들어 오라"가 아니라, "이 앱이 누군가에게 필요하다는 증거를 가져오라."
3편에서 저는 매출이 제품 품질이 아니라 사람의 인지에서 나온다는 걸 인정했습니다. 그런데 그걸 머리로만 받아들이고 행동은 안 바꿨습니다(4편의 재작성). 그러자 이번엔 애플이 같은 메시지를 더 강하게, 거절이라는 형태로 다시 전달한 것입니다.
App Store Review Guidelines 4.2 항목은 "최소한의 기능만 있는 앱(Minimum Functionality)"을 명시적으로 언급합니다. 하지만 이 항목이 실제로 작동하는 방식은 기능의 수가 아니라 기능의 맥락을 묻는 것입니다. 심사관은 JustBlurt가 음성을 받아 텍스트로 전환하고 Notion에 전송한다는 사실을 알고 있었을 것입니다. 그러나 그 기능이 특정 사용자의 특정 문제를 해결한다는 증거가 앱 어디에도 없었습니다. 스크린샷에는 기능 설명만 있었고, 설명란에는 기술 스펙만 있었으며, 앱 자체는 사용 맥락을 전혀 드러내지 않았습니다.
음성 메모 앱은 앱스토어에 수백 개 있습니다. STT(Speech-to-Text) 기반의 노트 앱도 수십 개 있습니다. Notion 연동 앱도 이미 여럿 있습니다. JustBlurt는 이 세 범주를 결합한 앱이었는데, 심사관 입장에서는 "결합"이 충분한 차별화가 되지 않았습니다. 차별화는 기능의 조합이 아니라, 그 조합이 특정 상황에서 특정 사람에게 어떻게 작동하는지를 보여줄 때 생기기 때문입니다. 저는 그 "특정 상황"과 "특정 사람"을 한 번도 구체적으로 정의해본 적이 없었습니다.
심사 반려를 "품질 피드백"으로 읽으면 또 제품으로 도망치게 됩니다. "시장 검증 요청"으로 읽어야 비로소 방향이 바뀝니다. 같은 반려장도 어떻게 읽느냐에 따라 다음 7주가 완전히 달라집니다. 저는 1차 반려를 "품질 피드백"으로 읽었고, 2주를 낭비했습니다. 2차 반려에서야 "시장 검증 요청"으로 다시 읽었습니다.
생각해보면 애플의 심사 프로세스는 기이하게도 공정했습니다. 심사관은 제 앱을 쓸 이유가 없는 사람입니다. 그는 사전 맥락 없이 앱을 열어서 직관적으로 판단합니다. 그 판단이 "이 앱이 누군가에게 필요하다는 게 보이지 않는다"는 결론이었다면, 그것은 제가 아직 시장에서 그 사실을 증명하지 못했다는 뜻입니다. 심사관은 잠재 사용자의 첫 번째 반응을 대리한 것이었습니다. 그리고 그 첫 번째 반응이 두 번 연속 "왜 이게 필요한지 모르겠다"였다면, 그것은 제품이 아니라 포지셔닝의 문제였습니다.
포지셔닝이란 "누구에게, 어떤 상황에서, 무엇 대신 쓰이는가"를 정의하는 작업입니다. 저는 개발을 시작한 첫날부터 이것을 한 번도 명시적으로 작성해본 적이 없었습니다. 앱스토어 심사는 그 공백을 두 번 짚었습니다.
1차 반려 — 그날 밤 제가 한 일
1차 반려 통보를 받은 건 평일 저녁이었습니다. 메일 알림이 울렸고, 제목을 보는 순간 무언가 잘못됐다는 걸 직감했습니다. "Your submission has been rejected"는 익숙한 문장이 아니었습니다. 그것은 제가 처음 받아보는 거절이었습니다. v1은 제출조차 못 했으니 거절 경험 자체가 없었습니다.
처음 10분은 반려 사유를 여러 번 읽으며 보냈습니다. 심사관이 재현한 시나리오가 있는지, 구체적인 버그 설명이 있는지 찾았습니다. 없었습니다. 그 다음 20분은 Apple Developer Documentation의 App Review Guidelines를 뒤졌습니다. 4.2 조항을 찾아 해석했고, 가이드라인 문서에서 "최소한의 기능" 관련 조항 전체를 읽었습니다. 그리고 저는 결론을 냈습니다. "UI를 더 개선하면 된다."
이 결론이 얼마나 틀렸는지는 그 후 2주가 증명했습니다. 저는 온보딩 플로를 재설계했습니다. 처음 앱을 열었을 때 Notion 계정 연결을 유도하는 방식을 바꿨고, 마이크 권한 요청 타이밍을 조정했으며, 앱 설명 화면에 기능 목록을 더 체계적으로 배치했습니다. 스크린샷도 다시 만들었습니다. 기능을 보여주는 스크린샷에서 "시나리오를 보여주는" 스크린샷으로 바꾸려 했습니다. 하지만 그 시나리오도 제가 상상한 것이었습니다. 실제 사용자가 앱을 쓰는 장면을 관찰한 적이 없었으니까요.
2차 제출 전날, 저는 앱 설명란을 다섯 번 고쳐 썼습니다. 마지막 버전에는 "아이디어가 떠오르는 순간, 손을 쓰지 않고 Notion에 기록하는 앱"이라는 문장이 들어갔습니다. 나름대로 사용 시나리오를 설명한다고 썼지만, 그 문장 뒤에 "실제로 이렇게 쓰는 사람이 있다"는 증거는 없었습니다. 저 한 명이 그 시나리오를 상상했을 뿐입니다.
2차 반려가 왔을 때, 저는 앱 설명이 문제가 아니라는 쪽으로 생각을 고쳐먹었습니다. 앱 설명을 아무리 잘 써도, 실사용자가 없으면 그 설명은 근거 없는 주장입니다. 심사관은 그 주장을 검증할 방법이 없었고, 검증되지 않은 주장 위에 앱을 통과시키지 않았습니다.
2차 반려 — 이번엔 다르게 읽었다
2차 반려를 받던 날은 1차와 다르게 시작했습니다. 메일을 열자마자 반려 사유의 첫 줄을 읽었고, 저는 이번엔 코드를 열지 않았습니다. 대신 노트 앱을 열었습니다. 반려 사유를 그대로 붙여넣고, 그 아래에 "이 문장이 묻는 것은 무엇인가"를 적기 시작했습니다.
그 과정에서 두 번의 반려 사유를 나란히 놓고 비교했습니다. 표현은 달랐지만 구조는 같았습니다. 두 반려 모두 "이 앱이 기존 앱과 어떻게 다른가"를 물었고, 두 반려 모두 "이 앱을 쓰는 사람이 왜 이 앱을 선택하는가"를 물었습니다. 1차 반려 때 저는 첫 번째 질문만 읽었고, 그것도 기능 차별화의 문제로 받아들였습니다. 두 번째 질문, 즉 "누가 왜 선택하는가"는 제 메모에 한 줄도 없었습니다.
두 번째 질문이 핵심이라는 걸 알고 나서, 저는 솔직하게 현황을 정리했습니다. JustBlurt를 설치한 외부 사용자: 0명. TestFlight 외부 테스터: 0명. 앱을 써봤다는 지인: 0명. 제가 직접 일주일 이상 사용한 시간: 단발적인 테스트 외에는 없음. 앱이 왜 필요한지를 증언할 수 있는 사람이 세상에 아무도 없었습니다. 저 포함해서요. 저조차 이 앱을 일상적으로 쓰고 있지 않았습니다.
이 사실을 정면으로 마주하는 데 2차 반려가 필요했습니다. 1차 반려 때는 "제품을 더 잘 만들면 된다"는 방어막이 있었습니다. 2차 반려는 그 방어막을 제거했습니다. 기술적으로 더 나아진 앱이 같은 이유로 다시 거절됐다는 건, 제품 개선이 해법이 아니라는 뜻이었습니다.
2차 반려 이후 저는 앱 코드를 일주일 동안 열지 않았습니다. 대신 사용자 인터뷰 초안을 작성했습니다. 제 앱의 잠재 사용자가 누구인지를 구체적으로 적어보려 했습니다. "아이디어를 자주 흘려보내는 사람", "회의 중 생각을 Notion에 바로 기록하고 싶은 사람", "양손이 자유롭지 않은 상황에서도 메모를 남겨야 하는 사람". 각각의 사용자 유형에 대해, 현재 그들이 어떻게 이 문제를 해결하는지도 적어보려 했습니다. 적다 보니 제가 상상한 사용자들이 이미 Apple Notes, Bear, 구글 킵, Otter.ai 등으로 충분히 해결하고 있다는 걸 알았습니다.
JustBlurt가 그들에게 제안할 수 있는 건 "Notion으로 직접 간다"는 것이었습니다. 그런데 Notion을 일상적으로 쓰는 사람들은 이미 Notion의 모바일 앱이 있습니다. 음성 입력도 됩니다. 느리지만 됩니다. JustBlurt가 그것보다 확실히 나은 점을 저는 아직 사용자를 통해 검증하지 못했습니다. 이 사실이 2차 반려를 계기로 처음으로 글자로 정리됐습니다.
그래서 반려에서 뭘 했어야 했나
돌아보면 반려 직후의 올바른 행동은 코드 수정이 아니었습니다. 1차 반려를 받던 날 밤, 저는 Xcode를 열기 전에 먼저 해야 할 일이 있었습니다. 그것은 전화기를 들고 지인 다섯 명에게 전화해서 "이 앱 한번 써봐"라고 부탁하는 것이었습니다. 설치를 부탁하고, 한 시간 동안 옆에서 지켜보고, 어디서 막히는지, 어느 순간에 쓰고 싶어지는지, 어느 순간에 "이게 왜 필요하지?"라고 느끼는지를 관찰하는 것이었습니다.
그 관찰이 있었더라면 심사 노트에 쓸 내용이 달라졌을 것입니다. App Store Connect에서 제출 시 심사관에게 메모를 남길 수 있는 "Notes for Reviewer" 항목이 있습니다. 저는 그 항목에 앱의 기술 스펙을 적었습니다. "마이크 권한은 음성 녹음에 사용됩니다", "Notion API 연동을 위해 OAuth 토큰이 필요합니다" 같은 내용이었습니다. 그게 심사관이 알고 싶어 하는 것이 아니었음을 두 번째 반려 이후에야 알았습니다.
심사관이 알고 싶어 하는 것은 "누가 어떤 상황에서 이 앱을 켜는가"였습니다. 그것을 관찰로 얻고, 그 관찰을 Notes for Reviewer에 쓰는 것이 맞는 순서였습니다. 예를 들면 이런 식으로요. "이 앱은 회의 중 아이디어가 떠오를 때 양손이 자유롭지 않은 상황에서 쓰입니다. 테스트 사용자 A는 출퇴근 중 걸으면서 아이디어를 녹음하고 Notion에 자동 분류되는 기능을 주 3회 사용했습니다." 이 문장 하나가 기술 스펙 설명 전체보다 훨씬 강력했을 것입니다.
- 실사용자를 단 한 명이라도 만든다. 지인 다섯 명에게라도 깔게 하고, 쓰는 걸 옆에서 관찰합니다. TestFlight 링크를 보내고 일주일 후에 "몇 번 썼어?"라고 묻는 것도 하나의 방법입니다.
- 차별점을 말이 아니라 사용 장면으로 정의한다. "Notion 자동 분류"가 진짜 가치인지, 사용자가 실제로 그걸 위해 쓰는지 확인합니다. 가치는 기능 목록이 아니라 "어떤 순간에 켰는가"로 증명됩니다.
- 그 증거를 심사 노트에 적는다. "누가 왜 쓰는지"에 대한 답을, 추측이 아니라 관찰로 채웁니다. 숫자가 없어도 됩니다. 구체적인 장면이 있으면 됩니다.
- 스크린샷을 기능 시연이 아니라 시나리오 서사로 교체한다. 앱스토어 스크린샷 5장은 "이 앱이 무엇을 하는가"보다 "이 앱이 어떤 순간에 쓰이는가"를 보여줄 때 더 강합니다. 배경을 자연스러운 상황으로 설정하고, 앱이 해결하는 문제를 화면 위의 캡션으로 명시하는 것이 좋습니다.
- 앱 설명 첫 문장을 기능 나열이 아닌 사용자 맥락으로 시작한다. "음성을 Notion으로 전송하는 앱"이 아니라 "걸으면서, 운전하면서, 양손이 바쁜 그 순간 — 생각이 사라지기 전에 Notion에 남기는 앱"처럼 맥락부터 제시합니다.
반려는 막다른 길이 아니라 가장 정확한 시장 신호였습니다. 무료로, 그것도 두 번이나 같은 말을 해준 셈입니다. 1차 반려를 제대로 읽었다면 2차는 없었을지도 모릅니다. 하지만 두 번의 거절이 있었기에, 저는 제가 무엇을 회피하고 있었는지를 더 선명하게 알 수 있었습니다.
반려를 데이터로 다루는 법
앱스토어 반려를 감정 사건으로 처리하면 반응이 방어적이 됩니다. "심사관이 내 앱을 이해 못 한 거다", "가이드라인이 모호하다", "운이 나빴다" — 이런 반응들은 틀리지 않을 수도 있지만, 다음 제출을 바꾸지는 못합니다. 반려를 데이터 포인트로 처리하면 다음이 달라집니다.
데이터로 처리한다는 건 반려 사유를 분류하는 것을 의미합니다. 저는 이제 반려 사유를 받으면 두 칸으로 나눕니다. 첫 번째 칸은 "제품 결함" — 크래시, 가이드라인 위반, UX 문제, 접근성 누락 같은 것들입니다. 이것은 코드로 해결됩니다. 두 번째 칸은 "시장 포지셔닝" — 누가 쓰는지, 왜 이 앱이어야 하는지, 기존 해결책 대비 명확한 이점이 무엇인지에 대한 물음입니다. 이것은 코드로 해결되지 않습니다.
JustBlurt의 두 번 반려는 두 번 모두 두 번째 칸이었습니다. 저는 두 번 모두 첫 번째 칸으로 잘못 분류했고, 그 결과 두 번 모두 코드를 건드렸습니다. 만약 처음부터 "이건 시장 포지셔닝 질문이다"라고 분류했다면, 저는 2주를 UI 개선에 쓰는 대신 사용자 인터뷰에 썼을 것입니다.
두 번째로 써먹을 수 있는 프레임은 "이 작업이 반려를 푸는가, 아니면 사용자를 만드는가"를 구분하는 것입니다. 이 두 가지는 거의 항상 다른 작업입니다. 반려를 푸는 작업은 심사관이 보기에 충분하게 만드는 것입니다. 사용자를 만드는 작업은 실제로 이 앱이 필요한 사람을 찾아서 쓰게 하는 것입니다. 포지셔닝 문제일 경우, 사용자를 만드는 작업이 자동으로 반려를 푸는 작업도 됩니다. 반대는 성립하지 않습니다.
세 번째는 반려를 외부 평가로 다루는 것입니다. 친구에게 앱을 보여주면 친구는 배려해서 좋게 말합니다. 심사관은 배려하지 않습니다. 심사관은 앱을 열어서 가치가 보이지 않으면 거절합니다. 그 냉정함이 실은 가장 정직한 피드백입니다. 저에게 두 번의 반려는 그동안 제가 받은 어떤 격려의 말보다 더 많은 정보를 담고 있었습니다.
네 번째는 반려를 타임스탬프로 기록하는 것입니다. "1차 반려: 날짜, 사유 요지, 분류(제품/시장), 조치" 형식으로 노트에 남겨 둡니다. 같은 유형의 반려가 반복되면 그것은 단순한 운이 아니라 구조적 문제입니다. 타임스탬프가 있어야 패턴이 보입니다. 저는 2차 반려 이후에 이 노트를 만들었습니다. 다음 번에는 1차 반려가 오는 즉시 만들 것입니다.
마지막으로, 반려 후 72시간 안에 코드를 열지 않는 규칙을 스스로에게 줬습니다. 이 규칙은 즉각적인 방어 반응 — 코드를 고쳐서 다음 심사를 통과하겠다는 충동 — 을 차단하기 위한 것입니다. 72시간 동안은 반려 사유를 분류하고, 그것이 제품 문제인지 시장 문제인지를 판단하고, 만약 시장 문제라면 무엇을 관찰해야 하는지를 정리하는 데 씁니다. 코드는 그 이후에 열어도 늦지 않습니다.
다음 편에서는 다시 제품 쪽으로 — 단, 이번엔 정당한 제품 작업으로 — 돌아갑니다. 앱이 너무 느려서 만든 저조차 안 쓰고 있었다는, 가장 부끄럽지만 가장 결정적인 발견입니다. 반려 이후 일주일 동안 앱을 일상에서 실제로 써보려다가, 앱이 쓸 수 없을 만큼 느렸다는 걸 처음으로 인식하는 과정이 7편에 담겨 있습니다. 이 시리즈의 다른 기록들과 마찬가지로, 여기 적은 심사 과정도 실제 경험을 바탕으로 하되 서비스명과 세부 사항은 알아볼 수 없게 바꿔 옮긴 것입니다.
- 떠오른 생각을 Notion에 박제하고 싶었다 발행
- 다 만들고도 제출조차 못 한 첫 버전 발행
- 준비 중독, 그리고 마케팅 공포 발행
- 그래서 나는 또 도망쳤다 — v2 전면 재작성 발행
- Claude Code로 앱을 다시 짓다 발행
- 앱스토어 2회 반려가 진짜로 말한 것 현재 편
- 너무 느려서 내가 안 썼다 — 온디바이스 STT 피벗 발행
- 매출 $0에서 다시 정한 우선순위 발행
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기