Apple App Store 등록 및 심사 가이드
작성일: 2026-04-06 Last Updated: 2026-04-06 대상: Flutter Mobile App (iOS) 공통 참조:
../common/security.md(코드 서명),../common/ci-cd.md(배포 파이프라인)
목차
- App Store 등록 절차
- App Store Connect 설정
- 스크린샷 규격
- App Store Review Guidelines 핵심
- 프라이버시 라벨 (App Privacy)
- 앱 추적 투명성 (ATT)
- In-App Purchase 설정
- TestFlight 베타 배포
- 심사 거부 대응 가이드
- 체크리스트
1. App Store 등록 절차
사전 요구사항
| 항목 | 상세 | 비용 |
|---|---|---|
| Apple Developer Program | 개인 또는 조직 등록 | $99/년 |
| D-U-N-S 번호 | 조직 등록 시 필수 (무료 발급) | 무료 |
| Apple ID | 2FA 필수 활성화 | - |
| Xcode | 최신 안정 버전 | 무료 |
| macOS | Xcode 호환 macOS | - |
등록 단계
| 단계 | 작업 | 소요 시간 |
|---|---|---|
| 1 | Apple Developer Program 가입 (https://developer.apple.com) | 개인: 즉시, 조직: 1-3일 |
| 2 | App Store Connect 접속 (https://appstoreconnect.apple.com) | - |
| 3 | 인증서 생성 (Signing & Capabilities) | 30분 |
| 4 | App ID + Provisioning Profile 생성 | 30분 |
| 5 | App Store Connect에서 앱 생성 | 15분 |
| 6 | 빌드 업로드 (Xcode 또는 CI) | 15-30 분 |
| 7 | 메타데이터 입력 + 스크린샷 업로드 | 1-2시간 |
| 8 | 심사 제출 | - |
| 9 | 심사 대기 | 평균 24-48시간 |
인증서 관리 (CI/CD 환경)
# fastlane match 사용 권장 (팀 인증서 공유)
fastlane match init
# Matchfile 설정
git_url("https://github.com/myorg/certificates")
storage_mode("git")
type("appstore")
app_identifier("com.myapp.app")
team_id("TEAM_ID")
# 인증서 동기화
fastlane match appstore # App Store 배포용
fastlane match development # 개발용
2. App Store Connect 설정
앱 정보 입력 항목
| 필드 | 설명 | 예시 |
|---|---|---|
| App Name | 스토어 표시 이름 (30자 이내) | MyApp |
| Subtitle | 보조 설명 (30자 이내) | 스마트한 업무 관리 도구 |
| Bundle ID | 고유 식별자 | com.mycompany.myapp |
| SKU | 내부 관리 코드 | MYAPP_IOS_2026 |
| Primary Language | 기본 언어 | Korean |
| Category | 앱 카테고리 (최대 2개) | Productivity, Business |
| Content Rights | 제3자 콘텐츠 포함 여부 | - |
| Age Rating | 연령 등급 질문 응답 | - |
가격 및 사용 가능 여부
App Store Connect > App > Pricing and Availability
- 가격 유형 선택 (무료 / 유료 / Freemium)
- 국가별 출시 지역 선택
- 사전 주문 설정 (선택)
앱 심사 정보
| 필드 | 설명 |
|---|---|
| 연락처 정보 | 심사팀이 연락할 이메일/전화번호 |
| 데모 계정 | 로그인 필요 앱은 테스트 계정 필수 제공 |
| 심사 노트 | 특수 기능 설명, 테스트 방법 안내 |
주의: 데모 계정 미제공은 심사 거부 사유 1위. 반드시 유효한 테스트 계정 입력.
3. 스크린샷 규격
필수 디바이스 스크린샷
| 디바이스 | 크기 (pixels) | 필수 여부 | 대상 |
|---|---|---|---|
| iPhone 6.7" | 1290 x 2796 | 필수 | iPhone 15 Pro Max, 14 Pro Max |
| iPhone 6.5" | 1284 x 2778 또는 1242 x 2688 | 필수 | iPhone 14 Plus, 11 Pro Max |
| iPhone 5.5" | 1242 x 2208 | 선택 | iPhone 8 Plus (구형 지원 시) |
| iPad Pro 12.9" (6세대) | 2048 x 2732 | iPad 지원 시 필수 | iPad Pro |
| iPad Pro 12.9" (2세대) | 2048 x 2732 | iPad 지원 시 필수 | iPad Pro (구형) |
스크린샷 요구사항
| 항목 | 요구사항 |
|---|---|
| 수량 | 디바이스당 최소 1개, 최대 10개 |
| 형식 | PNG 또는 JPEG (투명 배경 불가) |
| 방향 | 세로 또는 가로 (혼합 불가) |
| 콘텐츠 | 앱 실제 화면 기반 (과도한 목업 금지) |
| 텍스트 | 현지화 권장 |
자동 스크린샷 생성 (fastlane snapshot)
# Snapfile
devices([
"iPhone 15 Pro Max",
"iPhone 14 Plus",
"iPad Pro (12.9-inch) (6th generation)",
])
languages(["ko", "en-US", "ja"])
scheme("Runner")
output_directory("./fastlane/screenshots")
clear_previous_screenshots(true)
fastlane snapshot
fastlane deliver # 스크린샷 + 메타데이터 일괄 업로드
App Preview (동영상)
| 항목 | 규격 |
|---|---|
| 길이 | 15-30초 |
| 형식 | MP4, MOV |
| 해상도 | 스크린샷과 동일 해상도 |
| 오디오 | 선택적 (음소거 가능) |
4. App Store Review Guidelines 핵심
심사 거부 사유 Top 10
| 순위 | 가이드라인 | 거부 사유 | 대응 방안 |
|---|---|---|---|
| 1 | 2.1 앱 완성도 | 크래시, 미완성 기능, 플레이스홀더 | QA 완료 후 제출, 모든 링크 유효 확인 |
| 2 | 2.3.3 스크린샷 | 실제 앱과 불일치 | 실제 동작 화면 캡처 사용 |
| 3 | 4.0 디자인 | 최소 기능 미달, 웹뷰 래핑 | 네이티브 기능 활용, 고유 가치 제공 |
| 4 | 5.1.1 데이터 수집 | 개인정보 수집 미고지 | 프라이버시 라벨 정확 작성, 개인정보 처리방침 |
| 5 | 3.1.1 IAP 요구 | 디지털 콘텐츠를 외부 결제로 처리 | 디지털 콘텐츠는 반드시 IAP 사용 |
| 6 | 2.3.7 정확한 설명 | 앱 설명과 실제 기능 불일치 | 설명 정확히 기재 |
| 7 | 5.1.2 데이터 활용 | 불필요한 권한 요청 | 최소 권한 원칙, 용도 설명 |
| 8 | 4.2 최소 기능 | 단순 웹사이트 래핑 앱 | 네이티브 기능 (푸시, 오프라인 등) 추가 |
| 9 | 1.2 사용자 콘텐츠 | UGC 관리 기능 미비 | 신고, 차단, 콘텐츠 필터링 구현 |
| 10 | 2.5.1 공개 API만 사용 | 비공개 API 호출 | 공식 SDK/API만 사용 |
주요 가이드라인 요약
3.1 결제
| 규칙 | 설명 |
|---|---|
| 디지털 콘텐츠/구독 | 반드시 IAP 사용 (Apple 수수료 15-30%) |
| 물리적 상품/서비스 | 외부 결제 가능 (Stripe 등) |
| Reader 앱 | 외부 구매 콘텐츠 소비 가능 (앱 내 구매 유도 불가) |
| 크로스 플랫폼 구독 | 서버 검증으로 동기화 가능 |
4.0 디자인
| 규칙 | 설명 |
|---|---|
| Human Interface Guidelines | Apple HIG 준수 |
| 네이티브 기능 활용 | 웹뷰만의 앱은 거부 대상 |
| 최소 기능 | 의미 있는 고유 기능 필수 |
5.1 프라이버시
| 규칙 | 설명 |
|---|---|
| 개인정보 처리방침 | URL 필수 제공 |
| 프라이버시 라벨 | 모든 데이터 수집 항목 정확 기재 |
| 목적 문자열 | 카메라, 위치 등 권한 사용 이유 명시 (Info.plist) |
5. 프라이버시 라벨 (App Privacy)
데이터 수집 카테고리
| 카테고리 | 하위 항목 예시 | 일반적 SaaS 앱 해당 여부 |
|---|---|---|
| Contact Info | 이름, 이메일, 전화번호 | O |
| Identifiers | 사용자 ID, 디바이스 ID | O |
| Usage Data | 앱 인터랙션, 기능 사용 통계 | O |
| Diagnostics | 크래시 데이터, 성능 데이터 | O |
| Location | 대략적 위치, 정확한 위치 | 기능에 따라 |
| Financial Info | 결제 정보 | 직접 처리 시 |
| Health & Fitness | 건강 데이터 | 해당 시 |
| Purchases | 구매 이력 | O |
데이터 사용 목적
| 목적 | 설명 |
|---|---|
| App Functionality | 앱 핵심 기능 동작을 위해 |
| Analytics | 사용 패턴 분석 |
| Developer's Advertising | 자체 광고 |
| Third-Party Advertising | 제3자 광고 |
| Product Personalization | 개인화 |
프라이버시 라벨 작성 시 체크포인트
| # | 확인 항목 |
|---|---|
| 1 | 제3자 SDK (Firebase, Sentry 등)가 수집하는 데이터도 포함했는가? |
| 2 | 서버에서 수집하는 데이터도 포함했는가? |
| 3 | 데이터와 사용자 신원을 연결(Linked)하는지 정확히 구분했는가? |
| 4 | 추적(Tracking)에 해당하는 데이터 수집이 있는가? |
| 5 | 개인정보 처리방침 URL이 유효하고 최신인가? |
6. 앱 추적 투명성 (ATT)
ATT 요구사항
iOS 14.5+부터 사용자 추적 시 반드시 ATT 권한 요청 필요.
| 추적에 해당하는 경우 | 추적이 아닌 경우 |
|---|---|
| IDFA를 광고 네트워크에 전송 | 자사 분석만 수행 (Firebase Analytics 기본 설정) |
| 사용자 데이터를 데이터 브로커에 공유 | 사기 탐지, 보안 목적 |
| 광고 타겟팅용 이메일 해시 공유 | 앱 내부 분석 (Linked to User이지만 Tracking 아님) |
Flutter ATT 구현
// pubspec.yaml
// dependencies:
// app_tracking_transparency: ^2.0.0
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
class TrackingPermission {
/// ATT 권한 요청 (앱 최초 실행 시)
static Future<TrackingStatus> requestPermission() async {
// iOS 14.5+ 에서만 동작, 그 외는 자동 authorized
final status = await AppTrackingTransparency.trackingAuthorizationStatus;
if (status == TrackingStatus.notDetermined) {
// 권한 요청 전 사용자에게 설명 다이얼로그 표시 (권장)
// -> "맞춤 광고를 위해 활동 추적 허용이 필요합니다"
// -> 시스템 다이얼로그 표시
return await AppTrackingTransparency.requestTrackingAuthorization();
}
return status;
}
/// IDFA 조회 (authorized 상태에서만 유효한 값 반환)
static Future<String?> getIdfa() async {
final status = await AppTrackingTransparency.trackingAuthorizationStatus;
if (status == TrackingStatus.authorized) {
return await AppTrackingTransparency.getAdvertisingIdentifier();
}
return null;
}
}
Info.plist 필수 설정:
<key>NSUserTrackingUsageDescription</key>
<string>맞춤형 콘텐츠와 광고를 제공하기 위해 활동 추적 권한이 필요합니다.</string>
ATT 권한 요청 UX 가이드
| 단계 | 설명 |
|---|---|
| 1 | 온보딩 완료 후 (앱 첫 실행 직후 X) |
| 2 | 사전 설명 다이얼로그 표시 (왜 필요한지) |
| 3 | 시스템 ATT 다이얼로그 표시 |
| 4 | 거부 시 기능 제한 없이 정상 동작 |
7. In-App Purchase 설정
App Store Connect IAP 상품 등록
App Store Connect > App > In-App Purchases
| 상품 유형 | 용도 | 예시 |
|---|---|---|
| Auto-Renewable Subscription | 정기 구독 | Pro 월간/연간 |
| Non-Renewing Subscription | 비자동갱신 구독 | 시즌 패스 |
| Consumable | 소모품 | 크레딧, 코인 |
| Non-Consumable | 비소모품 | 프리미엄 잠금 해제 |
StoreKit 2 (Flutter에서 사용)
// in_app_purchase 공식 패키지 사용
// pubspec.yaml
// dependencies:
// in_app_purchase: ^3.1.0
// 또는 RevenueCat 사용 권장 (크로스 플랫폼 통합 관리)
// -> in-app-purchase.md 상세 참조
구독 그룹 설정
App Store Connect > In-App Purchases > Subscription Groups
그룹: "Premium"
├── Pro Monthly ($9.99/월)
├── Pro Yearly ($79.99/년) <- 16% 할인 강조
└── Enterprise ($29.99/월)
같은 그룹 내 상품은 자동 업그레이드/다운그레이드 적용.
Introductory Offers 설정
| Offer 유형 | 설명 | 제한 |
|---|---|---|
| Free Trial | 무료 체험 (3일~1년) | 구독 그룹당 1회 |
| Pay as You Go | 할인가 반복 (최대 3주기) | 구독 그룹당 1회 |
| Pay Up Front | 할인가 일시불 | 구독 그룹당 1회 |
8. TestFlight 베타 배포
TestFlight 개요
| 항목 | 상세 |
|---|---|
| 내부 테스터 | 최대 100명 (App Store Connect 사용자) |
| 외부 테스터 | 최대 10,000명 (이메일 초대 또는 공개 링크) |
| 빌드 유효기간 | 업로드 후 90일 |
| 외부 테스트 심사 | 첫 빌드 + 주요 변경 시 (보통 24시간 이내) |
업로드 방법
# 1. 빌드
flutter build ipa --flavor prod -t lib/main_prod.dart --release
# 2. Xcode에서 업로드
# Xcode > Product > Archive > Distribute App > App Store Connect
# 3. 또는 fastlane으로 자동화
fastlane pilot upload \
--ipa "./build/ios/ipa/MyApp.ipa" \
--skip_waiting_for_build_processing true
CI/CD 자동 TestFlight 배포
# .github/workflows/ios-testflight.yml (발췌)
- name: Upload to TestFlight
run: |
xcrun altool --upload-app \
--type ios \
--file build/ios/ipa/MyApp.ipa \
--apiKey ${{ secrets.APP_STORE_API_KEY_ID }} \
--apiIssuer ${{ secrets.APP_STORE_API_ISSUER_ID }}
테스트 그룹 관리
| 그룹 | 대상 | 용도 |
|---|---|---|
| Internal QA | 개발팀, QA팀 | 매 빌드 테스트 |
| Beta Testers | 선별된 외부 사용자 | 사용성 피드백 |
| Public Beta | 공개 링크 | 대규모 베타 |