EAS Submit iOS: Expo 앱 App Store 출시 방법
글: Mehdi Azizi
게시, 8분
EAS Submit은 iOS 빌드를 App Store Connect로 보내 TestFlight에 올려요. 심사 제출은 App Store Connect에서 직접 해야 해요.
eas submit --platform ios는 iOS 빌드를 App Store Connect로 보내고, Apple의 처리가 끝나면 빌드가 TestFlight에 나타나요. 이 명령어는 앱을 Apple 심사에 제출하지 않아요. 빌드 선택과 심사 제출은 App Store Connect에서 직접 해야 해요. 자동화하려면 앱 레코드 번호(ascAppId)와 App Store Connect API 키가 필요해요.
저는 Solys, TradaZen, Nolera 같은 iOS 앱을 Expo, EAS Build, EAS Submit으로 출시하고 있어요. 이 가이드는 Expo의 iOS 제출 문서를 따르고, 2026년 10월 25일에 다시 확인했어요. Mac이 없다면 전체 과정은 Mac 없이 iOS 앱 출시하기에 있어요. 여기서는 제출에만 집중할게요.
첫 명령어 전에 준비할 것
Expo가 제시하는 사전 조건은 세 가지예요.
- 유료 Apple Developer 계정. 가격과 가입 방법은 Apple 개발자 계정에 있어요.
ios.bundleIdentifier에 넣을 번들 ID. Expo 설정 레퍼런스에 따르면 직접 정하면 되지만, App Store 전체에서 고유해야 해요.- EAS CLI 설치 후 Expo 계정으로
eas login.
서명된 프로덕션 빌드도 필요해요. iOS 인증서와 프로비저닝 프로파일에서 설명했듯이, EAS Build가 대신 관리하는 인증서와 프로파일로 빌드를 만들어 줘요.
App Store Connect 앱 레코드: 직접 만들까, EAS에 맡길까?
EAS Submit은 App Store Connect에 이미 존재하는 앱으로 바이너리를 보내요.
직접 만들 수 있어요. Apple 도움말에 New App 창이 설명되어 있어요. 플랫폼, 이름, 기본 언어, 번들 ID, SKU, 사용자 접근 권한을 입력해요. Account Holder, Admin, App Manager 역할이 필요해요.
EAS가 첫 제출 때 만들어 줄 수도 있어요. Expo의 TestFlight 페이지에 따르면, 첫 빌드를 보낼 때 eas submit이 앱 레코드를 만들어요. eas.json 레퍼런스에 따르면 ascAppId를 입력하면 이 단계를 건너뛰어요. 이름은 appName에서, 없으면 설정의 name에서 가져와요. 기본 언어는 language에서 가져오고, 기본값은 en-US예요. 앱을 프랑스어로 먼저 출시한다면 첫 제출 전에 language를 입력하세요.
그다음 앱 레코드 번호를 ascAppId에 옮겨 적으세요. Expo가 위치를 알려 줘요. App Store Connect에서 앱을 열고 App Information으로 가세요. General Information 아래의 Apple ID 필드예요. 번들 ID가 아니라 숫자예요.
Apple ID 대신 API 키를 쓰는 이유
EAS Submit은 Apple ID 또는 App Store Connect API 키로 Apple에 연결해요.
Apple ID는 이중 인증에 막혀요. Apple은 모든 App Store Connect 사용자에게 이중 인증을 요구하기 때문에, 사람이 직접 로그인을 확인해야 해요. EXPO_APPLE_APP_SPECIFIC_PASSWORD로 넘기는 앱 암호를 쓰면 이 단계를 피할 수 있지만, Expo는 이 방법이 기본값이자 권장 방법인 API 키보다 덜 안전하다고 봐요. API 키는 아무런 상호작용 없이 인증할 수 있어서 제출을 자동화할 수 있어요.
키를 얻는 방법은 두 가지예요.
- EAS에 관리를 맡기기.
eas credentials --platform ios를 실행하고production프로필을 고른 뒤, Apple 계정에 로그인하고 "App Store Connect: Manage your API Key"를 선택하세요. - 직접 만든 키 쓰기. App Store Connect에서 Users and Access, Integrations 탭, App Store Connect API, Team Keys, 그리고 Generate API Key로 가세요. Admin 계정이 필요하고, Expo 가이드는 키에 Admin 역할을 줘요.
두 번째 방법이라면 활성 키 목록에 표시되는 Key ID와 Integrations 페이지 상단에 있는 Issuer ID를 적어 두세요. 무엇보다 .p8 파일을 잘 보관하세요. 딱 한 번만 다운로드할 수 있고, Apple은 사본을 보관하지 않아요.
Apple에 따르면 Admin 키는 계정의 사용자를 만들고 삭제할 수 있어요. Apple은 키를 절대 코드 저장소에 넣지 말라고 해요.
복사해서 쓰는 최소 eas.json
모든 값은 가짜예요. 본인 값으로 바꾸세요.
{
"cli": {
"appVersionSource": "remote"
},
"build": {
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890",
"appleTeamId": "ABCDE12345",
"ascApiKeyPath": "./keys/AuthKey_XXXXXXXXXX.p8",
"ascApiKeyIssuerId": "your-issuer-id",
"ascApiKeyId": "XXXXXXXXXX"
}
}
}
}
appVersionSource와autoIncrement: EAS 서버가 빌드 번호를 보관하고 프로덕션 빌드마다 올려요. EAS CLI 12부터 Expo는 이 원격 방식을 권장해요.ascAppId: 앱 레코드 번호예요. 없으면 비대화형 모드가 실패해요.appleTeamId: Apple Developer 팀 ID예요.ascApiKeyPath,ascApiKeyIssuerId,ascApiKeyId: API 키예요. 세 필드 모두 환경 변수를 받아요.keys폴더는.gitignore에 추가하세요.
appleId 필드는 Apple ID로 로그인할 때만 필요해요. EAS가 이미 키를 관리하고 있다면 ascApiKey 필드 세 개도 지우세요. 10월 25일에 확인해 보니, 제 앱 세 개의 프로덕션 제출 프로필에는 ascAppId만 있고 Solys에만 appleTeamId가 더 있어요. 파일 안에 키는 없어요.
빌드 후 제출하기
eas build --platform ios --profile production
eas submit --platform ios
다른 옵션 없이 실행하면 eas submit이 보낼 빌드를 고르게 하고, 처음 실행할 때 Apple ID를 물어봐요. production 제출 프로필이 있으면 기본으로 쓰여요. EAS CLI 레퍼런스에 선택 과정을 건너뛰는 옵션이 나와 있어요.
| 옵션 | 하는 일 |
|---|---|
--latest | 최신 iOS 빌드 전송 |
--id | 특정 EAS 빌드 전송 |
--path | 로컬 .ipa 파일 전송 |
--url | 온라인 아카이브 전송 |
--groups | 내부 그룹에 추가 |
--what-to-test | "What to test" 입력 |
한 번에 이어서 하려면 빌드 명령어에 --auto-submit을 붙이세요. Expo의 자동 제출 페이지에 따르면, 빌드가 끝나면 빌드 프로필과 같은 이름의 제출 프로필로 EAS Submit에 넘어가요. 다른 프로필을 쓰려면 --auto-submit-with-profile=이름을 쓰세요. 빌드는 TestFlight로 가지, 심사로 가지 않아요.
CI에서는 --non-interactive와 EXPO_TOKEN 토큰을 추가하세요. 이때 명령어는 아무것도 물어볼 수 없어요. 프로필에 ascAppId가 있어야 하고, API 키도 필요해요. EAS가 앱에 연결해 둔 키든, ascApiKey 필드 세 개에 넣은 본인 키든 상관없어요.
제출 후에 일어나는 일
1. Apple이 빌드를 처리해요. 이 처리를 거쳐야 App Store Connect에 나타나고, 끝나면 Apple이 이메일을 보내 줘요. Expo는 TestFlight에서 보이기까지 보통 10~15분 걸린다고 해요.
2. 수출 규정 준수. Missing Compliance 상태는 암호화 관련 신고가 빠졌다는 뜻이에요. Info.plist에 이미 답이 없으면 App Store Connect는 새 버전마다 이 질문을 해요. Expo에서는 키 이름이 ios.config.usesNonExemptEncryption이에요.
{
"expo": {
"ios": {
"config": {
"usesNonExemptEncryption": false
}
}
}
}
Apple에 따르면, 라이브러리를 포함해 앱이 암호화를 전혀 쓰지 않거나 면제된 암호화만 쓴다면 false가 맞아요. URLSession을 통한 HTTPS 같은 시스템 암호화는 보통 면제돼요. 앱에 실제로 해당될 때만 false로 신고하세요. 신고 내용에 대한 책임은 본인에게 있어요. Info.plist의 다른 키처럼 새 빌드가 필요해요.
3. TestFlight. Apple에 따르면 Ready to Submit 상태가 되면 빌드를 내부 테스터에게 배포하거나, 외부 테스터용 베타 심사를 받거나, App Store 심사로 보낼 수 있어요. 프로필의 groups 필드를 쓰면 내부 그룹에 추가돼요. 나머지는 모두 TestFlight로 앱 테스트하기에 있어요.
제출(업로드)은 심사 제출이 아니에요
Expo도 명시하고 있어요. TestFlight 빌드는 App Store에 자동으로 출시되지 않아요. EAS Submit은 앱 정보도, 스크린샷도 채워 주지 않아요. App Store Connect에서 할 일이 네 가지 남아 있고, 심사 제출에 관한 Apple 도움말에 설명되어 있어요.
- 버전의 필수 메타데이터를 채우세요.
- 버전의 Build 섹션에서 빌드를 고르세요.
- "Add for Review"를 클릭하세요. 버전이 Ready for Review로 바뀌지만, 아직 심사로 간 건 없어요.
- "Submit for Review"를 클릭하세요. 심사가 시작되면 상태가 In Review로 바뀌어요.
자주 나는 오류와 해결 방법
| 표시되는 오류 | 원인 | 해결 |
|---|---|---|
| ITMS-90189 | 이미 쓴 빌드 번호 | autoIncrement |
| ITMS-90062 또는 90186 | 이미 닫힌 버전 | version 올리기 |
| "Set ascAppId" | CI에서 ascAppId 없음 | ascAppId 추가 |
| "API Keys cannot" | 연결된 키 없음 | eas credentials |
| ITMS-90683 | 권한 사용 설명 누락 | ios.infoPlist |
| ITMS-91053 | 불완전한 매니페스트 | ios.privacyManifests |
| ITMS-90725 | 너무 오래된 iOS SDK | Expo SDK 올리기 |
| Missing Compliance | 암호화 미신고 | usesNonExemptEncryption |
Expo에 따르면 이미 쓴 빌드 번호는 업로드 거절의 흔한 원인이에요. 자세한 내용은 빌드 번호와 버전에 있어요. 세 가지 오류는 별도 가이드가 있어요. Expo에서 ITMS-90683, Expo에서 ITMS-91053, ITMS-90725를 보세요.
따옴표 안의 두 메시지는 EAS에서 나오고, EAS 설정에서 고쳐요. Missing Compliance는 App Store Connect에서 질문에 답해도 해결돼요. 나머지 항목은 모두 바이너리를 고쳐야 해요. 다시 빌드하고 다시 보내세요. 원격 업데이트로는 Info.plist도, 매니페스트도, 번호도 바뀌지 않아요.
헤매지 않고 첫 앱 제출하기
명령어는 한 단계일 뿐이에요. iOS Kit는 구독 기능까지 포함된 제 앱들의 시작 코드에서 출발해, 네 단계를 거쳐 App Store까지 본인 속도에 맞춰 진행해요.
첫 출시를 준비하고 있다면 무료 진단을 받아 보세요. 정말로 무엇이 막고 있는지 알려 주고, Apple 리젝 방지 체크리스트도 보내 드려요. 앱 정보, 스크린샷, 심사 통과는 App Store에 앱 출시하기 페이지에서 단계별로 다뤄요.
자주 묻는 질문
Expo 앱을 App Store에 어떻게 출시하나요?
EAS Build로 프로덕션 빌드를 만든 뒤 eas submit --platform ios로 보내세요. Apple 처리가 끝나면 TestFlight에 나타나요. 그다음 App Store Connect에서 앱 정보를 채우고, 버전에서 이 빌드를 고른 뒤 "Add for Review"와 "Submit for Review"를 클릭하세요.
EAS Submit이 앱을 Apple 심사에 제출하나요?
아니요. EAS Submit은 바이너리를 App Store Connect로 보내고, 빌드는 TestFlight에 도착해요. 심사 제출은 앱 정보를 채우고 빌드를 고른 뒤 App Store Connect에서 직접 해요.
앱의 ascAppId는 어디서 찾나요?
App Store Connect에서 앱을 열고 App Information으로 가세요. General Information 아래의 Apple ID 필드예요. 숫자이고, 번들 ID와 헷갈리면 안 돼요.
eas submit을 쓰려면 Apple ID가 필요한가요?
처음 실행할 때 명령어가 Apple ID를 물어봐요. 그 뒤로는 프로필에 ascAppId가 있고 App Store Connect API 키가 있으면 CI에서도 상호작용 없이 돌아가요. API 키는 Expo의 기본값이자 권장 방법이에요.
TestFlight에서 빌드가 보이기까지 얼마나 걸리나요?
Expo는 Apple 쪽 처리에 보통 10~15분 걸린다고 하고, 끝나면 Apple이 이메일을 보내 줘요. 빌드가 Missing Compliance 상태에 머물러 있다면 암호화 질문에 답하고, 다음 빌드부터는 설정에 신고해 두세요.