iOS 앱 빌드 — Xcode · 서명 · TestFlight
iOS 앱 빌드 — Xcode · 서명 · TestFlight
iOS 앱 빌드는 Android 와 비슷한 단계 (컴파일 → 자원 묶기 → 서명 → 패키지) 를 거치지만, 도구 · 배포 통로 · 정책의 모양이 꽤 다릅니다. 가장 큰 차이는 macOS 와 Apple Developer Program 이 사실상 강제된다는 점. 이 글은 Xcode 와 xcodebuild · 인증서 · 프로비저닝 프로파일 · 서명 모드 · TestFlight · App Store 심사 · Tauri / Flutter / RN 의 iOS 빌드 차이.
1. iOS 빌드의 표면
| 사건 | 시기 |
|---|---|
| Xcode 1.0 (Mac OS X) | 2003 |
| iPhone SDK 공개 | 2008 |
| App Store 출시 | 2008 |
| TestFlight 인수 (Apple) | 2014 |
| App Tracking Transparency (ATT) | 2021 (iOS 14.5) |
| Notarization · Privacy Manifest 강화 | 2024 ~ |
도구:
- Xcode — 통합 IDE + 빌드 시스템 + 시뮬레이터.
- xcodebuild — 명령줄 빌드 도구. Xcode 와 함께 설치.
- Xcode CLI Tools — Xcode 의 명령줄만 따로 설치 (
xcode-select --install). gcc / clang / git 의 mac 표준 진입점. - Apple Developer Program — 연 99 USD. 실기 디바이스 배포 · App Store 등록의 자격.
# Mac 만 가능 (iOS 빌드는 macOS 필수)
xcode-select --install
xcodebuild -version
2. 빌드 흐름
.swift / .m → swiftc / clang → .o
.storyboard · .xcassets → 컴파일 → asset catalog
Info.plist · entitlements → 병합
링크 → 실행 바이너리
↓
.app 번들 (디렉터리 모양의 패키지)
↓
서명 (codesign)
↓
.ipa (zip 포장된 .app)
Android 의 APK 가 ZIP 안에 DEX · 자원 · 매니페스트를 담는 것과 비슷. iOS 의 .ipa 는 기본적으로 Payload/MyApp.app 디렉터리를 zip 으로 묶은 모양.
Bundle Identifier — 앱의 전역 ID. 보통 reverse-DNS 모양 (com.example.myapp). 한 번 App Store 에 등록되면 변경이 거의 불가능. Apple Developer 콘솔의 App ID 와 매핑.
Info.plist · entitlements:
| 파일 | 의미 |
|---|---|
Info.plist |
번들 메타 (이름 · 버전 · 아이콘 · 필수 디바이스 기능 · 권한 설명) |
*.entitlements |
앱이 사용하는 보안 기능 (iCloud · Push · Sign in with Apple) |
ATT (앱 추적 투명성, iOS 14.5+) 도입 후 IDFA 사용은 NSUserTrackingUsageDescription 키 + 런타임 동의 필수.
3. 서명
iOS 의 서명 모델은 Android 보다 더 많은 객체가 얽힘.
인증서 (Certificate) — Apple 이 발급하는 개발자 인증서:
- Development Certificate — 디바이스에 직접 설치할 때.
- Distribution Certificate — TestFlight · App Store · Ad Hoc 배포.
키 페어를 macOS Keychain 에서 만들어 CSR 을 Developer 콘솔에 올리는 흐름이 표준.
App ID — Apple 콘솔에 등록된 앱의 식별. Bundle Identifier 와 매핑. com.example.myapp 또는 와일드카드 com.example.*.
Device — Ad Hoc · Development 배포 시 등록된 디바이스 UDID 만 설치 가능. 한 계정당 등록 디바이스 수에 한도 (연 100 개 정도).
Provisioning Profile — 위 세 가지 (인증서 · App ID · 디바이스) 를 묶은 파일 (.mobileprovision). 빌드된 .app 에 함께 포장돼 디바이스가 설치 시 검증:
| Profile 타입 | 용도 |
|---|---|
| Development | 등록 디바이스에 직접 설치 |
| Ad Hoc | 등록 디바이스에 배포 |
| App Store | App Store · TestFlight 배포 |
| Enterprise | 기업 내부 배포 (일반 개발자 계정과 별도) |
Automatic vs Manual Signing — Xcode 의 "Automatically manage signing" 을 켜면 인증서 · 프로파일 발급 · 갱신이 자동. CI 에서는 수동 모드를 쓰는 자리가 많음. 수동 흐름은 보통 fastlane match 같은 도구로 인증서 · 프로파일을 git repo 에 (암호화) 동기화.
4. 배포 채널
TestFlight — Apple 의 베타 배포 시스템. 내부 100 명, 외부 10000 명까지 초대 가능. 외부 베타는 첫 빌드에 짧은 심사.
App Store Connect — App Store 등록 · 심사 콘솔. 메타데이터 · 스크린샷 · 심사 노트 · 가격 · 공개 일정. 빌드 자체는 Xcode 또는 Transporter 로 업로드.
Ad Hoc — App Store 를 거치지 않고 등록 디바이스 100 대까지 직접 배포. 사내 시연 · 사용자 시범.
Enterprise — 일반 Developer Program 과 별도의 Enterprise Program (연 299 USD, 심사 후 가입). 사내 직원에게 App Store 외부 배포 가능. 외부 공개 용도가 발견되면 자격 박탈.
5. App Store 심사
심사 가이드라인의 큰 줄기:
- 기능 안전성 — 충돌 · 치명적 버그 없음, 약속된 기능 동작.
- 메타데이터 정확성 — 스크린샷 · 설명이 실제 앱과 일치.
- 사생활 · 권한 — 권한 요청에 명확한 사용 이유. ATT · PII 보호.
- 결제 — 디지털 콘텐츠는 원칙적으로 IAP (In-App Purchase, 30% / 15% 수수료). 물리 상품 · 일부 외부 결제 자리는 예외.
- 특정 카테고리 정책 — 어린이 · 헬스 · 금융 · 도박은 추가 요구사항.
심사 거절 시 사유 통지 후 수정 재제출. 평균 심사 시간은 24 ~ 48 시간 안에 끝나는 흐름이 자주 보고되지만 시기에 따라 변동.
6. 크로스플랫폼 도구의 iOS 빌드
Tauri Mobile · Flutter · React Native 모두 결국 같은 Xcode + xcodebuild 흐름:
- 자체 코드 (Rust · Dart · JS) 를 컴파일 또는 번들.
- Xcode 프로젝트 (
ios/디렉터리) 를 자동 생성 · 관리. xcodebuild archive·xcodebuild -exportArchive로.ipa산출.- 인증서 · 프로파일은 Xcode 또는 fastlane 으로 관리.
| 도구 | 메모 |
|---|---|
| Tauri 2 (mobile) | Rust + WebView. Xcode 프로젝트 자동 생성. 비교적 신생. |
| Flutter | Dart + Skia / Impeller. iOS 빌드 안정. fastlane 통합 흔함. |
| React Native | JS + 네이티브 브리지. CocoaPods 의존성. EAS Build (Expo) 가 표준 자리. |
iOS 빌드에서 macOS 가 사실상 강제되는 점은 모든 도구에 공통. Linux / Windows 에서 iOS 를 빌드하려는 시도는 매우 제한적 (Cirrus CI · MacStadium · GitHub Actions 의 macOS runner 같은 우회).
7. 자주 쓰는 모양
CLI 빌드:
# Mac
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-archivePath build/MyApp.xcarchive archive
xcodebuild -exportArchive \
-archivePath build/MyApp.xcarchive \
-exportOptionsPlist ExportOptions.plist \
-exportPath build/
# Windows: 직접 빌드 불가. macOS runner (GitHub Actions · self-hosted) 사용.
TestFlight 업로드:
# Mac (Transporter CLI)
xcrun altool --upload-app -f build/MyApp.ipa \
-u "you@apple.id" -p "@keychain:AC_PASSWORD"
fastlane (iOS · Android 배포 자동화의 표준 도구. Ruby gem):
lane :beta do
match(type: "appstore")
build_app(workspace: "MyApp.xcworkspace", scheme: "MyApp")
upload_to_testflight
end
match 가 인증서 · 프로파일을 git 저장소에 암호화 보관해 팀 · CI 에서 공유.
CI 매트릭스:
- GitHub Actions —
macos-latest러너. 시간당 단가. - CircleCI · Bitrise · Codemagic — iOS 빌드 친화 호스팅.
- 자체 Mac mini · MacStadium — 안정적 비용 통제.
8. 자주 걸리는 자리
인증서 만료 — Distribution 인증서는 보통 1 년 유효. 만료 후 새 .ipa 를 만들 수 없음. 재발급 후 모든 프로파일 갱신.
프로비저닝 프로파일 누락 — 빌드 .app 의 entitlements 와 프로파일이 일치해야 함. 불일치 시 디바이스 설치 단계에서 거부.
Bundle ID 변경 불가 — 앱 출시 후 변경 사실상 불가. 새 앱으로 등록.
iOS 버전 호환 — IPHONEOS_DEPLOYMENT_TARGET 이 너무 낮으면 일부 API 의 런타임 분기 필요. 너무 높으면 사용자 범위 좁아짐.
ATT 누락 — IDFA 를 사용하는 SDK 가 있는데 사용 설명 미기재 → 거절. AdMob · 광고 SDK 사용 시 점검.
Privacy Manifest (2024 ~) — 일부 SDK 가 Privacy Manifest 첨부 필수. 누락 시 거절.
암호화 신고 — Info.plist ITSAppUsesNonExemptEncryption. HTTPS 만 쓰면 보통 면제.
CocoaPods · SwiftPM 충돌 — 한 프로젝트에서 두 의존성 관리자가 같이 쓰일 때 충돌. 점진적 SPM 이전 흐름.
하고픈 말
iOS 빌드는 macOS + Apple Developer Program + 인증서 / 프로파일 / 디바이스의 다층 모델 + App Store 심사 + ATT / Privacy Manifest 등의 정책으로 운영 부담이 Android 보다 높음. fastlane match 가 팀 · CI 자동화의 표준이고, 매년 인증서 만료 · 정책 갱신이 정기 자리. 사업 가치가 명확한 시점에 진입.
Next
- (mobile 끝)
Apple Developer Documentation · App Store Review Guidelines · Xcode Help · TestFlight · fastlane 공식 · Transporter · Tauri Mobile · Flutter iOS 배포 를 참고합니다.