Flutter 튜토리얼 63편: Android/iOS 스토어 배포
Flutter 튜토리얼 63편: Android/iOS 스토어 배포
이번 튜토리얼에서는 Flutter 앱을 Google Play Store와 Apple App Store에 배포하는 전체 과정을 학습합니다. 지난 튜토리얼에서 준비한 코드 난독화와 빌드 플레이버를 기반으로 실제 스토어 배포를 진행해 봅니다.
학습 목표
- Google Play Store에 Android 앱 배포하기
- Apple App Store에 iOS 앱 배포하기
- 앱 서명 및 인증서 관리 이해하기
- 스토어 등록 정보 작성하기
1. 스토어 배포 개요
1.1 왜 스토어 배포가 필요한가?
이유: 앱 스토어는 사용자가 앱을 안전하게 다운로드할 수 있는 공식 채널입니다. 직접 APK나 IPA를 배포하는 것보다 신뢰성이 높고, 자동 업데이트 및 결제 시스템을 활용할 수 있습니다.
1.2 배포 프로세스 흐름
1.3 플랫폼별 요구사항
| 항목 | Android | iOS |
|---|---|---|
| 개발자 계정 비용 | $25 (1회) | $99/년 |
| 빌드 형식 | App Bundle (.aab) | App Store Archive (.ipa) |
| 서명 방식 | Keystore | 인증서 + 프로비저닝 |
| 심사 기간 | 수 시간~수 일 | 1~3일 |
| 테스트 배포 | 내부/비공개/공개 테스트 | TestFlight1 |
2. Android - Google Play Store 배포
2.1 왜 App Bundle을 사용하는가?
이유: App Bundle2은 Google Play에서 기기별로 최적화된 APK를 자동 생성합니다. 앱 크기가 줄어들고 사용자에게 더 나은 다운로드 경험을 제공합니다.
2.2 앱 서명 키 생성
무엇을: 앱에 디지털 서명을 하기 위한 키를 생성합니다.
# Keystore 생성keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \ -keysize 2048 -validity 10000 -alias upload주의사항:
- Keystore 파일과 비밀번호는 절대 분실하면 안 됩니다
- 분실 시 앱 업데이트가 불가능합니다
- 안전한 장소에 백업을 유지하세요
2.3 앱 서명 설정
android/key.properties 파일을 생성합니다.
storePassword=<keystore 비밀번호>keyPassword=<key 비밀번호>keyAlias=uploadstoreFile=<keystore 파일 경로>android/app/build.gradle.kts에서 서명 설정을 추가합니다.
import java.util.Propertiesimport java.io.FileInputStream
val keystoreProperties = Properties()val keystorePropertiesFile = rootProject.file("key.properties")if (keystorePropertiesFile.exists()) { keystoreProperties.load(FileInputStream(keystorePropertiesFile))}
android { // ...
signingConfigs { create("release") { keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["keyPassword"] as String storeFile = file(keystoreProperties["storeFile"] as String) storePassword = keystoreProperties["storePassword"] as String } }
buildTypes { release { signingConfig = signingConfigs.getByName("release") isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } }}2.4 App Bundle 빌드
# App Bundle 생성 (권장)flutter build appbundle --release
# 난독화와 함께 빌드flutter build appbundle --obfuscate --split-debug-info=./symbols/android
# 빌드 결과 위치# build/app/outputs/bundle/release/app-release.aab2.5 Google Play Console 등록
어떻게: Google Play Console에서 앱을 등록하고 스토어 정보를 작성합니다.
스토어 등록정보 체크리스트:
| 항목 | 설명 | 요구사항 |
|---|---|---|
| 앱 이름 | 스토어에 표시될 이름 | 최대 30자 |
| 간략한 설명 | 앱 소개 한 줄 | 최대 80자 |
| 전체 설명 | 상세 앱 설명 | 최대 4,000자 |
| 스크린샷 | 앱 화면 캡처 | 휴대전화 2장 이상 |
| 고해상도 아이콘 | 스토어 아이콘 | 512x512 PNG |
| 그래픽 이미지 | 스토어 배너 | 1024x500 PNG |
2.6 테스트 트랙 활용
3. iOS - App Store 배포
3.1 왜 Apple Developer Program이 필요한가?
이유: iOS 앱을 App Store에 배포하려면 Apple Developer Program3 멤버십이 필수입니다. 이를 통해 코드 서명 인증서와 프로비저닝 프로파일을 발급받을 수 있습니다.
3.2 Bundle ID 등록
무엇을: App Store Connect에서 앱을 식별하는 고유 ID를 등록합니다.
- Apple Developer 계정의 Identifiers 페이지로 이동
- + 버튼을 클릭하여 새 Bundle ID 생성
- 앱 이름과 Explicit App ID 입력
- 필요한 Capabilities 선택 (Push Notifications, Sign in with Apple 등)
- Register 클릭
3.3 Xcode 프로젝트 설정
# Xcode workspace 열기open ios/Runner.xcworkspace확인해야 할 설정들:
| 설정 | 위치 | 설명 |
|---|---|---|
| Display Name | General > Identity | 앱 표시 이름 |
| Bundle Identifier | General > Identity | 등록한 Bundle ID |
| Version | General > Identity | 사용자 버전 (예: 1.0.0) |
| Build | General > Identity | 빌드 번호 (정수) |
| Team | Signing & Capabilities | 개발자 계정 팀 |
| iOS Deployment Target | Build Settings | 최소 지원 iOS 버전 |
3.4 앱 아이콘 및 런치 이미지
어떻게: Xcode에서 Assets.xcassets의 아이콘과 런치 이미지를 설정합니다.
# Runner 폴더의 Assets.xcassets 열기ios/Runner/Assets.xcassets/├── AppIcon.appiconset/ # 앱 아이콘├── LaunchImage.imageset/ # 런치 이미지└── Contents.jsoniOS 앱 아이콘 요구사항:
| 용도 | 크기 (pt) | @1x | @2x | @3x |
|---|---|---|---|---|
| iPhone App | 60 | - | 120x120 | 180x180 |
| iPad App | 76 | 76x76 | 152x152 | - |
| iPad Pro App | 83.5 | - | 167x167 | - |
| App Store | 1024 | 1024x1024 | - | - |
3.5 Archive 생성 및 업로드
버전 정보 업데이트 (pubspec.yaml):
version: 1.0.0+1# 형식: <version>+<build-number># version: CFBundleShortVersionString (1.0.0)# build-number: CFBundleVersion (1)IPA 빌드:
# iOS Archive 및 IPA 생성flutter build ipa --release
# 난독화와 함께 빌드flutter build ipa --obfuscate --split-debug-info=./symbols/ios
# 결과 파일 위치# build/ios/ipa/*.ipa# build/ios/archive/Runner.xcarchive3.6 App Store Connect 업로드
방법 1: Transporter 앱 사용
# Mac App Store에서 Transporter 앱 설치 후# build/ios/ipa/*.ipa 파일을 드래그 앤 드롭방법 2: 명령줄 업로드
xcrun altool --upload-app --type ios \ -f build/ios/ipa/*.ipa \ --apiKey your_api_key \ --apiIssuer your_issuer_id방법 3: Xcode에서 업로드
# Archive 파일 열기open build/ios/archive/Runner.xcarchive
# Xcode에서:# 1. Validate App 버튼 클릭# 2. 문제 없으면 Distribute App 클릭# 3. App Store Connect 선택3.7 App Store Connect 설정
필수 입력 정보:
| 항목 | 설명 |
|---|---|
| 앱 이름 | App Store에 표시될 이름 |
| 부제 | 앱 이름 아래 표시되는 짧은 설명 |
| 프로모션 텍스트 | 언제든 변경 가능한 홍보 문구 |
| 설명 | 앱 상세 설명 |
| 키워드 | 검색용 키워드 (쉼표로 구분) |
| 지원 URL | 고객 지원 웹사이트 |
| 마케팅 URL | 앱 홍보 웹사이트 (선택) |
3.8 TestFlight 배포
왜 TestFlight를 사용하는가?
- App Store 출시 전 베타 테스트 가능
- 내부 테스터: 팀원 최대 100명
- 외부 테스터: 최대 10,000명
- 간편한 피드백 수집
4. 버전 관리 전략
4.1 시맨틱 버저닝
무엇을: 버전 번호를 의미있게 관리하는 방법입니다.
MAJOR.MINOR.PATCH+BUILD │ │ │ │ │ │ │ └── 빌드 번호 (내부 추적용) │ │ └── 버그 수정 │ └── 새 기능 추가 (하위 호환) └── 주요 변경 (하위 호환 X)예시:
1.0.0+1→ 첫 출시1.0.1+2→ 버그 수정1.1.0+3→ 새 기능 추가2.0.0+4→ 대규모 변경
4.2 빌드 번호 자동화
# 빌드 번호를 날짜 기반으로 생성flutter build apk --build-number=$(date +%Y%m%d%H)
# 또는 pubspec.yaml의 버전 사용flutter build apk --build-name=1.2.0 --build-number=425. 배포 체크리스트
5.1 출시 전 체크리스트
5.2 플랫폼별 심사 가이드라인
| 항목 | Google Play | App Store |
|---|---|---|
| 가이드라인 | 개발자 프로그램 정책 | App Review Guidelines |
| 주요 거부 사유 | 권한 남용, 허위 광고 | 버그, 불완전한 앱, 가이드라인 위반 |
| 심사 기간 | 수 시간~수 일 | 평균 24시간 (최대 48시간) |
| 이의 제기 | 가능 | 가능 |
5.3 앱 업데이트 전략
6. Codemagic CLI 도구 활용
6.1 왜 CLI 도구를 사용하는가?
이유: CI/CD 파이프라인에서 자동화된 빌드와 배포가 가능합니다. 수동 작업을 줄이고 일관된 빌드 환경을 유지할 수 있습니다.
6.2 iOS 배포 자동화
# Codemagic CLI 도구 설치pip3 install codemagic-cli-tools
# App Store Connect API 키 설정export APP_STORE_CONNECT_ISSUER_ID=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeexport APP_STORE_CONNECT_KEY_IDENTIFIER=ABC1234567export APP_STORE_CONNECT_PRIVATE_KEY=`cat /path/to/AuthKey.p8`
# 임시 키체인 설정keychain initialize
# 코드 서명 파일 가져오기app-store-connect fetch-signing-files $(xcode-project detect-bundle-id) \ --platform IOS \ --type IOS_APP_STORE \ --certificate-key=@file:/path/to/cert_key \ --create
# 인증서 추가keychain add-certificates
# Xcode 프로젝트 설정 업데이트xcode-project use-profiles
# Flutter 빌드flutter build ipa --release \ --export-options-plist=$HOME/export_options.plist
# App Store Connect 업로드app-store-connect publish \ --path $(find $(pwd) -name "*.ipa")
# 키체인 복원 (중요!)keychain use-login7. 문제 해결
7.1 Android 일반적인 문제
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| 서명 오류 | Keystore 불일치 | key.properties 확인 |
| 업로드 실패 | 버전 코드 중복 | 빌드 번호 증가 |
| 앱 크기 초과 | 150MB 이상 | Asset 최적화, Play Feature Delivery 사용 |
| 64비트 오류 | arm64-v8a 누락 | flutter build appbundle로 해결 |
7.2 iOS 일반적인 문제
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| 프로비저닝 오류 | 프로파일 만료 | Xcode에서 새로 발급 |
| 아이콘 누락 | 필수 크기 미포함 | 모든 크기 아이콘 추가 |
| 빌드 번호 오류 | 이전과 같은 번호 | 빌드 번호 증가 |
| 심사 거부 | 가이드라인 위반 | 거부 사유 확인 후 수정 |
7.3 심사 거부 대응
정리
이번 튜토리얼에서 배운 핵심 내용입니다:
| 항목 | Android | iOS |
|---|---|---|
| 빌드 명령 | flutter build appbundle | flutter build ipa |
| 서명 방식 | Keystore + key.properties | 인증서 + 프로비저닝 |
| 배포 콘솔 | Google Play Console | App Store Connect |
| 테스트 배포 | 내부/비공개/공개 트랙 | TestFlight |
| 개발자 계정 | $25 (1회) | $99/년 |
배포 핵심 포인트:
- 서명 키/인증서는 절대 분실하지 않도록 백업
- 버전 번호는 항상 증가해야 함
- 테스트 트랙을 활용한 단계적 출시 권장
- 스토어 가이드라인을 미리 숙지
다음 튜토리얼에서는 Desktop과 Web 플랫폼에 앱을 배포하는 방법을 학습하겠습니다.
참고 자료
Footnotes
-
TestFlight: Apple에서 제공하는 베타 테스트 플랫폼으로, 내부 테스터(최대 100명)와 외부 테스터(최대 10,000명)에게 앱을 배포할 수 있습니다. ↩
-
App Bundle: Google에서 권장하는 앱 배포 형식으로, .aab 확장자를 가지며 Google Play에서 기기 구성에 맞는 최적화된 APK를 동적으로 생성합니다. ↩
-
Apple Developer Program: Apple의 공식 개발자 프로그램으로, 연간 $99의 비용이 발생하며 App Store 배포, TestFlight 베타 테스트, 고급 앱 기능 사용이 가능합니다. ↩
공유
이 글이 도움이 되었다면 다른 사람과 공유해주세요!