Flutter 앱을 Apple App Store에 출시하는 완벽 가이드
처음 앱을 출시하는 분들을 위한 상세 가이드입니다. 한 번도 앱을 배포해본 적 없어도 괜찮습니다. 이 글을 처음부터 끝까지 따라가면 여러분의 Flutter 앱이 App Store에 올라가게 됩니다.
1. Apple Developer Program 등록
왜 필요한가요?
Apple은 App Store에 앱을 올리려는 개발자에게 Apple Developer Program 가입을 요구합니다. 이것은 Apple이 앱의 품질과 보안을 관리하고, 개발자의 신원을 확인하기 위한 절차입니다. 가입하지 않으면 앱을 App Store에 절대 올릴 수 없습니다.
비용
- 연간 $99 (USD), 매년 갱신해야 합니다.
- 갱신하지 않으면 앱이 App Store에서 내려갑니다.
- 한국 원화 기준으로 약 13만 원 정도입니다 (환율에 따라 변동).
등록 절차
1단계: Apple ID 준비
이미 Apple ID가 있다면 그것을 사용하면 됩니다. 없다면 Apple ID 생성 페이지에서 만드세요.
[주의] 개인 Apple ID와 개발용 Apple ID를 따로 쓰는 분들도 있습니다. 하지만 처음이라면 기존 Apple ID를 그대로 사용해도 문제없습니다.
2단계: Apple Developer 웹사이트 접속
Apple Developer Programs 에 접속하여 "Enroll" 버튼을 클릭합니다.
3단계: 본인 인증 (2단계 인증 필수)
Apple은 보안을 위해 2단계 인증(Two-Factor Authentication)이 활성화된 Apple ID만 Developer Program에 가입할 수 있게 합니다. 아직 활성화하지 않았다면:
- iPhone 또는 Mac에서 설정 > [내 이름] > 로그인 및 보안 > 이중 인증으로 이동합니다.
- 이중 인증을 켭니다.
- 신뢰할 수 있는 전화번호를 등록합니다.
4단계: 개인 또는 조직 선택
- 개인(Individual): 혼자 개발하는 경우. 본인 이름이 App Store에 "판매자"로 표시됩니다.
- 조직(Organization): 회사나 단체 명의로 출시하는 경우. D-U-N-S 번호가 필요합니다.
개인 개발자라면 "Individual"을 선택하세요. 조직으로 등록하려면 사업자등록증과 D-U-N-S 번호가 필요하고 심사에 시간이 더 걸립니다.
5단계: 신원 확인
개인 등록의 경우, Apple이 본인 확인을 요청할 수 있습니다. 최근에는 iPhone 또는 iPad의 Apple Developer 앱을 통해 본인 인증을 진행하는 경우가 많습니다.
- App Store에서 "Apple Developer" 앱을 설치합니다.
- Apple ID로 로그인합니다.
- 앱 내에서 등록 절차를 진행하면 신분증 촬영 등의 본인 인증이 진행됩니다.
[참고] 본인 인증은 보통 1~3일 정도 걸립니다. 빠르면 당일에 완료되기도 합니다. 주말이나 공휴일에는 시간이 더 걸릴 수 있습니다.
6단계: 결제
본인 인증이 완료되면 $99를 결제합니다. Apple ID에 등록된 결제 수단(신용카드 등)으로 결제됩니다.
7단계: 가입 완료 확인
결제가 완료되면 보통 최대 48시간 이내에 계정이 활성화됩니다. 활성화되면 App Store Connect에 로그인할 수 있게 됩니다.
[팁] Developer Program 가입이 완료되었는지 확인하려면 Apple Developer Account 에 접속해서 "Membership" 섹션을 확인하세요. "Active"라고 표시되면 성공입니다.
2. App Store Connect에서 앱 등록
왜 필요한가요?
App Store Connect는 Apple이 제공하는 앱 관리 웹 포털입니다. 앱의 정보를 입력하고, 빌드를 관리하고, 심사를 제출하고, 매출을 확인하는 모든 작업이 여기서 이루어집니다. 빌드를 업로드하기 전에 먼저 여기서 앱을 "등록"해두어야 합니다.
번들 ID (Bundle Identifier) 이해하기
번들 ID는 앱의 고유한 식별자입니다. 전 세계에서 유일해야 하며, 한 번 정하면 변경할 수 없습니다.
- 형식: 역방향 도메인 표기법 (예:
com.yourcompany.yourapp) - 예시:
com.example.justqr
[주의] 번들 ID는 나중에 절대 변경할 수 없습니다. 신중하게 정하세요. 보통 자신이 소유한 도메인을 역순으로 사용합니다. 도메인이 없다면 com.본인이름.앱이름 형태로 지정합니다.
앱 등록 절차
1단계: App Store Connect 접속
App Store Connect 에 로그인합니다.
2단계: "앱" 메뉴에서 새 앱 생성
- 좌측 메뉴에서 "앱"을 클릭합니다.
- 좌측 상단의 "+" 버튼 > "신규 앱"을 클릭합니다.
3단계: 앱 기본 정보 입력
다음 정보를 입력해야 합니다:
| 항목 | 설명 |
|---|---|
| 플랫폼 | iOS 선택 |
| 이름 | App Store에 표시될 앱 이름 (최대 30자). 다른 앱과 중복 불가 |
| 기본 언어 | 한국어 (Korean) 등 선택 |
| 번들 ID | 위에서 정한 번들 ID 선택 (먼저 Developer 포털에서 등록해야 목록에 나타남) |
| SKU | 내부 관리용 ID. 아무 영숫자 조합 가능 (예: justqr_v1) |
| 사용자 액세스 | "전체 액세스" 선택 |
[팁] 앱 이름은 App Store 검색에 큰 영향을 줍니다. 앱의 핵심 기능을 나타내는 이름을 짓되, 너무 일반적이거나 다른 앱과 겹치지 않도록 하세요.
4단계: 번들 ID를 Developer 포털에서 먼저 등록하기
App Store Connect에서 번들 ID를 선택하려면, 먼저 Apple Developer 포털에서 등록해야 합니다:
- Apple Developer - Identifiers 에 접속합니다.
- "+" 버튼을 클릭합니다.
- "App IDs"를 선택하고 Continue를 누릅니다.
- Type으로 "App"을 선택합니다.
- Description에 앱 설명을 입력합니다.
- Bundle ID에서 "Explicit"을 선택하고 번들 ID를 입력합니다.
- 필요한 Capabilities(Push Notifications 등)를 체크합니다.
- Continue > Register를 클릭합니다.
이제 App Store Connect에서 앱을 생성할 때 이 번들 ID가 드롭다운 목록에 나타납니다.
3. Xcode 서명 설정
왜 서명이 필요한가요?
iOS 앱은 코드 서명(Code Signing)이 되어야만 기기에서 실행될 수 있습니다. 이것은 "이 앱은 검증된 개발자가 만들었고, 중간에 누군가 코드를 변조하지 않았다"는 것을 보증하는 역할을 합니다. 서명이 없으면 앱 설치도, App Store 업로드도 불가능합니다.
필수 개념 정리
서명 설정을 하기 전에, 몇 가지 개념을 이해하면 훨씬 수월합니다:
- 인증서 (Certificate): "나는 Apple이 인정한 개발자입니다"를 증명하는 디지털 인증서입니다. 개발용(Development)과 배포용(Distribution) 두 종류가 있습니다.
- Provisioning Profile: 인증서, 앱 ID, 그리고 (개발용의 경우) 테스트 기기 목록을 하나로 묶은 파일입니다. "이 개발자가, 이 앱을, 이 기기에서 실행할 수 있다"는 허가증 같은 것입니다.
- Team: Developer Program에 가입한 개발자(또는 조직)를 의미합니다.
Xcode에서 자동 서명 설정하기 (추천)
Flutter 프로젝트의 iOS 부분은 Xcode에서 설정합니다. 자동 서명을 사용하면 Xcode가 인증서와 Provisioning Profile을 알아서 관리해줍니다.
1단계: Xcode에서 iOS 프로젝트 열기
터미널에서 프로젝트 루트 디렉터리로 이동한 후:
open ios/Runner.xcworkspace
[주의] Runner.xcodeproj가 아니라 반드시 Runner.xcworkspace를 열어야 합니다. .xcworkspace를 열어야 CocoaPods 등의 의존성이 제대로 로드됩니다.
2단계: 프로젝트 설정으로 이동
- Xcode 좌측 파일 탐색기에서 "Runner" 프로젝트를 클릭합니다 (가장 위의 파란색 아이콘).
- TARGETS 섹션에서 "Runner"를 선택합니다.
- "Signing & Capabilities" 탭을 클릭합니다.
3단계: Team 설정
- "Automatically manage signing" 체크박스가 체크되어 있는지 확인합니다.
- Team 드롭다운에서 자신의 Apple Developer 계정을 선택합니다.
- 목록에 없다면: Xcode 메뉴 > Settings (또는 Preferences) > Accounts에서 Apple ID를 추가하세요.
- Team을 선택하면 Xcode가 자동으로 Provisioning Profile과 인증서를 생성/다운로드합니다.
4단계: Bundle Identifier 확인
"General" 탭에서 Bundle Identifier가 App Store Connect에서 등록한 번들 ID와 정확히 일치하는지 확인합니다.
Flutter 프로젝트에서 번들 ID를 변경하려면 다음 파일을 수정합니다:
ios/Runner.xcodeproj/project.pbxproj
또는 Xcode의 General 탭에서 직접 수정할 수도 있지만, Flutter에서는 다음 경로의 설정도 함께 확인하세요:
# pubspec.yaml 에는 번들 ID 설정이 없습니다.
# iOS 번들 ID는 Xcode 또는 ios/Runner.xcodeproj/project.pbxproj 에서 관리됩니다.
5단계: 배포 서명 설정 확인
빌드 설정에서 Release 구성이 올바른지 확인합니다:
- "Build Settings" 탭을 클릭합니다.
- 검색창에 "signing"을 입력합니다.
- Code Signing Identity가 Release 구성에서 "Apple Distribution"으로 되어 있는지 확인합니다.
- 자동 서명을 사용하면 대부분 알아서 설정되므로 별도로 건드릴 필요가 없습니다.
[팁] "Automatically manage signing"을 체크해두면 Xcode가 대부분의 서명 문제를 자동으로 해결해줍니다. 초보자에게는 자동 서명을 강력히 추천합니다.
[주의] 서명 관련 오류가 나타나면 다음을 시도해보세요:
- Xcode > Settings > Accounts에서 Apple ID를 제거했다가 다시 추가
- Xcode를 완전히 종료했다가 다시 열기
ios/Pods폴더와ios/Podfile.lock을 삭제 후pod install다시 실행
4. flutter build ipa 릴리스 빌드
왜 릴리스 빌드가 필요한가요?
개발 중에는 Debug 모드로 앱을 실행합니다. Debug 모드에는 디버깅 도구, 느린 애니메이션 표시 등 개발용 기능이 포함되어 있어 앱이 느리고 용량도 큽니다. App Store에 올릴 때는 이런 것들을 모두 제거하고 최적화된 Release 빌드를 만들어야 합니다.
빌드 전 체크리스트
빌드 전에 다음 사항을 확인하세요:
1. 앱 버전과 빌드 번호 확인
pubspec.yaml 파일에서 버전을 확인합니다:
version: 1.0.0+1
1.0.0부분이 버전 이름 (Version)입니다. 사용자에게 보이는 버전입니다.+1부분이 빌드 번호 (Build Number)입니다. 같은 버전이라도 빌드 번호는 항상 이전보다 높아야 합니다.
[주의] App Store에 한 번 업로드한 빌드 번호는 재사용할 수 없습니다. 새 빌드를 올릴 때마다 빌드 번호를 1씩 올려야 합니다. 예: 1.0.0+1 -> 1.0.0+2 -> 1.0.1+3
2. 앱 아이콘 확인
앱 아이콘이 빠져있으면 심사에서 거절(리젝)됩니다. ios/Runner/Assets.xcassets/AppIcon.appiconset/ 폴더에 모든 크기의 아이콘이 있는지 확인하세요. flutter_launcher_icons 패키지를 사용하면 편리합니다.
3. iOS 최소 배포 버전 확인
ios/Podfile 파일 상단에서 최소 iOS 버전을 확인합니다:
platform :ios, '13.0'
너무 낮은 버전(예: 11.0)으로 설정하면 최신 라이브러리와 호환 문제가 생길 수 있고, 너무 높게 설정하면 지원하는 기기가 줄어듭니다. 현재 시점에서 13.0 이상을 추천합니다.
빌드 실행
터미널에서 다음 명령어를 실행합니다:
flutter build ipa --release
이 명령어가 하는 일:
- Flutter 코드를 네이티브 iOS 코드로 컴파일합니다.
- Release 모드로 최적화합니다 (Tree shaking, AOT 컴파일 등).
.ipa파일을 생성합니다 (이 파일이 App Store에 업로드할 파일입니다).
빌드가 성공하면 다음과 같은 메시지가 나타납니다:
Built IPA to build/ios/ipa/앱이름.ipa
특정 export 방식 지정하기
기본적으로 flutter build ipa는 App Store 배포용으로 빌드합니다. 만약 export 옵션을 세밀하게 제어하고 싶다면 export options plist 파일을 사용할 수 있습니다:
flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
하지만 처음이라면 기본 명령어만으로 충분합니다.
빌드 오류가 발생할 때
자주 발생하는 오류와 해결법:
오류: "No signing certificate"
# Xcode에서 서명 설정을 다시 확인하세요.
# 또는 키체인 접근 앱에서 만료된 인증서를 삭제 후 Xcode에서 다시 생성
오류: "Module not found" (CocoaPods 관련)
cd ios
pod deintegrate
pod install --repo-update
cd ..
flutter clean
flutter build ipa --release
오류: "Minimum deployment target" 관련
# ios/Podfile에서 최소 iOS 버전을 올려주세요
# platform :ios, '13.0' 또는 그 이상
5. 빌드 업로드
왜 업로드가 필요한가요?
빌드한 .ipa 파일을 Apple 서버에 올려야 App Store Connect에서 이 빌드를 심사에 제출할 수 있습니다. 업로드 방법은 크게 두 가지가 있습니다.
방법 1: Xcode를 통한 업로드 (Distribute App)
이 방법은 Xcode가 설치되어 있다면 가장 직관적입니다.
절차
-
Xcode에서
ios/Runner.xcworkspace를 엽니다. -
상단 메뉴에서 Product > Archive를 선택합니다.
- 이 메뉴가 비활성화되어 있다면, 빌드 대상을 "Any iOS Device"로 변경하세요 (시뮬레이터가 아닌 실제 기기).
-
Archive가 완료되면 Organizer 창이 자동으로 열립니다.
- 열리지 않으면: Window > Organizer에서 수동으로 열 수 있습니다.
-
방금 생성한 Archive를 선택하고 "Distribute App" 버튼을 클릭합니다.
-
배포 방법으로 "App Store Connect"를 선택합니다.
-
"Upload"를 선택합니다 (Export가 아님).
-
옵션을 확인합니다:
- "Include bitcode"는 최신 Xcode에서는 더 이상 표시되지 않을 수 있습니다.
- "Upload your app's symbols"은 체크해두는 것을 추천합니다 (크래시 리포트 분석에 필요).
-
서명 옵션에서 "Automatically manage signing"을 선택합니다.
-
"Upload"를 클릭하고 완료될 때까지 기다립니다.
업로드가 성공하면 "Upload Successful" 메시지가 나타납니다.
[참고] flutter build ipa로 이미 .ipa 파일을 만들었다면 Xcode의 Archive 과정을 다시 할 필요 없이, Transporter를 사용하는 것이 더 간편할 수 있습니다.
방법 2: Transporter 앱을 통한 업로드 (추천)
Transporter는 Apple이 제공하는 무료 앱으로, .ipa 파일을 드래그 앤 드롭으로 간편하게 업로드할 수 있습니다.
절차
-
Mac App Store에서 "Transporter"를 검색하여 설치합니다.
-
Transporter를 실행하고 Apple ID로 로그인합니다.
-
flutter build ipa로 생성된.ipa파일을 찾습니다:
# 빌드 결과물 위치 확인
ls build/ios/ipa/
-
.ipa파일을 Transporter 창에 드래그 앤 드롭합니다. -
Transporter가 파일을 검증(Verify)합니다. 문제가 없으면 "Deliver" 버튼을 클릭합니다.
-
업로드가 완료될 때까지 기다립니다.
[팁] Transporter는 업로드 진행률을 보여주고, 오류가 있으면 구체적인 에러 메시지를 알려줍니다. Xcode보다 에러 메시지가 명확한 편이라 초보자에게 추천합니다.
방법 3: 커맨드라인으로 업로드 (xcrun altool / xcrun notarytool)
터미널에서 직접 업로드하는 방법도 있습니다:
xcrun altool --upload-app --type ios \
--file build/ios/ipa/YourApp.ipa \
--apiKey YOUR_API_KEY \
--apiIssuer YOUR_ISSUER_ID
이 방법은 CI/CD 파이프라인에서 주로 사용하며, 처음 배포하는 분에게는 추천하지 않습니다.
업로드 후 처리 과정
업로드가 완료되면 Apple 서버에서 자동 검증 (Processing)이 진행됩니다. 이 과정은 보통 5분~30분 정도 걸립니다. 처리가 완료되면 등록된 이메일로 결과가 옵니다.
- 성공: App Store Connect의 "TestFlight" 탭에서 빌드가 나타납니다.
- 실패: 이메일로 구체적인 오류 사유가 전달됩니다.
[주의] 업로드 직후에 App Store Connect에서 빌드가 안 보이는 것은 정상입니다. Processing이 완료될 때까지 기다려주세요.
6. App Store Connect에서 앱 정보 작성
왜 앱 정보가 중요한가요?
App Store에서 사용자가 보는 모든 정보(앱 이름, 설명, 스크린샷 등)는 여기서 입력합니다. 이 정보는 단순히 보여주기 위한 것이 아니라 심사의 대상이기도 합니다. 부정확하거나 부적절한 정보는 심사 거절의 원인이 됩니다.
앱 정보 작성 항목별 상세 안내
App Store Connect에서 앱을 선택하면 여러 섹션이 있습니다. 하나씩 살펴보겠습니다.
1) 앱 이름과 부제
- 앱 이름: 최대 30자. App Store에서 검색될 때 사용됩니다.
- 부제 (Subtitle): 최대 30자. 앱 이름 아래에 작게 표시됩니다. 핵심 기능을 한 줄로 요약하세요.
2) 설명 (Description)
- 최대 4,000자.
- 앱이 무엇을 하는지, 왜 유용한지 명확하게 작성합니다.
- 첫 세 줄이 가장 중요합니다 (미리보기에서 보이는 부분).
- 키워드를 자연스럽게 포함시키면 검색 노출에 도움됩니다.
3) 키워드 (Keywords)
- 최대 100자 (쉼표로 구분).
- 사용자가 검색할 만한 단어를 입력합니다.
- 앱 이름에 이미 포함된 단어는 중복하여 넣지 않아도 됩니다.
4) 스크린샷
스크린샷은 심사에서 매우 중요합니다. 필수 항목이며, 규격이 정해져 있습니다.
| 기기 | 필요 여부 | 해상도 |
|---|---|---|
| iPhone 6.9인치 (iPhone 16 Pro Max 등) | 필수 | 1320 x 2868 px |
| iPhone 6.7인치 (iPhone 15 Pro Max 등) | 필수 | 1290 x 2796 px |
| iPhone 6.5인치 (iPhone 11 Pro Max 등) | 선택 | 1242 x 2688 px |
| iPhone 5.5인치 (iPhone 8 Plus 등) | 선택 | 1242 x 2208 px |
| iPad Pro 13인치 | iPad 앱인 경우 필수 | 2048 x 2732 px |
[참고] 스크린샷 규격은 Apple의 정책에 따라 변경될 수 있으므로, 항상 App Store Connect의 안내를 확인하세요. 최근에는 6.9인치와 6.7인치 두 가지만 필수인 경우가 많습니다.
스크린샷 준비 팁:
- 최소 3장, 최대 10장까지 등록 가능합니다.
- 시뮬레이터에서 스크린샷을 찍을 수 있습니다:
Cmd + S(Xcode 시뮬레이터에서). - 스크린샷에 설명 텍스트를 오버레이하면 전환율이 높아집니다. Figma, Canva 등의 도구를 활용하세요.
- 실제 앱 화면을 반영해야 합니다. 앱과 관련 없는 이미지를 사용하면 리젝됩니다.
5) 앱 미리보기 동영상 (선택사항)
15~30초 길이의 앱 사용 영상을 올릴 수 있습니다. 필수는 아니지만, 앱의 핵심 기능을 효과적으로 보여줄 수 있습니다.
6) 카테고리
앱의 주요 카테고리와 보조 카테고리를 선택합니다:
- 주요 카테고리: 앱의 핵심 기능에 맞는 것을 선택 (예: Utilities, Productivity 등)
- 보조 카테고리: 선택사항이지만, 추가 노출을 위해 설정하는 것을 추천합니다.
7) 개인정보처리방침 (Privacy Policy URL)
필수 항목입니다. Apple은 모든 앱에 개인정보처리방침 URL을 요구합니다.
- 웹페이지 형태로 만들어서 URL을 입력해야 합니다.
- 개인 정보를 수집하지 않는 앱이라도 "본 앱은 개인정보를 수집하지 않습니다"라는 내용의 페이지가 필요합니다.
- GitHub Pages, Notion, 개인 블로그 등에 무료로 호스팅할 수 있습니다.
[주의] 개인정보처리방침이 없으면 심사 제출 자체가 불가능합니다. 반드시 미리 준비해두세요.
8) 연령 등급 (Age Rating)
Apple의 설문에 답하면 자동으로 연령 등급이 산정됩니다. 질문 예시:
- 폭력적인 콘텐츠가 있나요?
- 성인 콘텐츠가 있나요?
- 도박 요소가 있나요?
- 사용자 생성 콘텐츠가 있나요?
대부분의 유틸리티 앱은 "4+" 등급을 받습니다. 솔직하게 답변하세요. 거짓으로 답변하면 심사에서 거절될 수 있습니다.
9) 가격 및 사용 가능 여부
- 가격: 무료 또는 유료를 선택합니다. 유료인 경우 가격대를 선택합니다.
- 사용 가능 여부: 앱을 출시할 국가/지역을 선택합니다. 기본적으로 모든 국가가 선택되어 있습니다.
10) 앱 심사 정보
- 연락처 정보: 심사 과정에서 Apple이 연락할 수 있는 이름, 이메일, 전화번호를 입력합니다.
- 로그인 정보: 앱에 로그인이 필요한 경우, 심사팀이 사용할 수 있는 테스트 계정 정보를 제공해야 합니다.
- 메모: 심사팀에게 전달하고 싶은 메모를 남길 수 있습니다. 예를 들어, 특정 기능의 사용법 등.
7. TestFlight 베타 테스트
왜 TestFlight를 사용하나요?
TestFlight는 Apple이 제공하는 공식 베타 테스트 도구입니다. 앱을 App Store에 정식 출시하기 전에 소수의 테스터에게 먼저 배포하여 버그를 찾고 피드백을 받을 수 있습니다.
TestFlight 테스트는 필수는 아니지만 강력히 추천합니다. 이유는 다음과 같습니다:
- 심사 전에 실제 기기에서 문제가 없는지 확인할 수 있습니다.
- 다양한 iPhone/iPad 모델에서 테스트할 수 있습니다.
- 심사에서 리젝되면 수정 후 재제출하는 데 며칠이 걸리므로, 미리 테스트하는 것이 시간을 절약합니다.
내부 테스트 vs 외부 테스트
| 구분 | 내부 테스트 | 외부 테스트 |
|---|---|---|
| 대상 | 팀 멤버 (최대 100명) | 일반 사용자 (최대 10,000명) |
| Apple 심사 | 불필요 | 간단한 베타 심사 필요 |
| 초대 방법 | 이메일 | 이메일 또는 공개 링크 |
| 소요 시간 | 즉시 사용 가능 | 베타 심사 1~2일 |
개인 개발자라면 내부 테스트로 충분합니다.
TestFlight 사용 절차
1단계: 빌드 업로드
위의 5단계에서 이미 빌드를 업로드했다면, App Store Connect > TestFlight 탭에서 해당 빌드를 확인할 수 있습니다.
2단계: 수출 규정 관련 질문 답변
빌드가 처리되면 "수출 규정 관련 문서가 누락됨"이라는 경고가 표시됩니다. 이것은 미국 수출 규정과 관련된 질문입니다.
- 대부분의 앱은 "아니오, 표준 암호화만 사용합니다"에 해당합니다.
- HTTPS 통신만 사용하는 경우 "예, 하지만 면제 대상"에 해당합니다.
이 질문에 답해야 TestFlight 배포가 활성화됩니다.
[팁] 매번 이 질문에 답하는 것이 번거롭다면 ios/Runner/Info.plist에 다음을 추가하면 자동으로 처리됩니다:
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
이 설정은 "앱이 면제 대상이 아닌 암호화를 사용하지 않는다"는 의미입니다. HTTPS만 사용하는 일반적인 앱이라면 false로 설정해도 됩니다.
3단계: 테스터 추가 (내부 테스트)
- TestFlight 탭에서 "내부 테스트" 섹션으로 이동합니다.
- "+" 버튼으로 새 그룹을 만듭니다.
- 테스터의 Apple ID 이메일을 추가합니다.
- 테스터에게 초대 이메일이 발송됩니다.
4단계: 테스터가 앱 설치
- 테스터는 App Store에서 "TestFlight" 앱을 설치합니다.
- 초대 이메일의 링크를 탭하면 TestFlight 앱에서 해당 앱을 설치할 수 있습니다.
5단계: 피드백 확인
TestFlight에서 테스터는 스크린샷과 함께 피드백을 보낼 수 있습니다. App Store Connect에서 이 피드백을 확인할 수 있습니다.
8. 심사 제출 및 주의사항
심사 제출 절차
모든 정보를 입력하고 빌드가 준비되었다면 심사를 제출합니다.
1단계: 빌드 선택
App Store Connect > 앱 > 해당 버전 페이지에서:
- "빌드" 섹션 옆의 "+" 버튼을 클릭합니다.
- 업로드한 빌드 중 하나를 선택합니다.
2단계: 모든 필수 정보 확인
페이지 상단에 "이 버전을 제출하기 전에 다음 항목을 완료해야 합니다"라는 메시지가 있다면, 해당 항목을 모두 완료하세요.
3단계: 심사 제출
모든 항목이 완료되면 "심사를 위해 제출" 버튼이 활성화됩니다. 버튼을 클릭하면 심사가 시작됩니다.
심사 소요 시간
- 보통 24~48시간 이내에 결과가 나옵니다.
- 빠르면 몇 시간 만에 결과가 나오기도 합니다.
- 연말 연시(특히 12월 말)에는 심사가 느려질 수 있습니다.
심사 상태 의미
| 상태 | 의미 |
|---|---|
| Waiting for Review | 심사 대기 중 |
| In Review | 심사 진행 중 |
| Pending Developer Release | 심사 통과, 개발자가 출시 버튼을 눌러야 함 |
| Ready for Distribution | 심사 통과, 출시 중 |
| Rejected | 심사 거절 |
주요 리젝 사유와 대처법
Apple의 심사는 생각보다 꼼꼼합니다. 자주 발생하는 리젝 사유를 미리 알고 대비하세요.
1) 버그 또는 크래시
사유: 앱이 심사 중에 크래시가 발생하거나 주요 기능이 작동하지 않는 경우.
대처: 다양한 기기와 iOS 버전에서 충분히 테스트하세요. TestFlight를 활용하면 좋습니다.
2) 불완전한 앱 정보
사유: 스크린샷이 실제 앱과 다르거나, 설명이 부정확하거나, 개인정보처리방침 URL이 작동하지 않는 경우.
대처: 스크린샷은 최신 버전의 앱 화면을 사용하고, 개인정보처리방침 URL이 정상적으로 접근 가능한지 확인하세요.
3) 로그인 기능 관련
사유: 로그인이 필요한 앱인데 심사용 테스트 계정을 제공하지 않은 경우.
대처: App Store Connect의 "앱 심사 정보" 섹션에 테스트 계정 정보(ID/비밀번호)를 반드시 입력하세요.
4) 최소 기능 요건 (Guideline 4.2)
사유: 앱이 너무 단순하거나 웹사이트를 단순히 감싼 것에 불과한 경우.
대처: 앱이 네이티브 기능을 충분히 활용하고, 웹 페이지를 그대로 보여주는 것 이상의 가치를 제공해야 합니다.
5) 개인정보 관련 (Guideline 5.1)
사유: 앱이 수집하는 개인정보에 대한 설명이 부족하거나, App Tracking Transparency 팝업이 없는 경우.
대처: 개인정보를 수집한다면 이유를 명확히 설명하고, 추적 기능을 사용한다면 ATT 프레임워크를 구현하세요.
6) 결제 관련 (Guideline 3.1)
사유: 앱 내 결제를 Apple의 인앱 결제 시스템을 우회하여 처리하는 경우.
대처: 디지털 콘텐츠의 구매는 반드시 Apple의 인앱 결제(StoreKit)를 사용해야 합니다.
리젝되었을 때 해야 할 일
- 리젝 사유를 꼼꼼히 읽습니다: App Store Connect의 "Resolution Center"에서 구체적인 사유를 확인할 수 있습니다.
- 필요한 수정을 합니다: 사유에 맞게 앱이나 메타데이터를 수정합니다.
- 리젝 사유에 대해 질문하거나 이의를 제기할 수 있습니다: Resolution Center에서 Apple 심사팀에게 메시지를 보낼 수 있습니다.
- 수정 후 다시 제출합니다: 새 빌드를 업로드하거나, 메타데이터만 수정한 경우 기존 빌드로 재제출할 수 있습니다.
[팁] 리젝은 흔한 일입니다. 낙담하지 말고 사유를 정확히 파악하여 수정하면 대부분 다음 심사에서 통과합니다.
9. 자주 하는 실수 / FAQ
자주 하는 실수
실수 1: 빌드 번호를 올리지 않음
증상: "Redundant Binary Upload" 또는 "Build number already used" 오류
해결: pubspec.yaml에서 version: 1.0.0+1의 + 뒤 숫자를 올려주세요. 한 번 사용한 빌드 번호는 재사용할 수 없습니다.
실수 2: 앱 아이콘 누락
증상: 업로드 후 "Missing App Icon" 경고 이메일 수신
해결: 1024x1024 크기를 포함한 모든 필수 크기의 아이콘을 준비하세요. flutter_launcher_icons 패키지를 사용하면 자동으로 모든 크기를 생성해줍니다.
# pubspec.yaml에 추가
dev_dependencies:
flutter_launcher_icons: ^0.14.0
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/icon/app_icon.png"
dart run flutter_launcher_icons
실수 3: 개인정보처리방침 URL 누락 또는 접근 불가
증상: 심사 제출 버튼이 비활성화되거나 리젝됨
해결: 유효한 URL에 개인정보처리방침 페이지를 호스팅하세요. GitHub Pages를 이용하면 무료로 호스팅할 수 있습니다.
실수 4: 스크린샷 규격 불일치
증상: "Invalid screenshot" 오류
해결: 위의 스크린샷 규격 표를 참고하여 정확한 해상도의 스크린샷을 준비하세요. 시뮬레이터에서 해당 기기 모델을 선택하여 스크린샷을 찍으면 정확한 크기로 생성됩니다.
실수 5: Release 빌드 테스트 없이 제출
증상: Debug 모드에서는 잘 작동했지만 Release 빌드에서 크래시 발생
해결: Release 빌드는 Debug 빌드와 다르게 동작할 수 있습니다 (Tree shaking, AOT 컴파일 등). 반드시 Release 빌드를 실제 기기에서 테스트하거나 TestFlight로 확인하세요.
실수 6: Info.plist 필수 권한 설명 누락
증상: 카메라, 사진 라이브러리 등의 권한을 사용하는데 사용 이유 설명이 없어서 리젝
해결: ios/Runner/Info.plist에 권한별 사용 이유를 명시해야 합니다:
<!-- 카메라 사용 시 -->
<key>NSCameraUsageDescription</key>
<string>QR 코드를 스캔하기 위해 카메라 접근 권한이 필요합니다.</string>
<!-- 사진 라이브러리 접근 시 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>QR 코드 이미지를 저장하기 위해 사진 라이브러리 접근 권한이 필요합니다.</string>
<!-- 사진 라이브러리 추가 전용 접근 시 -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>생성된 QR 코드를 사진 앨범에 저장하기 위해 권한이 필요합니다.</string>
[주의] 권한 설명은 반드시 사용자가 이해할 수 있는 구체적인 이유를 적어야 합니다. "이 앱에 필요합니다" 같은 모호한 설명은 리젝 사유가 됩니다.
FAQ
Q: Developer Program 비용 $99는 매년 내야 하나요?
A: 네, 매년 갱신해야 합니다. 갱신하지 않으면 앱이 App Store에서 내려가고, 새로운 앱을 업로드할 수 없게 됩니다. 이미 다운로드한 사용자는 계속 사용할 수 있지만 업데이트는 받을 수 없습니다.
Q: Mac이 없으면 iOS 앱을 출시할 수 없나요?
A: 네, 현재로서는 Mac이 반드시 필요합니다. Xcode는 macOS에서만 실행되며, iOS 앱 빌드와 서명에 Xcode가 필요합니다. 임시 방편으로 클라우드 Mac 서비스(예: MacStadium, GitHub Actions의 macOS runner)를 사용하는 방법이 있지만, 처음이라면 실제 Mac을 사용하는 것을 추천합니다.
Q: 앱 심사에 얼마나 걸리나요?
A: 보통 24~48시간이지만, 빠르면 수 시간, 느리면 일주일 이상 걸릴 수도 있습니다. 특히 연말 연시 시즌에는 심사가 느려집니다.
Q: 리젝되면 처음부터 다시 해야 하나요?
A: 아닙니다. 리젝 사유를 수정한 후 동일한 앱 버전에서 다시 심사를 제출할 수 있습니다. 코드 수정이 필요한 경우에만 새 빌드를 업로드하면 됩니다.
Q: 무료 앱인데도 $99를 내야 하나요?
A: 네, 무료 앱이든 유료 앱이든 Developer Program 가입비는 동일합니다. 이 비용은 앱의 판매 여부와 관계없이 개발자 자격을 유지하기 위한 연회비입니다.
Q: 앱을 업데이트할 때도 심사를 받아야 하나요?
A: 네, 모든 업데이트는 심사를 거쳐야 합니다. 하지만 첫 심사보다는 보통 빠르게 처리됩니다.
Q: TestFlight 테스트는 반드시 해야 하나요?
A: 필수는 아닙니다. 하지만 심사 전에 실제 기기에서 Release 빌드를 테스트해보는 것은 매우 중요합니다. TestFlight가 이를 위한 가장 쉬운 방법입니다.
Q: 시뮬레이터에서 정상 작동하면 실제 기기에서도 괜찮은 건가요?
A: 아닙니다. 시뮬레이터와 실제 기기는 차이가 있습니다. 카메라, GPS, 센서 등은 시뮬레이터에서 테스트할 수 없고, 성능 차이도 있을 수 있습니다. 가능하면 반드시 실제 기기에서도 테스트하세요.
Q: 앱이 승인된 후 바로 App Store에 공개되나요?
A: 앱 제출 시 "자동 출시" 또는 "수동 출시"를 선택할 수 있습니다. 자동 출시를 선택하면 심사 통과 즉시 App Store에 공개됩니다. 수동 출시를 선택하면 심사 통과 후 개발자가 직접 "출시" 버튼을 눌러야 공개됩니다. 특정 날짜에 맞추어 출시하고 싶다면 수동 출시를 선택하세요.
전체 흐름 요약
아래는 Flutter 앱을 App Store에 출시하는 전체 과정을 한눈에 정리한 것입니다:
1. Apple Developer Program 가입 ($99/년)
|
2. Apple Developer 포털에서 App ID (번들 ID) 등록
|
3. App Store Connect에서 새 앱 생성
|
4. Xcode에서 서명 설정 (Team, Bundle ID 확인)
|
5. flutter build ipa --release 로 빌드
|
6. Transporter 또는 Xcode로 .ipa 파일 업로드
|
7. App Store Connect에서 앱 정보 작성
(스크린샷, 설명, 개인정보처리방침 등)
|
8. (선택) TestFlight로 베타 테스트
|
9. 심사 제출
|
10. 심사 통과 -> App Store 출시 완료!
처음에는 복잡해 보이지만, 한 번 해보면 다음부터는 훨씬 수월합니다. 특히 업데이트 시에는 4~6번과 9번만 반복하면 되므로 시간이 많이 단축됩니다.
이 가이드가 여러분의 첫 앱 출시에 도움이 되길 바랍니다. 성공적인 출시를 응원합니다!