식별자와 버전
번들 ID · 애플리케이션 ID · MSIX 패키지 ID 로 앱을 구분하고, pubspec.yaml 의 version X.Y.Z+B 가 플랫폼별 버전 이름과 빌드 번호로 바뀌는 방식을 정리합니다.
목차
앱을 스토어에 올리면 식별자(이 앱이 무엇인지)와 버전(몇 번째 판인지)이 스토어에 기록됩니다. 식별자는 한 번 올리면 바꿀 수 없는 곳이 많고, 빌드 번호는 스토어마다 규칙이 있으며(아래 「스토어별 규칙」) 이미 쓴 값을 다시 쓸 수 없는 곳이 있으니 첫 업로드 전에 정해 두세요.
참고
이 페이지의 파일 위치는 Flutter 가 기본으로 만드는 프로젝트 기준입니다. Cocode IDE 로 만든 프로젝트에 플랫폼 폴더(ios/ · android/ · macos/ · windows/)가 어떻게 있는지, 서명과 버전 설정을 CI 가 대신하는지는 프로젝트마다 다를 수 있으니 프로젝트의 README 와 CI 설정을 확인하세요.
준비물
- 식별자로 쓸 이름 — 소유한 도메인을 거꾸로 적은 형태가 기본입니다. 도메인이
mycompany.com이면com.mycompany.myapp처럼 씁니다. - 스토어 계정 — 개발자 계정을 먼저 준비합니다. Apple 은 번들 ID 를 계정에 등록하고, Microsoft 는 앱 이름을 예약한 뒤 파트너 센터에서 패키지 식별 정보를 확인합니다.
- Flutter 프로젝트의
pubspec.yaml— 버전은 이 파일의version:한 줄에서 시작합니다.
식별자
| 스토어 | 식별자 | 규칙 | Flutter 프로젝트에서 정하는 곳 | 바꿀 수 있나 |
|---|---|---|---|---|
| App Store (iOS · iPadOS) | 번들 ID(Bundle ID) | 영문 · 숫자 · 하이픈(-) · 마침표(.)만, 대소문자 구분 없음. 보통 역도메인 형식 | Xcode 의 Runner 타깃 → General → Identity → Bundle Identifier (ios/Runner.xcworkspace) |
App Store Connect 에 빌드를 올린 뒤에는 바꿀 수 없습니다 |
| Mac App Store | 번들 ID | 위와 같음 | macos/Runner/Configs/AppInfo.xcconfig 의 PRODUCT_BUNDLE_IDENTIFIER |
위와 같음 |
| Google Play | 애플리케이션 ID(applicationId, 패키지 이름) | 점으로 나뉜 조각 2개 이상, 각 조각은 글자로 시작, 영문 · 숫자 · 밑줄(_)만 | android/app/build.gradle.kts 의 applicationId |
게시한 뒤 바꾸면 Google Play 가 전혀 다른 앱으로 취급합니다. 패키지 이름은 고유하고 영구적이며, 삭제하거나 나중에 다시 쓸 수 없습니다 |
| Microsoft Store | 패키지 ID 이름(Identity Name) · 게시자(Publisher) | 스토어가 부여합니다 | 파트너 센터의 「제품 ID(Product identity)」 값을 msix_config 에(한국어 화면에서는 「앱 ID 세부 정보」 같은 이름으로 보일 수 있습니다) |
스토어가 부여한 값을 그대로 씁니다(앱 이름을 예약한 뒤 파트너 센터에서 확인) |
팁
iOS 규칙에는 밑줄이 없고 Android 규칙에는 하이픈이 없으므로, 영문 소문자 · 숫자 · 마침표만 쓰되 점으로 나뉜 조각을 2개 이상 두고 각 조각이 글자로 시작하게 하면 두 스토어 모두에 같은 이름을 쓸 수 있습니다(예: com.mycompany.2048game 은 Android 에서 올바르지 않습니다).
주의
Flutter 가 만든 프로젝트의 기본 식별자는 com.example 으로 시작합니다(flutter create --help 에 나오는 --org 옵션으로 프로젝트를 만들 때 정할 수 있습니다). 그대로 올리지 말고 내 이름으로 바꾸세요. Android 에서 applicationId 와 namespace 를 바꾸면 MainActivity 파일의 package 줄과 폴더 위치도 새 이름에 맞춰야 합니다.
참고
Google Play 는 앱을 만들 때 패키지 이름을 Android 개발자 인증에 자동으로 등록해 계정에 연결합니다. 이미 다른 개발자가 쓰는 이름이면 Play Console 이 다른 이름을 고르라고 안내합니다. 기존 앱은 Play Console 홈에서 등록 상태를 확인하세요. Google 은 2026-09-30 까지 등록되지 않은 앱을 Play 에서 삭제한다고 안내했고(2026-10-08 확인) 그 시한은 이미 지났으니, 기존 앱이 있다면 지금 홈에서 등록 상태를 확인하세요.
버전 번호
버전은 pubspec.yaml 한 곳에서 정합니다.
version: 1.2.3+4
+ 앞의 점으로 이은 숫자 세 개가 버전 이름(build name, 사용자에게 보이는 번호)이고, + 뒤의 숫자가 빌드 번호(build number, 스토어가 어느 빌드가 더 새로운지 가리는 번호)입니다. 빌드할 때 --build-name 과 --build-number 로 덮어쓸 수 있습니다.
| 값 | pubspec | 빌드 옵션 | Android | iOS · macOS | Windows |
|---|---|---|---|---|---|
| 버전 이름 | 1.2.3 |
--build-name |
versionName |
CFBundleShortVersionString |
실행 파일의 파일 · 제품 버전 앞 3자리 |
| 빌드 번호 | 4 |
--build-number |
versionCode |
CFBundleVersion |
실행 파일의 파일 · 제품 버전 4번째 자리 |
Windows 의 Microsoft Store 용 MSIX 패키지는 이 표와 다르게 패키징 때 버전을 따로 정합니다(msix_config 의 msix_version, a.b.c.d 형식). msix 패키지(3.18.0 기준)는 MSIX 버전을 --version 옵션 → msix_version → pubspec 의 x.y.z 뒤에 .0 을 붙인 값의 순서로 정하고, pubspec 의 +빌드번호 는 버립니다. 그래서 + 뒤 숫자만 올리면 MSIX 버전이 그대로이니, 업데이트에는 msix_version(또는 pubspec 의 x.y.z)을 올리세요. 스토어 규칙상 첫 자리는 0 이 될 수 없으니, pubspec 의 버전이 0. 으로 시작하면 msix_version 을 직접 정하세요. 아래 규칙도 보세요.
스토어별 규칙
| 스토어 | 규칙 |
|---|---|
| App Store · Mac App Store | CFBundleShortVersionString 은 마침표로 이은 정수 세 개(예: 1.2.3), CFBundleVersion 은 정수 한~세 개를 마침표로 이은 형식이며 둘 다 숫자와 마침표만 씁니다. 빌드는 번들 ID · 버전 번호 · 빌드 문자열의 조합으로 식별되고, 업로드마다 고유한 빌드 번호가 필요합니다. Mac 앱의 빌드 번호는 앱의 모든 버전에 걸쳐 계속 올라가야 하고, 다른 플랫폼은 새 버전에서 1 로 되돌려도 됩니다 |
| Google Play | versionCode 는 양의 정수이고 클수록 최신입니다. 이미 쓴 versionCode 로는 업로드할 수 없고, Google Play 가 허용하는 최댓값은 2100000000 입니다. versionName 은 사용자에게 보이는 문자열입니다. 숫자가 빨리 커지는 번호 체계는 나중에 업데이트를 올리지 못하게 만들 수 있으니 주의하세요(예: 날짜와 시각을 분 단위까지 yyMMddHHmm 으로 이어 붙이면 2610081030 처럼 상한 2100000000 을 넘습니다) |
| Microsoft Store | 패키지 버전은 a.b.c.d 네 자리입니다. 네 번째 자리는 스토어가 쓰도록 예약돼 있어 0 으로 두어야 하고, 나머지는 0~65535 의 정수입니다(첫 자리는 0 불가). 스토어는 기기에 맞는 가장 높은 버전의 패키지를 배포하므로, 모든 사용자가 갱신되려면 업데이트의 버전이 이전보다 높아야 합니다 |
참고
Xcode 로 업로드할 때 기본 배포 방식(「TestFlight & App Store」)은 보관 파일의 빌드 번호를 자동으로 올릴 수 있습니다. CI 가 빌드 번호를 직접 관리한다면 이 옵션 때문에 --build-number 로 정한 값이 업로드 단계에서 바뀌지 않는지 확인하세요.
단계
-
식별자를 정합니다. 소유 도메인을 거꾸로 쓴 이름을 정합니다(예:
com.mycompany.myapp). 스토어마다 규칙이 다르니 위 표의 문자 규칙을 지키세요. -
Flutter 프로젝트에 식별자를 맞춥니다. 위 표의 파일에서
com.example…기본값을 바꿉니다. 바꾼 뒤flutter run으로 앱이 빌드되고 실행되면 성공입니다. -
스토어에 식별자를 등록합니다. Apple 은 개발자 계정의 Certificates, Identifiers & Profiles 에서 Explicit App ID 로 번들 ID 를 등록하고 App Store Connect 의 앱 레코드에 연결합니다. Microsoft 는 파트너 센터에서 앱 이름을 예약한 뒤 「제품 관리 → 제품 ID」 의 패키지 이름 · 게시자 · 게시자 표시 이름을 확인합니다. Google Play 의 패키지 이름은 앱의
applicationId이고, 앱의 첫 아티팩트(번들)를 올리고 나면 고정되어 바꿀 수 없습니다. 고유하고 영구적이라 삭제하거나 다시 쓸 수도 없습니다. -
버전을 올립니다. 새 릴리스를 올릴 때마다
pubspec.yaml의version:을 올립니다. 예:1.0.0+1→1.0.1+2. 빌드 번호는 버전 이름이 같더라도 올리세요. -
빌드해 결과를 확인합니다. 아래 명령으로 스토어에 올릴 산출물을 만듭니다.
flutter build appbundle --build-name=1.0.1 --build-number=2 # Android → build/app/outputs/bundle/release/ 폴더의 .aab flutter build ipa --build-name=1.0.1 --build-number=2 # iOS → build/ios/archive 와 build/ios/ipa flutter build macos --build-name=1.0.1 --build-number=2 # macOS → Xcode 에서 Archive 로 이어 갑니다Windows 는
msix_config에msix_version: 1.0.1.0처럼 네 번째 자리를 0 으로 정한 뒤dart run msix:create --store를 실행합니다.
확인
- 업로드한 빌드가 각 콘솔의 빌드(패키지) 목록에 나타나고, 버전 이름과 빌드 번호가 방금 정한 값과 같습니다.
- 이전에 올린 빌드와 번호가 겹치지 않습니다. Google Play 는 이미 쓴
versionCode의 업로드를 막습니다.
자주 겪는 문제
Google Play 가 이미 사용한 버전 코드라며 업로드를 거부합니다
versionCode 는 올릴 때마다 커져야 하고 이미 쓴 값은 다시 쓸 수 없습니다. pubspec.yaml 의 + 뒤 숫자를 올리고 다시 빌드하세요.
App Store Connect 업로드가 빌드 번호 때문에 실패합니다
업로드마다 고유한 빌드 번호가 필요합니다. 버전 이름이 같아도 + 뒤 빌드 번호를 올려 다시 빌드하세요. Xcode 로 보관(Archive)한 빌드를 검증만 했다면 같은 번호를 다시 쓸 수 있지만, 한 번 업로드한 번호는 다시 쓰지 마세요.
Microsoft Store 제출에서 버전 때문에 막힙니다
스토어 제출용 MSIX 는 버전 네 번째 자리가 0 이어야 합니다. msix_version 의 마지막 숫자를 0 으로 되돌리세요.
Microsoft Store 업데이트를 올렸는데 기존 사용자가 갱신되지 않습니다
스토어는 기기에 맞는 가장 높은 버전을 배포합니다. pubspec 의 + 뒤 빌드 번호만 올리면 msix 패키지가 만드는 MSIX 버전은 바뀌지 않으니, msix_version 의 앞 세 자리를 올려 다시 패키징하세요.
Android 에서 applicationId 를 바꿨더니 앱이 빌드되지 않습니다
applicationId 와 namespace 를 함께 바꿨다면 MainActivity 의 package 선언과 파일 위치(android/app/src/main/kotlin/<새 패키지 경로>/)도 새 이름에 맞춰야 합니다.
다음 단계
식별자와 버전이 정해졌으면 스토어에 보일 이미지를 준비합니다. 아이콘 · 스플래시 · 스크린샷으로 이어서 진행하세요.
출처
- docs.flutter.dev/deployment/ios
- docs.flutter.dev/deployment/macos
- docs.flutter.dev/deployment/android
- docs.flutter.dev/deployment/windows
- developer.apple.com/documentation/bundleresources/information-property-list/cfbundleidentifier
- developer.apple.com/documentation/bundleresources/information-property-list/cfbundleshortversionstring
- developer.apple.com/documentation/bundleresources/information-property-list/cfbundleversion
- developer.apple.com/documentation/xcode/preparing-your-app-for-distribution
- developer.apple.com/documentation/xcode/distributing-your-app-for-beta-testing-and-releases
- developer.android.com/build/configure-app-module
- developer.android.com/studio/publish/versioning
- support.google.com/googleplay/android-developer/answer/9859152
- support.google.com/googleplay/android-developer/answer/17367361
- developer.android.com/developer-verification/guides/google-play-console
- support.google.com/googleplay/android-developer/answer/16984799
- learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msix/app-package-requirements
- pub.dev/packages/msix
- support.google.com/googleplay/android-developer/answer/9845334