store-publishing
이 절차는 2026년 11월 8일에 실제 Google Play Console 및 App Store Connect를 대상으로 마지막으로 테스트되었습니다. 두 콘솔은 공지 없이 화면, 필드 이름 및 탐색을 변경합니다. 아래 단계가 실제 보이는 것과 일치하지 않으면 추측하지 말고 이 저장소에 이슈를 열고, 수정 사항을 찾으면 PR을 보내주세요.
0. 현재 경로 결정
| 상황 | 이동할 곳 |
|---|---|
| 앱이 한 번도 제출된 적 없고, 두 콘솔 모두에 기록이 없음 | §1, 그다음 §2, §3, §4 |
| 앱이 이미 등록되어 있고, 새 빌드를 출시해야 함 | §5 (반복 경로) |
| 계정 질문 (개인 vs 조직, 이전, 패키지 이름) | §6 |
| 리뷰어가 로그인할 수 없거나 앱이 거절됨 | §7 |
모든 곳에 적용되는 규칙: 모든 업로드에는 출시되는 모든 목록 언어에 대한 릴리스 노트가 필요합니다. "새로운 기능" 상자를 비워두지 마세요. 빈 상자는 리뷰어에게 테스트되지 않은 빌드로 읽힙니다.
1. 첫 번째 설정 체크리스트 (두 스토어 모두)
순서대로 수행하세요. 각 단계는 다음 단계를 해제합니다.
- 개발자 계정이 존재하고 확인되었습니다. 앱은 실제로 제품을 소유한 계정에서 게시되어야 합니다. 즉, 기록상의 게시자는 관련 없는 앱에서 사용되는 공유 계정이나 대행사 계정이 아니어야 합니다. 특히 Apple은 관련 없는 여러 제품을 보유한 계정으로 제출할 때 상용화된 템플릿이나 앱 생성 서비스에서 나온 것처럼 보이는 앱을 거절하며, 별도로 (가이드라인 5.2.1) IP 소유자가 제출할 것을 기대합니다. 개인 대 조직 결정은 §6을 참조하세요.
- 법적 페이지가 프로덕션 도메인에 있습니다: 개인정보 보호정책, 이용약관, 앱이 가입을 허용하는 경우 계정 삭제 페이지입니다. 두 스토어 모두 이러한 URL을 요청합니다. Google의 데이터 안전성 양식은 삭제 페이지를 직접 연결합니다. 제출에 사용하기 전에 제품 소유자로부터 법적 텍스트에 대한 승인을 받으세요. 이는 기술적 결정이 아닌 비즈니스 결정입니다.
- 프레임워크 기본값이 아닌 실제 앱 아이콘 — 두 스토어 모두 변경되지 않은 기본 아이콘을 품질이 낮은 것으로 거절하거나 표시합니다. 필요한 자산: 바이너리 내의 적응형/전경 아이콘, 512×512 Play 아이콘, 1024×500 Play 기능 그래픽, 자산 카탈로그의 1024×1024 Apple 아이콘 (투명도 없음 — Apple이 평면화하며, 일반적으로 검정색으로 변환).
- 리뷰 데모 계정, 앱에 로그인이 필요한 경우. 필요 사항: 고정 식별자 (전화번호, 이메일 또는 사용자 이름)와 해당 식별자에 대해서만 유효한 고정 일회성 코드 또는 비밀번호, 리뷰어가 실제로 사용해 볼 수 있는 시드된 데모 상태, 외부 부작용 없음 (실제 SMS 없음, 실제 청구 없음). 자격 증명을 콘솔 페이지 자체 외부에 저장하세요. App Review 노트에 일반 텍스트로 붙여넣어 영구적이고 널리 읽을 수 있는 기록이 되지 않도록 하세요. 제출 직전, 매번 제출되는 정확한 빌드에 대해 로그인이 작동하는지 확인하세요.
- 데이터 인벤토리: 앱이 수집하는 모든 데이터 유형, 이유, 사용되는 SDK를 나열하는 하나의 문서 (저장소, 위키, 팀이 사양을 유지하는 곳). Google의 데이터 안전성 양식과 Apple의 앱 개인정보 보호 양식은 이 문서에서 가져와서 채워지며, 절대 기억에서 채워지지 않습니다. 앱에 새 권한이나 새 분석/진단 SDK가 추가될 때마다 인벤토리는 권한을 추가하는 동일한 변경 사항에서 변경되고, 두 양식은 다음 제출 전에 다시 작성됩니다. 양식의 내용과 바이너리의 실제 동작 간의 불일치는 일반적이고 피할 수 있는 거절 사유입니다.
- Google Play — 앱 만들기, 그런 다음 "앱 설정"을 위에서 아래로 살펴보세요: 개인정보 보호정책 URL, 앱 액세스 (공개, 또는 리뷰 계정 및 지침이 있는 제한), 광고 선언, 콘텐츠 등급 설문지 (앱의 실제 동작에서 진실하게 응답), 대상 연령층 및 연령, 정부 앱 선언, 금융 기능 선언, 건강 선언, 데이터 안전성 (인벤토리에서), 광고 ID 선언. Play App Signing을 수락하여 Google이 앱 서명 키를 보유하고 업로드 키를 교체 가능하게 유지하세요. 메인 스토어 등록 정보 (이름, 설명, 아이콘, 기능 그래픽, 최소 2개의 휴대폰 스크린샷)를 입력하세요. 그런 다음 프로덕션을 건드리기 전에 클로즈드 테스트 트랙과 릴리스를 만드세요.
- Apple — 명시적 App ID 등록, App Store Connect에서 앱 레코드 만들기 (이름, SKU, 기본 언어), 앱 정보 입력 (카테고리, 콘텐츠 권리, 연령 등급), 앱 개인정보 보호 (인벤토리에서), 가격 및 이용 가능 여부, 버전 페이지 (스크린샷, 설명, 키워드 ≤100자, 지원 URL, 저작권), App Review 정보 (필요한 경우 로그인 지침, 리뷰 연락처, 메모), 릴리스 옵션 선택 (수동 릴리스가 더 안전한 기본값입니다. "라이브 전환" 결정을 승인 후 별도의 신중한 클릭으로 만듭니다). TestFlight 빌드의 경우, 매번 수출 규정 준수 질문에 답하거나, 해당하는 경우 Info.plist에
ITSAppUsesNonExemptEncryption=false를 한 번 추가하여 질문이 반복되지 않도록 하세요. - 둘 다 일찍 제출하세요. 리뷰는 각 스토어에서 몇 시간에서 며칠이 걸리며, 첫 번째 리뷰는 일반적으로 실제 문제가 표면화되는 곳입니다. 특히 Apple의 경우 최소 한 번의 거절과 재제출을 예산에 포함하세요.
2. 릴리스 패키지 빌드
어떤 툴체인 (Flutter, React Native, Expo, 네이티브 Swift/Kotlin 프로젝트)이든 릴리스되는 정확한 커밋의 클린 체크아웃에서 빌드하고, 커밋되지 않은 변경 사항이 있는 작업 디렉토리에서 절대 빌드하지 마세요. 커밋되지 않은 편집 내용이 스토어 바이너리로 유출되면 사후에 알아차리기가 매우 어렵습니다.
- Android: 서명된 릴리스 AAB (스토어 업로드의 경우 절대 APK 아님)를 빌드 번호 (
versionCode또는 이에 상응하는 것)가 마지막으로 출시된 것보다 엄격히 높은 상태로 생성하세요. 업로드 전에 번들에 포함된 패키지 이름이 대상 Play 계정이 소유한 패키지 이름과 일치하는지 확인하세요. 일치하지 않는 패키지 이름은 업로드 단계에서 실패합니다. - iOS: 올바른 Apple Developer Program 멤버십 (앱의 인증서와 앱 레코드가 모두 속한 "팀")으로 서명하여, 빌드 번호가 마지막으로 출시된 것보다 엄격히 높고, App Store Connect 레코드가 생성된 정확한 번들 식별자를 사용하여 아카이브하고 내보내기 (또는 아카이브 단계에서 App Store Connect에 직접 업로드)하세요. 올바른 팀에서 자동 서명을 사용하면 대부분의 인증서 문제를 피할 수 있습니다.
- Both: 빌드가 프로덕션 API/백엔드를 가리키도록 하고, 스테이징이나 로컬을 가리키지 않도록 하세요. 이것이 실제로 바이너리에 내장되어 있는지 확인하고, 기본값으로 자동으로 대체될 수 있는 빌드 플래그로만 전달되지 않도록 하세요. 제품에 공유 버전 문자열이 있는 경우 iOS와 Android를 동일한 빌드/버전 번호로 유지하여 "버전 2.3"에 대한 지원 대화가 두 플랫폼에서 동일한 것을 의미하도록 하세요.
3. 스크린샷
실제 캡처만 사용하세요. Apple의 가이드라인 2.3.3은 스크린샷으로 제시된 목업 및 마케팅 합성물을 명시적으로 거절합니다. 신뢰할 수 있는 패턴은 실제 앱을 실행하고, 리뷰 계정으로 실제 (모의되지 않은) 백엔드에 로그인하고, 각 화면으로 이동하고, 프레임을 캡처하는 자동화된 UI 테스트입니다. 시뮬레이터의 손에 든 휴대폰 사진이 아닙니다.
일반적으로 포함해야 할 기기 크기 (이에 의존하기 전에 현재 스토어 요구 사항을 확인하세요. 변경될 수 있음): 대형 최신 iPhone (Apple의 현재 "가장 큰" 요구 사항), 앱이 iPad를 지원하는 경우 iPad, Play용 대표적인 Android 휴대폰 및/또는 태블릿. Apple은 대부분의 경우 가장 큰 세트에서 더 작은 iPhone 크기를 자동으로 파생합니다.
제품의 이야기를 순서대로 전달하는 작은 세트 (5-8개 이미지)를 선택하세요: 목록 또는 홈 보기, 핵심 구조 화면, 단일 항목/세부 정보 보기, 진행 중인 주요 워크플로, 완료/성공 상태, 관련이 있는 경우 설정. 기본 로그인 화면과 빈 상태는 건너뛰세요. 앱이 하는 일에 대해 아무것도 말해주지 않습니다.
알려진 문제점 (툴체인 무관):
- 디버그 빌드는 종종 보이는 디버그 리본이나 워터마크를 표시합니다. 캡처하기 전에 끄세요.
- 시뮬레이터나 에뮬레이터 세션은 재설치 전에 이전 로그인을 유지할 수 있습니다. 테스트 내에서 명시적으로 로그아웃하거나 먼저 시뮬레이터/에뮬레이터 상태를 초기화하세요.
- 다른 매개변수로 "동일한" 화면으로 다시 탐색하면 상태 저장 화면이 깔끔하게 다시 렌더링되지 않는 경우가 있습니다. 캡처 사이에 상위 화면을 통해 탐색하세요.
- 동일한 프로젝트 디렉토리에서 두 개의 캡처 세션을 동시에 실행하면 생성된 빌드 아티팩트에서 충돌이 발생하는 경향이 있습니다. 병렬로 실행하는 경우 별도의 작업 복사본을 사용하세요.
4. 업데이트 흐름 (이미 등록된 앱)
전용 반복 릴리스 체크리스트는 §5를 참조하세요. 짧은 버전: 새 빌드는 마지막으로 출시된 것보다 엄격히 높은 빌드 번호를 가지며, 마지막 릴리스 이후의 데이터 인벤토리 차이에 따라 개인정보 양식을 업데이트해야 하는지 여부가 결정되며, 릴리스 노트는 절대 건너뛰지 않으며, 리뷰 데모 계정은 제출할 때마다 새 바이너리가 가리키는 정확한 환경에서 다시 확인됩니다.
5. 반복 경로 — 앱이 이미 라이브 상태일 때의 릴리스
하나의 릴리스 = 이 목록을 위에서 아래로 한 번 통과합니다.
사전 조건 (이 중 하나라도 실패하면 중지)
- 출시되는 코드가 실제로 프로덕션에 배포되고, 모든 데이터베이스 마이그레이션이 이미 적용되었습니다. 배포와 마이그레이션은 동일한 단계가 아니며, 마이그레이션하지 않고 배포하거나 전혀 마이그레이션하지 않으면 백엔드가 준비되지 않은 상태에서 통신하는 빌드가 생성됩니다.
- 리뷰 데모 계정이 프로덕션에 로그인하고 리뷰어가 봐야 하는 데모 상태에 도달합니다.
- 마지막으로 출시된 빌드 이후의 데이터 인벤토리 차이가 확인됩니다. 새 행이 있으면 거절이 지적한 후가 아니라 제출하기 전에 개인정보 양식이 변경됨을 의미합니다.
- Apple의 버전 슬롯이 비어 있습니다. 이전 버전이 "개발자 릴리스 보류 중" 상태이거나 여전히 리뷰 중인 경우, App Store Connect에서 다음 버전 행을 만들 수 없습니다. 먼저 보류 중인 버전을 릴리스하거나 취소하세요. "이것을 보류하고, 대신 더 새로운 빌드를 제출"하는 옵션은 없습니다.
- 버전 문자열과 빌드 번호가 결정되었습니다: 빌드 번호 = 각 플랫폼에서 마지막으로 출시된 빌드 + 1; 버전 문자열은 사용자가 실제로 알아차릴 수 있는 변경 사항에 대해서만 증가합니다.
릴리스 노트
실제로 출시된 내용 (마지막 릴리스 이후 병합된 변경 사항)에서 작성하며, 사용자가 볼 수 있는 항목만 포함하고, 대략 4-8개의 글머리 기호로, 목록이 지원하는 모든 언어로 작성하세요. 여러 언어가 필요하다고 가정하기 전에 목록에 실제로 어떤 언어가 있는지 확인하세요. 하나의 언어만 구성된 목록은 해당 언어가 없는 언어에 대한 릴리스 노트 필드를 거절합니다. Apple의 경우, 목록에 완전히 새로운 언어를 추가하는 것은 독자적인 프로젝트입니다 (이름, 부제목, 설명, 키워드 및 자체 스크린샷 세트). 단순한 텍스트 상자 변경이라고 가정하지 마세요.
스크린샷
쇼핑객이 알아차릴 만한 방식으로 화면이 실제로 변경된 경우에만 다시 작업하세요. 그렇지 않으면 기존 세트를 그대로 두세요. 교체하는 경우, 추가하는 대신 이전과 동일한 순서로 전체 세트를 교체하세요. 대부분의 콘솔은 목록당 스크린샷 수를 제한하므로, 부분 교체는 해당 제한에 도달할 위험이 있습니다.
콘솔
Google Play: 인벤토리가 변경된 경우 먼저 데이터 안전성 양식을 업데이트하세요. 그런 다음: 관련 테스트 또는 프로덕션 트랙 → 새 릴리스 만들기 → AAB 업로드 → 구성된 모든 언어로 릴리스 노트 → 릴리스 검토 → 롤아웃 시작 ("롤아웃 시작"을 신중하고 확인된 조치로 취급하세요. Play 흐름에서 되돌릴 수 없는 한 번의 클릭입니다). 프로덕션 롤아웃은 백분율로 단계적으로 진행하고 몇 퍼센트 후에 문제가 보이면 일시 중지할 수 있습니다.
Apple App Store Connect: 새 빌드를 먼저 TestFlight에 첨부하고 (수출 규정 준수, "테스트할 내용"), 그런 다음 기존 버전 페이지를 편집하거나 (버전 문자열이 변경되지 않았고 이전 버전이 아직 릴리스되지 않은 경우) 새 버전을 만듭니다 (이전 사전 조건 참조 — 현재 "제출 준비 중" 상태인 버전이 없는 경우에만 가능). App Review 정보가 여전히 정확한지 다시 확인하고, 인벤토리가 변경된 경우 App Privacy를 다시 확인하고, 새 빌드를 선택하고, "새로운 기능"을 입력하고, 리뷰를 위해 제출합니다. "리뷰를 위해 제출"을 Play의 롤아웃 클릭과 동일하게 취급하세요. 즉, 자동으로 실행되는 것이 아닌 신중하고 확인된 조치입니다.
기록 유지
팀이 이미 릴리스에 대해 가지고 있는 기록 (변경 로그, 릴리스 이슈, 스프레드시트)에는 다음이 포함되어야 합니다: 출시된 버전 및 빌드 번호, 업로드 시간, 트랙/단계, 롤아웃 또는 제출을 확인한 사람, 결과가 알려진 후 리뷰 결과. 프로젝트 자체 버전 파일을 실제로 출시된 버전과 일치하도록 업데이트하세요. 여기서 불일치가 발생하면 다음 릴리스에서 실수로 빌드 번호를 재사용하는 방법입니다.
준비된 버전을 절대 방치하지 마세요.
App Store Connect에서 "제출 준비 중" 상태인 버전은 사용 가능한 유일한 버전 슬롯을 차지합니다. 그 아래에 새 버전을 만들 수 없습니다. 따라서 준비된 버전의 운명을 준비된 동일한 세션에서 결정하세요. 제출하거나, 아직 행을 만들지 마세요.
이전에 준비된 버전이 방치되어 있는 동안 더 새로운 빌드가 준비된 경우, 방치된 행을 삭제하거나 슬롯을 비우기 위해 오래된 빌드를 제출하지 마세요. 버전이 "제출 준비 중" 상태인 동안 버전 문자열은 여전히 편집 가능한 필드입니다. 제자리에서 앞으로 롤링하세요: 버전 문자열을 새 것으로 변경하고, 새 빌드를 첨부하고, "새로운 기능"을 교체하세요. 스크린샷, 리뷰 노트 및 개인정보 응답은 이월되므로 준비된 내용이 낭비되지 않습니다.
테스터 빌드 (TestFlight)와 공개 제출은 독립적인 결정입니다. 특히 TestFlight의 내부 테스트 트랙은 리뷰나 버전 행이 전혀 필요하지 않으므로, "테스터가 오늘 빌드가 필요하다"는 것은 공개 제출이 기다려야 하는 이유가 아니며, 보류 중인 공개 제출이 테스터가 기다려야 하는 이유도 아닙니다.
6. 계정, 이전, 패키지 이름
- 정책 마감일 (이 글을 쓰는 시점에서 2023년 11월 13일 — 현재 정책 확인) 이후에 생성된 개인 Google Play 개발자 계정은 최소 ...
...(번역을 위해 잘림)