App Store (iOS · iPadOS)
Flutter 앱을 iPhone · iPad 용 App Store 에 올리는 전체 절차를 앱 등록, 서명, flutter build ipa, 업로드, TestFlight, 심사 제출, 출시 방식 선택 순서로 안내합니다.
목차
Flutter 앱을 iPhone · iPad 용 App Store 앱으로 올리는 절차를 앱 등록부터 출시까지 이어서 안내합니다. 계정 · 식별자 · 이미지 · 개인정보는 공통 준비에서 끝냈다고 보고, 여기서는 Apple 개발자 계정 사이트 · App Store Connect · Xcode · Flutter 에서 하는 일을 순서대로 다룹니다. Mac 앱은 Mac App Store 편을 보세요.
참고
Cocode IDE 로 만든 프로젝트도 Flutter 프로젝트라 같은 절차를 따릅니다. 다만 프로젝트에 ios/ 폴더가 있는지, 서명과 버전 설정을 CI 가 대신하는지는 프로젝트마다 다를 수 있으니 프로젝트의 README 와 CI 설정을 확인하세요.
주의
업로드 요건 · 심사 소요 시간 · 콘솔 메뉴 이름은 Apple 이 바꿀 수 있습니다. 이 페이지의 수치는 「마지막 확인」 날짜 기준이고, 다르면 Apple 의 공식 문서가 우선합니다. App Store Connect 화면은 로그인이 필요해 직접 확인하지 못했으므로, 메뉴와 버튼 이름 · 각 단계의 성공 판정(화면에 보이는 상태)은 Apple 도움말의 설명을 따랐습니다. 이름은 확인한 범위에서 한국어판 도움말의 표기를 「한글(영문)」으로 적었고, 확인하지 못한 이름은 영문으로 적었습니다(역할 이름은 영문으로 통일했습니다).
준비물
- 끝낸 공통 준비 — 개발자 계정(Apple Developer Program 이 활성이고 Account Holder 가 App Store Connect 의 최신 계약에 서명), 식별자와 버전, 아이콘 · 스플래시 · 스크린샷, 개인정보와 권한.
- Mac 과 Xcode — Apple 은 2026-04-28 부터 Xcode 26 이상으로, iOS 26 SDK 이상을 써서 빌드한 앱만 App Store Connect 에 올릴 수 있다고 안내합니다. 또 2026-09-09 부터는 iOS 13 이상을 대상으로 하는 앱이어야 합니다. Flutter 3.47 이 지원하는 iOS 는 15 이상이라 Flutter 앱은 보통 이 요건을 이미 넘습니다. Apple 은 2027년 4월부터는 iOS · iPadOS 앱을 iOS 27 SDK 이상으로 빌드해야 한다고 예고했습니다. 제출 안내 페이지에는 iOS 15 이상을 대상으로 해야 한다는 문구도 있지만 개발자 소식에는 없고, 정확한 날짜는 어느 쪽에도 없습니다(2026-10-09 확인). 배포 대상을 13 · 14 로 낮춰 둔 프로젝트라면 이 요건에 걸릴 수 있으니 제출 안내 페이지를 확인하세요.
- App Store Connect 역할 — Apple 도움말의 「필요한 역할」 기준으로, 앱 레코드는 Account Holder · App Manager · Admin 이, 빌드 업로드는 Account Holder · Admin · App Manager · Developer 가, 심사 제출과 출시 옵션 설정은 Account Holder · Admin · App Manager 가 합니다. 역할마다 세부 권한은 Apple 의 역할 권한 표를 확인하세요.
- 실제 iPhone 이나 iPad — 릴리스 빌드를 한 번 실행해 봅니다(제출 전 체크리스트 참고).
- (로그인이 있는 앱) 심사용 데모 계정 — 만료되지 않는 계정을 준비합니다. 법적 · 보안상 계정을 줄 수 없을 때만 Apple 의 사전 승인을 받아 데모 모드로 대신할 수 있습니다(심사 지침 2.1(a)).
프로젝트에서 바꿀 항목
아래 파일 위치와 기본값은 flutter create 로 만든 Flutter 3.47.6 기본 프로젝트에서 확인한 것입니다(2026-10-09). 프로젝트마다 다를 수 있으니 직접 열어 확인하세요.
| 항목 | 어디서 바꾸나 | 기본값과 메모 |
|---|---|---|
| 번들 ID | ios/Runner.xcworkspace 를 Xcode 로 열어 Runner 타깃 → General → Identity → Bundle Identifier (프로젝트 파일에서는 PRODUCT_BUNDLE_IDENTIFIER) |
기본은 com.example.<프로젝트 이름을 lowerCamelCase 로 바꾼 값> 입니다(예: my_app → com.example.myApp). 기본 com.example 번들 ID 가 남아 있으면 Flutter 도구가 경고하니 내 이름으로 바꾸세요. App Store Connect 의 번들 ID 와 같아야 하고, 빌드를 올린 뒤에는 바꿀 수 없습니다 |
| 표시 이름 | ios/Runner/Info.plist 의 CFBundleDisplayName |
홈 화면 아이콘 아래에 보이는 이름이며 기본은 프로젝트 이름을 읽기 좋게 바꾼 값입니다. App Store Connect 의 앱 「이름」과는 따로 입력합니다 |
| 버전 · 빌드 번호 | pubspec.yaml 의 version: |
Info.plist 의 CFBundleShortVersionString · CFBundleVersion 이 빌드 때 이 값을 받아 씁니다. 자세한 규칙은 식별자와 버전 |
| 서명 · 팀 | Runner 타깃 → Signing & Capabilities → Automatically manage signing · Team | 기본은 자동 서명입니다 |
| 최소 iOS 버전 | Runner 타깃 → Build Settings → Deployment → iOS Deployment Target (프로젝트 파일에서는 IPHONEOS_DEPLOYMENT_TARGET) |
기본은 15.0 입니다. Apple 의 업로드 요건은 iOS 13 이상입니다 |
| 권한 사유 문구 | ios/Runner/Info.plist 의 NS…UsageDescription 키 |
기본 템플릿에는 없습니다. 앱이 쓰는 기능마다 추가합니다. 개인정보와 권한 |
| entitlements | Runner 타깃 → Signing & Capabilities 에서 capability 를 더합니다 | 기본 템플릿에는 iOS entitlements 파일이 없습니다. App ID 에서 켠 capability 를 쓰려면 Xcode 프로젝트의 타깃에도 추가해야 합니다 |
| 수출 규정 키 | ios/Runner/Info.plist 의 ITSAppUsesNonExemptEncryption |
기본 템플릿에는 없습니다. 아래 11단계를 보세요 |
| 아이콘 · 런치 이미지 | ios/Runner/Assets.xcassets 의 AppIcon · LaunchImage |
아이콘 · 스플래시 · 스크린샷 |
단계
앱 등록
-
계약 상태를 확인합니다. Account Holder 가 App Store Connect 의 「비즈니스(Business)」 섹션에서 최신 계약에 서명하기 전에는 계정에 앱을 추가할 수 없습니다. 유료 앱이나 앱 내 결제를 낼 때는 Account Holder 가 유료 앱 계약(Paid Apps Agreement)에도 서명해야 하고, 서명하지 않았다면 앱을 무료로만 제공할 수 있습니다. 성공 판정 — 「앱(Apps)」 페이지에서 앱 추가 버튼(+)을 누를 수 있습니다.
-
번들 ID 를 Apple 개발자 계정에 등록합니다. Certificates, Identifiers & Profiles 의 Identifiers 에서 추가 버튼(+) → App IDs → App → Description 입력 → Explicit App ID 선택 → Bundle ID 칸에 식별자와 버전에서 정한 번들 ID 입력 → 앱이 쓰는 capability 선택 → Continue → Register 순서입니다. App Store Connect 에 올리려면 명시적(Explicit) App ID 로 등록된 앱 레코드가 필요하고, 여기 입력한 번들 ID 는 Xcode 프로젝트의 번들 ID 와 같아야 합니다. Apple 도움말의 「필요한 역할」은 Account Holder 또는 Admin 입니다. 성공 판정 — 등록한 번들 ID 가 Identifiers 목록에 보입니다.
-
App Store Connect 에 앱 레코드를 만듭니다. App Store Connect의 「앱(Apps)」에서 추가 버튼(+) → 「신규 앱(New App)」을 고르고 아래를 입력한 뒤 「생성(Create)」을 누릅니다.
- 플랫폼 — iOS 를 선택합니다. Flutter 문서는 Flutter 가 tvOS 를 지원하지 않으니 tvOS 는 선택하지 말라고 안내합니다.
- 이름 — 2자 이상 30자 이하입니다. 앱 심사에 제출하기 전까지 편집할 수 있고, 그 뒤에는 새 버전을 만들 때나 버전 상태가 허용할 때 바꿉니다. 같은 이름은 현지화마다 앱 하나에만 쓸 수 있습니다.
- 기본 언어(Primary Language) — 제품 페이지 문구의 기본 언어입니다.
- 번들 ID — 2단계에서 등록한 것을 고릅니다. 빌드를 올린 뒤에는 바꿀 수 없습니다.
- SKU — 내부 추적용 고유 ID 로 고객에게 보이지 않습니다. 문자 · 숫자 · 하이픈 · 마침표 · 밑줄을 쓸 수 있고 하이픈 · 마침표 · 밑줄로 시작할 수 없으며, 앱을 추가한 뒤에는 바꿀 수 없습니다.
- 사용자 액세스 권한(User Access) — 「제한된 액세스」면 이 앱을 볼 사용자를 직접 고릅니다.
조직으로 등록했다면 등록된 상호나 DBA 를 법적 이름 대신 개발자 이름으로 쓸 수 있습니다(입력란은 「회사 이름(Company Name)」). 이 이름은 계정에 처음 앱을 추가할 때만 정할 수 있고 나중에 고칠 수 없습니다. 성공 판정 — 앱이 「앱」 목록에 나타나고 상태가 「제출 준비 중(Prepare for Submission)」입니다.
서명과 릴리스 빌드
-
서명을 정합니다.
open ios/Runner.xcworkspace로 Xcode 를 열고 Runner 타깃의 Signing & Capabilities 에서 Automatically manage signing 을 켠 채(Flutter 기본값) Team 에 Apple Developer Program 의 팀을 고릅니다. Apple 은 Xcode 가 클라우드 관리 서명 인증서로 앱을 자동 서명하고, 자동 서명으로 App Store Connect 에 올리면 배포 프로비저닝 프로필도 관리해 준다고 안내합니다. CI 처럼 직접 서명해야 하면 아래를 준비합니다.준비할 것 이름과 만드는 곳 배포 인증서 현재 이름은 「Apple 배포(Apple Distribution)」입니다(「iOS Distribution」은 Xcode 11 이하용 옛 이름). Certificates, Identifiers & Profiles 나 Xcode 에서 만들고, Apple 도움말의 「필요한 역할」은 Account Holder 또는 Admin 이며 종류마다 팀당 하나만 허용됩니다. 만들 때 필요한 인증서 서명 요청(CSR)은 Mac 의 Keychain Access → Certificate Assistant → Request a Certificate from a Certificate Authority 에서 「Saved to disk」로 만듭니다 프로비저닝 프로필 Profiles → 추가 버튼(+) → Distribution 에서 「App Store Connect」 → 번들 ID 와 일치하는 App ID → 배포 인증서 → 이름 → Generate → Download. 프로필에는 배포 인증서가 하나만 들어갑니다. 인증서가 만료되거나 폐기되면 그 인증서로 서명한 새 앱이나 업데이트는 App Store Connect 에 올릴 수 없으니 새 인증서로 다시 서명합니다 팀 ID 10자리 문자열이며 개발자 계정의 「멤버십 세부 사항(Membership details)」에서 찾습니다 성공 판정 — Xcode 의 Signing & Capabilities 에 서명 오류가 없습니다.
-
버전과 빌드 번호를 올립니다.
pubspec.yaml의version: 1.0.0+1에서+앞이CFBundleShortVersionString, 뒤가CFBundleVersion이 됩니다. 업로드마다 고유한 빌드 번호가 필요합니다. 규칙은 식별자와 버전을 보세요. 성공 판정 — 올릴 버전이pubspec.yaml에 적혀 있고,+뒤 빌드 번호가 이미 올린 빌드의 번호와 겹치지 않습니다. -
flutter build ipa로 릴리스 빌드를 만듭니다. 프로젝트 폴더에서 실행합니다.flutter build ipa --build-name=1.0.0 --build-number=1- 기본이 릴리스 모드이고
--export-method의 기본값은app-store(App Store 업로드용)입니다. - 결과로
build/ios/archive/에 Xcode 아카이브(.xcarchive)가,build/ios/ipa/에 App Store 용 앱 번들(.ipa)이 생깁니다. - Dart 코드를 난독화하려면
--obfuscate --split-debug-info=<심볼 폴더>를 함께 주고, 나중에 스택 트레이스를 해독할 수 있게 그 폴더의 심볼 파일을 보관하세요. - Xcode 의 Distribute App 으로 내보낸
ExportOptions.plist가 있으면--export-options-plist로 같은 옵션을 다시 쓸 수 있습니다. - 빌드 전에
ios/Runner/Info.plist의ITSAppUsesNonExemptEncryption을 정해 두면(11단계의 수출 규정) 업로드 뒤 같은 질문을 받지 않습니다.
성공 판정 — 명령이
Built build/ios/archive/…xcarchive를 출력한 뒤.ipa를 만들고Built IPA to …로 끝납니다. 아카이브 직후 출력되는 「App Settings Validation」(버전 · 빌드 번호 · 표시 이름 · 배포 대상 · 번들 ID)에서 기본com.example경고가 없는지, 「App Icon and Launch Image Assets Validation」에서 자리표시자 아이콘 · 런치 이미지 경고가 없는지 보세요(Flutter 3.47.6 도구 소스로 확인). - 기본이 릴리스 모드이고
업로드와 TestFlight 시험
-
빌드를 업로드합니다. Apple 은 앱을 계정에 추가한 뒤 Xcode · Swift Playground · altool · Transporter 로 빌드를 올릴 수 있다고 안내합니다. 어느 도구든 업로드할 때 번들 ID 와 버전 번호로 빌드를 앱 레코드에 연결하고, 빌드 문자열(빌드 번호)로 빌드를 구분합니다.
도구 이럴 때 방법 Xcode 서명을 Xcode 에 맡길 때 build/ios/archive/의.xcarchive를 Xcode 로 열어 Validate App 으로 먼저 검증하고, 문제가 없으면 Distribute App → TestFlight & App Store(기본 권장 설정)로 올립니다Transporter .ipa를 끌어다 놓기만 할 때Mac App Store 에서 Transporter 를 받아 build/ios/ipa/*.ipa를 끌어다 놓습니다xcrun altool명령줄 · CI 아래 명령과 안내를 보세요 App Store Connect API CI 자동화 API 키로 JWT 를 만들어 Transporter 명령줄 도구 등으로 올립니다 명령줄로 올릴 때는 App Store Connect API 키(
.p8) 또는 사용자 이름과 앱 암호로 인증합니다. 아래 예시는 API 키를 씁니다. 팀 키는 App Store Connect 의 Users and Access → Integrations → Team Keys 에서 Account Holder 나 Admin 이 만들 수 있고(Apple 도움말은 App Store Connect API 접근을 요청하는 일은 Account Holder 만 할 수 있다고 안내합니다), 개인 키 파일은 한 번만 내려받을 수 있습니다. Apple 의 altool 가이드는--upload-app명령이 deprecated(2022-04-01)이니--upload-package를 쓰라고 안내합니다. 형식은 다음과 같습니다.xcrun altool --upload-package build/ios/ipa/<앱>.ipa -t ios \ --apple-id <앱의 Apple ID> --bundle-id <번들 ID> \ --bundle-short-version-string <버전> --bundle-version <빌드 번호> \ --apiKey <키 ID> --apiIssuer <발급자 ID><앱의 Apple ID>는 앱을 계정에 추가할 때 자동으로 만들어지는 고유 식별자로, App Store Connect 의 앱 정보(App Information)에서 볼 수 있습니다. 계정이 여러 제공자(provider)에 속하면 가이드는--asc-public-id도 요구합니다.--apiKey의 키 ID 에 해당하는AuthKey_<키 ID>.p8파일은 altool 이 정해진 폴더(./private_keys·~/private_keys·~/.private_keys·~/.appstoreconnect/private_keys)나 환경 변수API_PRIVATE_KEYS_DIR가 가리키는 폴더에서 찾으니 그곳에 두세요(altool 가이드와 Xcode 27.0 의xcrun altool --help).참고
공식 문서끼리 어긋나는 곳입니다. altool 가이드는
--upload-app이 deprecated 라고 하는데 Apple 의 「빌드 업로드」 도움말과 Flutter 문서는 아직--upload-app형식을 보여 줍니다. Xcode 27.0(altool 27.0.5)의xcrun altool --help는--upload-package와--upload-app -f를 모두 나열하고 deprecated 표시는 없으며(2026-10-09 확인),--upload-package항목에는--wait만 보이고 위의--apple-id·--bundle-id같은 옵션은 나열하지 않습니다. 제공자가 여럿일 때의 옵션도 가이드는--asc-public-id, 도움말은--provider-public-id이고, API 키 옵션은 도움말이--api-key·--api-issuer로 적습니다. 그래서 명령줄을 쓰기 전에 설치된 Xcode 의xcrun altool --help로 현재 옵션을 확인하세요. altool 은 공증 용도로는 더 이상 쓸 수 없지만 App Store 에 앱을 올리는 데는 여전히 쓸 수 있다고 Apple 이 안내합니다. 2단계 인증을 켠 계정으로 사용자 이름과 비밀번호로 올리려면 앱 암호를 만들어야 합니다.성공 판정 — 도구가 오류 없이 끝납니다. 빌드가 App Store Connect 에 나타나는지는 다음 단계에서 확인합니다.
-
처리가 끝나기를 기다립니다. 빌드는 Apple 시스템에서 처리된 뒤에야 App Store Connect 에 나타나고, 처리가 끝나면 이메일이 옵니다.
- Flutter 문서는 보통 30분 안에 이메일이 온다고 안내하지만 Apple 이 보장하는 시간은 아닙니다.
- 업로드 진행 상황은 앱의 TestFlight 탭에서 「빌드 업로드(Build Uploads)」를 펼쳐 「상태」 열로 봅니다. Flutter 문서는 Activities 탭을 안내하지만, Apple 도움말이 설명하는 곳은 TestFlight 탭의 「빌드 업로드」입니다.
- 「처리 중(Processing)」이 24시간을 넘으면 문제가 있을 수 있다고 Apple 이 안내하고, 이때는 Feedback Assistant 에 티켓을 제출하거나 Apple 에 문의하라고 합니다. 처리가 끝났는데 문제가 있으면 「실패(Failed)」이고, 업로드가 실패했다면 다음 업로드에 같은 빌드 번호를 다시 써도 됩니다.
- 빌드에 「수출 규정 관련 문서가 누락됨(Missing Compliance)」이 보이면 11단계의 수출 규정 질문에 답하세요.
성공 판정 — 빌드 업로드 상태가 「완료(Complete)」입니다.
-
TestFlight 로 시험합니다. 앱의 TestFlight 탭에서 내부 그룹을 만들고(「내부 테스팅(Internal Testing)」 옆 + 버튼) 빌드를 추가한 뒤(「빌드 추가(Add Builds)」 → 「테스트 내용(What to Test)」 입력 → 「추가(Add)」) 그룹 오른쪽의 「테스터 초대(Invite Testers)」로 초대할 App Store Connect 사용자를 고릅니다.
- 내부 테스터는 App Store Connect 사용자로 최대 100명까지이고, 외부 테스터는 App Store Connect 사용자가 아닌 사람으로 최대 10,000명까지입니다.
- 외부 테스트는 먼저 내부 그룹을 만들어야 하고, TestFlight 용 테스트 정보(「베타 앱 설명(Beta App Description)」 필수)가 필요하며, 외부 그룹에 처음 넣는 빌드는 App Review 의 TestFlight 심사를 거칩니다.
- 외부 그룹은 사이드바의 「외부 테스팅(External Testing)」 옆 + 버튼으로 만들고 「빌드 추가」로 빌드를 넣은 뒤, 빌드 상태에 따라 「심사 제출(Submit Review)」 또는 「테스팅 시작(Start Testing)」을 누릅니다. 이메일 주소나 공개 링크로 테스터를 초대합니다.
- 테스터는 TestFlight 앱에서 초대를 수락해 설치합니다. 빌드는 최대 90일 동안 테스트할 수 있습니다.
성공 판정 — 테스터가 TestFlight 앱으로 빌드를 설치해 실행합니다.
등록정보와 심사 제출
-
스토어 등록정보를 채웁니다. App Store Connect 의 앱 페이지에서 채웁니다. 정확한 목록은 Apple 의 필수 속성 표를 직접 확인하세요.
- 앱 정보에서 필수: 이름 · 연령 등급 · 번들 ID · SKU · 콘텐츠 권한(Content Rights) · 기본 언어 · 기본 카테고리 · 디지털 서비스법(DSA) 거래자 상태(EU 에 배포하지 않아도 신고해야 합니다). 한국에서 조직 계정으로 배포하면 「대한민국에서의 사용 가능 여부(Availability in the Republic of Korea)」도 필수입니다(제출 전 체크리스트 참고).
- 버전 페이지에서 필수: 지원 URL · 저작권 · 앱 심사 정보 · 버전 출시 설정. 설명(최대 4000자)과 키워드(전체 100바이트)도 필요합니다.
- 이미지는 아이콘 · 스플래시 · 스크린샷의 규격을 따릅니다.
- 콘텐츠 권한은 제3자 콘텐츠를 담거나 보여 주거나 접근하는 앱이 그 콘텐츠에 필요한 모든 권리를 갖고 있거나 앱을 제공하는 각 국가 · 지역의 법에 따라 쓸 수 있어야 한다는 속성입니다.
성공 판정 — Apple 의 필수 속성 표와 대조해 위 필수 항목에 빈 칸이 없습니다.
-
개인정보 · 수출 규정 · 연령 등급에 답합니다.
- 앱이 수집하는 개인정보(App Privacy) — 사이드바의 「앱이 수집하는 개인정보」 → 「시작하기(Get Started)」에서 답하고 「게시(Publish)」를 누릅니다. 개인정보 처리방침 URL 은 모든 앱에 필수입니다. 질문에 답하는 방법은 개인정보와 권한을 보세요.
- 수출 규정(암호화) — 앱이 암호화를 쓰거나 접근하면 App Store Connect 의 질문에 답해야 합니다. 앱이 암호화를 쓰지 않거나 면제되는 암호화만 쓰면
Info.plist에ITSAppUsesNonExemptEncryption을NO로 넣어 두면 업로드할 때마다 같은 질문을 받지 않습니다. 이 키가 없으면 새 버전을 올릴 때마다 질문지가 나옵니다. 책임은 개발자에게 있으니 정확히 판단하세요. - 연령 등급 — 「앱 정보(App Information)」의 「연령 등급(Age Ratings)」에서 「연령 등급 설정(Set Up Age Ratings)」으로 질문지에 답합니다. 등급이 없는 앱은 App Store 에 게시할 수 없습니다. 2026년 9월부터는 새 앱과 업데이트를 제출할 때 소셜 미디어 기능 질문에도 답해야 한다고 Apple 이 밝혔습니다.
성공 판정 — 앱 개인정보를 게시(Publish)했고, 수출 규정 질문에 답했거나
ITSAppUsesNonExemptEncryption을 넣었고, 연령 등급 질문지를 마쳤습니다. -
앱 심사 정보와 가격 · 가용성을 정합니다.
- 앱 심사 정보에는 연락처(이름 · 이메일 · 국제 형식 전화번호)를 필수로 넣고, 로그인이 필요한 앱은 제출 시점에 동작하는 데모 계정을 넣습니다. Notes 에는 비직관적인 기능을 설명합니다.
- 사이드바의 「가격 및 사용 가능 여부(Pricing and Availability)」에서 가격(무료 포함)과 제공 국가 · 지역을 정해야 심사에 제출할 수 있습니다.
성공 판정 — 앱 심사 정보(연락처 · 데모 계정)와 가격 · 제공 국가 · 지역이 채워져 있습니다.
-
빌드를 고르고 심사에 제출합니다. 앱의 버전 페이지에서 Build 섹션의 추가 버튼(+)으로 올린 빌드를 고르고(「완료」 → 오른쪽 위 「저장」) 올바른 빌드가 연결됐는지 확인합니다. 오른쪽 위 「심사에 추가(Add for Review)」로 제출 초안에 넣은 뒤(상태 「심사 준비됨(Ready for Review)」) 「심사를 위해 제출(Submit for Review)」을 누릅니다. 이 단계에서 출시 방식도 고릅니다. 버전 페이지의 「App Store 버전 출시(App Store Version Release)」에서 고르는 세 가지입니다.
선택지 동작 「수동으로 버전 출시(Manually release this version)」 승인 뒤 상태가 「개발자 출시 대기 중(Pending Developer Release)」이 되고, 직접 「이 버전 출시(Release This Version)」를 눌러 출시합니다 「자동으로 버전 출시(Automatically release this version)」 승인되면 자동으로 출시합니다 「다음 날짜 이후 앱 심사가 끝나면 자동으로 이 버전을 공개(Automatically release this version after App Review, no earlier than)」 정한 날짜와 시간 이후에 자동으로 출시합니다 성공 판정 — 상태가 「심사 대기 중(Waiting for Review)」으로 바뀝니다.
심사와 출시
-
심사 결과를 기다리고 출시합니다.
- 상태는 「심사 대기 중」 → 「심사 중(In Review)」으로 바뀝니다. Apple 은 App Review 가 보통 제출의 최소 50% 를 24시간 안에, 90% 를 48시간 안에 심사한다고 안내합니다. 보장이 아니므로 일정에 여유를 두세요.
- 승인되면 고른 출시 방식대로 출시됩니다. 수동 출시를 골랐다면 직접 출시해야 하고, 「개발자 출시 대기 중」이 30일을 넘으면 Apple 이 이메일로 알립니다. 출시 뒤 App Store 에 보이기까지 최대 24시간이 걸릴 수 있습니다.
- 거절되면 App Store Connect 의 메시지를 읽고 아래 「자주 겪는 문제」를 보세요. 스토어별 사유와 번호는 심사 거절 대응에도 모아 두었습니다.
- 앱을 업데이트할 때는 새 버전을 7일에 걸쳐 나눠 내는 단계적 출시(Phased Release)를 고를 수 있습니다. App Store Connect API 문서는 이 기능을 앱의 첫 버전에는 쓸 수 없다고 밝힙니다. 업데이트 절차는 업데이트와 단계적 출시에서 이어집니다.
성공 판정 — 상태가 「배포 준비됨(Ready for Distribution)」입니다.
확인
- 빌드:
flutter build ipa가build/ios/archive/…xcarchive와build/ios/ipa/의.ipa를 만들고, 「App Settings Validation」 에com.example경고가 없습니다. - 업로드: 앱의 TestFlight 탭에서 빌드 업로드 상태가 「완료(Complete)」이고 빌드 번호가 방금 올린 값과 같습니다.
- TestFlight: 테스터가 TestFlight 앱으로 빌드를 설치해 실행해 봤습니다.
- 제출: 앱 상태가 「심사 대기 중」으로 바뀌었습니다. 심사가 시작되면 「심사 중」이 됩니다.
- 출시: 상태가 「배포 준비됨(Ready for Distribution)」이고 App Store 에서 앱 제품 페이지가 열립니다.
자주 겪는 문제
앱 레코드를 만드는 화면에서 번들 ID 가 보이지 않습니다
앱 레코드에는 명시적(Explicit) App ID 로 등록한 번들 ID 가 필요합니다. 목록에 번들 ID 가 없으면 위 2단계대로 Certificates, Identifiers & Profiles 의 Identifiers 에 등록했는지, 같은 개발자 계정(팀)인지 확인하세요. 번들 ID 는 Xcode 프로젝트의 번들 ID 와 같아야 합니다.
앱 이름을 쓸 수 없다고 합니다
이름은 현지화마다 앱 하나에만 쓸 수 있습니다. 내 계정의 다른 앱이 이미 쓰고 있다면 그 앱의 이름을 바꾸는 업데이트를 제출하거나 그 앱을 App Store Connect 에서 제거하세요. 다른 개발자가 쓰고 있고 내가 상표권을 가졌다면 클레임을 제출할 수 있습니다.
업로드한 빌드가 App Store Connect 에 보이지 않습니다
빌드는 처리가 끝나야 나타나고, 처리가 끝나면 이메일이 옵니다. 앱의 TestFlight 탭에서 「빌드 업로드」 상태를 확인하세요. 「실패(Failed)」면 문제를 고치고 다시 올리며, 24시간이 넘도록 「처리 중(Processing)」이면 문제가 있을 수 있다고 Apple 이 안내하니 Feedback Assistant 에 티켓을 제출하거나 Apple Developer Support 에 문의하세요.
빌드 번호가 이미 있다며 업로드가 거부됩니다
업로드마다 고유한 빌드 번호가 필요합니다. pubspec.yaml 의 + 뒤 숫자를 올리거나 --build-number 를 올려 다시 빌드하세요. Xcode 의 「Manage version and build number」 옵션을 켜 두면 Xcode 가 업로드 때 빌드 번호를 바꿀 수 있으니 CI 에서는 이 옵션을 확인하세요.
빌드에 「수출 규정 관련 문서가 누락됨(Missing Compliance)」이 뜨고 제출이 막힙니다
수출 규정(암호화) 정보가 빠졌다는 뜻입니다. 해당 빌드에서 질문에 답하거나, 앱이 암호화를 쓰지 않거나 면제되는 암호화만 쓴다면 Info.plist 에 ITSAppUsesNonExemptEncryption 을 NO 로 넣고 새 빌드를 올리세요.
업로드할 때 권한 사유 문구가 없다는 오류가 납니다
카메라 · 위치 · 사진처럼 보호된 데이터에 접근하는 API 를 쓰면 Info.plist 에 해당 키와 사용 설명 문자열이 있어야 합니다. 플러그인이 참조하는 API 의 키도 필요할 수 있으니, 오류가 알려 주는 키를 ios/Runner/Info.plist 에 추가하세요. 문구 쓰는 법은 개인정보와 권한을 보세요.
업로드가 필수 사유 API(개인정보 매니페스트) 누락으로 거부됩니다
Apple 은 앱 코드(서드파티 SDK 포함)가 쓰는 필수 사유 API 마다 승인된 사유를 밝혀야 새 앱이나 업데이트를 App Store Connect 에 올릴 수 있다고 안내합니다. 앱과 플러그인이 쓰는 API 에 승인된 사유를 PrivacyInfo.xcprivacy 에 적으세요. 방법은 개인정보와 권한을 보세요.
외부 TestFlight 테스트가 시작되지 않습니다
외부 그룹에 처음 추가한 빌드는 App Review 의 TestFlight 심사를 통과해야 테스트를 시작할 수 있습니다. 그룹의 빌드 상태가 「심사 대기 중(Waiting for Review)」이나 「베타 심사 중(In Beta Review)」인지 확인하세요.
심사에서 2.1 (App Completeness) 로 거절됐습니다
Apple 심사 지침 2.1(a)는 제출물이 모든 메타데이터와 동작하는 URL 을 갖춘 최종본이어야 하고 플레이스홀더 텍스트 · 빈 웹사이트를 없애야 한다고 정합니다. 기기에서 충돌 · 버그를 시험하고, 로그인이 있으면 데모 계정을 넣고 백엔드 서비스를 켜 두며, 충돌하거나 눈에 띄는 기술 문제가 있는 앱은 거절된다고 안내합니다. 해결되지 않은 이슈의 평균 40% 이상이 이 지침과 관련된다고 Apple 이 밝힙니다.
심사에서 4.x (디자인) 로 거절됐습니다
4.2 (Minimum Functionality)는 앱이 재포장한 웹사이트를 넘어서는 기능 · 콘텐츠 · UI 를 갖춰야 한다고 정합니다. 4.3(a)는 같은 앱의 번들 ID 를 여러 개 만들지 말라고, 4.3(b)는 이미 널리 있는 앱과 구분되지 않는 앱을 내지 말라고 정합니다. 4.2.6 은 상용 템플릿이나 앱 생성 서비스로 만든 앱을 콘텐츠 제공자가 직접 제출하지 않으면 거절한다고 정하니, 템플릿 그대로가 아니라 내 콘텐츠와 기능을 담았는지 점검하세요. 소셜 로그인으로 주 계정을 만든다면 4.8 이 요구하는 동등한 로그인 서비스도 제공해야 합니다.
심사에서 개인정보 (5.1.1) 로 거절됐습니다
5.1.1(i)은 개인정보 처리방침 링크를 App Store Connect 와 앱 안 두 곳에 넣어야 한다고, 5.1.1(v)는 계정 생성을 지원하면 앱 안에서 계정 삭제도 제공해야 한다고 정합니다. 방침 · 스토어 선언 · 실제 동작을 맞추는 방법은 개인정보와 권한을 보세요.
거절됐습니다. 어떻게 답하나요?
App Store Connect 의 App Review 메시지에서 지침 위반 내용을 읽습니다. 메타데이터 문제로 거절됐다면 문제를 고친 뒤 같은 빌드를 다시 제출할 수 있습니다. 빌드 문제는 고친 새 빌드를 올려 다시 제출하세요. Apple 은 App Review 와 메시지로 이슈를 해결한 뒤 빌드를 다시 제출하라고 안내합니다. 결과에 동의하지 않으면 먼저 메시지로 해명하고, 그래도 해결되지 않을 때 App Review Board 에 이의 제기(appeal)를 합니다. 이의 제기는 거절되거나 삭제된 앱 하나당 한 번이라고 Apple 의 이의 제기 안내가 적습니다. 스토어별 사유와 번호, 재제출 방법은 심사 거절 대응을 보세요.
승인됐는데 상태가 「개발자 출시 대기 중」에서 멈췄습니다
수동 출시를 골랐거나, 「다음 날짜 이후 …」를 골랐는데 아직 그 날짜가 지나지 않았기 때문입니다. 수동이면 버전 페이지에서 「이 버전 출시(Release This Version)」 → 「확인」을 누르세요. 날짜를 정한 경우에는 그 날짜에 자동으로 출시됩니다. 출시를 취소하려면 버전 페이지 메시지에서 「출시를 취소(Cancel This Release)」를 고릅니다.
다음 단계
같은 Apple 계정으로 Mac 앱도 올린다면 Mac App Store 편으로 이어서 보세요. 제출 직전에는 제출 전 체크리스트를 다시 훑고, 다른 스토어는 스토어별 안내에서 고르세요. 출시한 뒤의 업데이트와 거절 대응은 출시 후 운영에서 다룹니다.
출처
- developer.apple.com/news/upcoming-requirements
- developer.apple.com/app-store/submitting
- developer.apple.com/news/?id=k1mtkt1k
- developer.apple.com/help/app-store-connect/create-an-app-record/add-a-new-app
- developer.apple.com/help/app-store-connect/reference/app-information/app-information
- developer.apple.com/help/app-store-connect/manage-agreements/sign-and-update-agreements
- developer.apple.com/help/account/identifiers/register-an-app-id
- developer.apple.com/help/account/certificates/certificates-overview
- developer.apple.com/help/account/certificates/cloud-managed-certificates
- developer.apple.com/help/account/certificates/create-a-certificate-signing-request
- developer.apple.com/help/account/provisioning-profiles/create-an-app-store-provisioning-profile
- developer.apple.com/help/glossary/team-id
- developer.apple.com/documentation/xcode/preparing-your-app-for-distribution
- developer.apple.com/documentation/xcode/distributing-your-app-for-beta-testing-and-releases
- developer.apple.com/help/app-store-connect/manage-builds/upload-builds
- help.apple.com/asc/appsaltool/en.lproj/static.html
- developer.apple.com/documentation/technotes/tn3147-migrating-to-the-latest-notarization-tool
- developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api
- developer.apple.com/help/app-store-connect/reference/app-uploads/build-upload-statuses
- developer.apple.com/help/app-store-connect/reference/app-uploads/app-build-statuses
- developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview
- developer.apple.com/help/app-store-connect/test-a-beta-version/add-internal-testers
- developer.apple.com/help/app-store-connect/test-a-beta-version/invite-external-testers
- developer.apple.com/help/app-store-connect/test-a-beta-version/provide-test-information
- developer.apple.com/help/app-store-connect/reference/app-information/required-localizable-and-editable-properties
- developer.apple.com/help/app-store-connect/manage-app-information/manage-app-privacy
- developer.apple.com/help/app-store-connect/manage-app-information/overview-of-export-compliance
- developer.apple.com/documentation/bundleresources/information-property-list/itsappusesnonexemptencryption
- developer.apple.com/help/app-store-connect/manage-app-information/set-an-app-age-rating
- developer.apple.com/news/?id=tlur8uvi
- developer.apple.com/help/app-store-connect/manage-app-pricing/set-a-price
- developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-an-app
- developer.apple.com/help/app-store-connect/reference/app-information/app-and-submission-statuses
- developer.apple.com/distribute/app-review
- developer.apple.com/app-store/review/guidelines
- developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages
- developer.apple.com/help/app-review/after-submitting-for-review/appeal-to-the-app-review-board
- developer.apple.com/help/app-store-connect/manage-your-apps-availability/select-an-app-store-version-release-option
- developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases
- developer.apple.com/documentation/appstoreconnectapi/app-store-version-phased-releases
- docs.flutter.dev/deployment/ios
- docs.flutter.dev/reference/supported-platforms
- docs.flutter.dev/deployment/obfuscate
- developer.apple.com/help/app-store-connect/create-an-app-record/set-your-developer-name
- developer.apple.com/help/app-store-connect/reference/app-information/platform-version-information
- developer.apple.com/help/app-store-connect/manage-builds/view-builds-and-metadata
- developer.apple.com/help/app-store-connect/manage-builds/choose-a-build-to-submit
- developer.apple.com/help/app-store-connect/reference/account-management/role-permissions
- developer.apple.com/help/app-store-connect/manage-compliance-information/manage-european-union-digital-services-act-trader-requirements