구성 관리는 모바일 개발에서 가장 과소평가된 측면 중 하나입니다. CloudBees(2025)에 따르면, 프로덕션 인시던트의 47%가 잘못된 빌드 구성과 관련되어 있습니다. Build Variant, Scheme 및 .env 파일의 올바른 설정은 안정적인 CI/CD와 예측 가능한 릴리스의 핵심입니다.
핵심 요점
Build Variant — Build Type(debug/release/staging)과 Product Flavor(free/paid, demo/full)의 조합입니다. Gradle은 각 조합에 대해 자동으로 variant를 생성합니다: freeDebug, freeRelease, paidDebug, paidRelease. 각 variant는 고유한 코드, 리소스 및 종속성을 가질 수 있습니다 — 이것이 Android 모바일 앱의 구성 관리 기반입니다.
Build Type — 빌드 설정: 디버깅 활성화 여부, 서명, ProGuard 최적화. debug는 기본적으로 debuggable=true를 포함하고, release는 minifyEnabled=true를 포함합니다.
Product Flavor — 앱 변형: 무료(free), 유료(paid), 데모(demo). Flavor는 다른 applicationId, 리소스, SDK 종속성을 가질 수 있습니다.
// build.gradle — Android 제품 flavor 구성
android {
productFlavors {
free {
applicationId "com.example.app.free"
versionName "1.0-free"
}
paid {
applicationId "com.example.app.paid"
versionName "1.0-paid"
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
}
}
예제는 free와 paid 두 개의 flavor를 생성합니다. free에는 별도의 applicationId가 설정되어 있습니다 — 이를 통해 한 기기에 두 앱을 모두 설치할 수 있습니다. BuildConfig는 각 variant에 대해 생성됩니다: BuildConfig.FLAVOR = "free", BuildConfig.BUILD_TYPE = "debug". 조건부 로직을 위해 코드에서 BuildConfig를 사용하세요.
settings.gradle — 프로젝트 모듈을 설명하는 루트 Gradle 파일입니다.
Gradle KTS — Kotlin DSL을 사용하는 Groovy의 대안입니다. KTS는 Android Studio에서 자동 완성 및 타입 검사를 제공합니다. 새 프로젝트에 권장됩니다.
iOS의 구성 관리는 Scheme을 기반으로 합니다 — 무엇을, 어떻게 빌드할지 정의하는 Xcode 구성입니다: Build Configuration(Debug/Release), 테스트, 분석, 아카이빙. Scheme은 다른 환경(Development, Staging, Production)용으로 복제할 수 있습니다. Scheme은 xcshareddata 폴더의 .xcscheme 파일에 저장됩니다.
.xcconfig — 빌드 설정을 텍스트 형식으로 저장하는 Xcode 구성 파일입니다. 모바일 앱 구성 관리를 위해 iOS는 .xcconfig를 사용합니다: Git에서 버전 관리, 프로젝트 간 재사용, 수동 설정 감소. .xcconfig에서 SWIFT_ACTIVE_COMPILATION_CONDITIONS, PRODUCT_BUNDLE_IDENTIFIER, CODE_SIGN_IDENTITY를 설정합니다.
Info.plist — 앱 메타데이터 파일입니다. 버전, 식별자, 권한을 저장합니다. Info.plist는 Build Settings의 Info.plist File을 통해 각 Scheme마다 다를 수 있습니다.
AndroidManifest.xml — Android의 해당 항목: 권한, 구성 요소, 메타데이터를 저장합니다.
Scheme — 빌드 시나리오(무엇을 할지). Build Configuration — 설정 세트(어떻게 할지). 하나의 Scheme은 하나의 Build Configuration(Debug 또는 Release)을 사용합니다. CI/CD의 경우: 동일한 Scheme에서 Archive 작업을 Release로, Test 작업을 Debug로 구성하세요.
pubspec.yaml — Flutter 프로젝트 구성 파일입니다. 종속성, 버전, 리소스를 포함합니다. --dart-define을 통해 환경 변수를 지원합니다.
Podfile — iOS용 CocoaPods 종속성 관리자입니다. 라이브러리 버전과 플랫폼을 정의합니다.
.env — 모든 플랫폼의 환경 변수가 포함된 파일입니다. Flutter와 React Native는 구성 관리에 다른 접근 방식을 사용합니다: Flutter의 dart-define, React Native의 react-native-config. 크로스 플랫폼 프로젝트의 구성 관리는 스택에 따라 다른 도구를 포함합니다.
.env — 키=값 쌍의 텍스트 파일입니다. Git에 커밋하지 마세요(.gitignore에 추가). Flutter의 경우 — flutter_dotenv, iOS의 경우 — #include가 있는 Config.xcconfig, Android의 경우 — BuildConfig. env 변수: API_URL, SENTRY_DSN, APP_SECRET. 모바일 개발 구성 관리에서 .env는 리포지토리 외부에 시크릿을 저장하는 사실상의 표준입니다.
Podfile은 CocoaPods 종속성과 플랫폼을 설명합니다(platform :ios, '15.0'). Flutter용 pubspec.yaml — dependencies 및 dev_dependencies. 둘 다 조건부 종속성을 지원합니다: pod 'Analytics', :configs => ['Release'] 또는 flutter pub add --flavor free. IT Sectr에서는 모바일 프로젝트에서 시크릿용으로 .env + BuildConfig를, 네이티브 종속성용으로 Podfile을 사용합니다.
| 매개변수 | Android | iOS | Flutter |
|---|---|---|---|
| 구성 단위 | Build Variant | Scheme | Flavor (--flavor) |
| 빌드 파일 | build.gradle | .xcconfig | pubspec.yaml |
| 조건부 코드 | BuildConfig | Active Compilation Conditions | dart-define |
| 시크릿 | BuildConfig/NDK | .xcconfig | .env/dart-define |
| 종속성 관리자 | Gradle(Maven) | SPM/CocoaPods | pub(dart) |
표는 모바일 플랫폼 간 구성 관리의 주요 차이점을 보여줍니다. Android는 Build Variant를 통해 더 많은 유연성을 제공합니다. iOS는 더 간단하지만 유연성이 떨어집니다. Flutter는 dart-define에 구성을 중앙 집중화하지만, 네이티브 종속성에는 여전히 Podfile/build.gradle 구성이 필요합니다.
조건부 컴파일 — 플래그에 따라 컴파일 시 코드를 포함하거나 제외합니다. 이는 구성 관리의 일부입니다: 디버그 빌드에 디버깅 도구(로깅, 인스펙터)를 포함하고 릴리스에서 제거할 수 있습니다. 구현은 플랫폼마다 다릅니다.
#if DEBUG — Swift 전처리기 지시문입니다. 블록 내의 코드는 Debug 구성에서만 컴파일됩니다. 다른 플래그: #if !RELEASE, #if targetEnvironment(simulator). Build Settings의 Active Compilation Conditions — -D FLAG_NAME을 통해 사용자 정의 플래그를 추가하세요. 컴파일 조건을 통한 빌드 구성 관리는 iOS의 표준 관행입니다.
BuildConfig.DEBUG — 부울 필드, 디버그 빌드에서 true입니다. BuildConfig는 Gradle이 자동으로 생성합니다. 사용자 정의 플래그의 경우 build.gradle에서 buildConfigField를 사용하세요: buildConfigField "boolean", "REPORT_CRASHES", "true". 코드에서: if (BuildConfig.REPORT_CRASHES) { ... }.
dart-define — Flutter 컴파일 플래그: flutter run --dart-define=ENV=staging. 코드에서: const env = String.fromEnvironment('ENV', defaultValue: 'production'). 조건부 모바일 앱 빌드의 경우 코드 생성을 통해 build_runner 플러그인을 사용하세요.
자주 묻는 질문
Build Variant = Build Type(debug/release) + Product Flavor입니다. Flavor는 앱 변형(유료/무료, 클라이언트/서버)이고, Build Type은 빌드 설정(디버그/최적화)입니다. flavour + type의 조합이 variant를 형성합니다: 예를 들어, paidDebug.
.xcconfig는 빌드 설정을 텍스트 형식으로 저장하는 Xcode 구성 파일입니다. Xcode 프로젝트에서 설정을 Git 친화적인 파일로 이동하여 모바일 프로젝트의 CI/CD와 팀 작업을 간소화합니다.
API 키는 코드에 저장해서는 안 됩니다 — 모든 .apk 또는 .ipa는 디컴파일될 수 있습니다. .env 파일, 백엔드 프록시 또는 Build Config를 통한 난독화를 사용하세요. IT Sectr은 서버에 시크릿을 저장하고 인증 후 클라이언트에 발급하는 것을 권장합니다.
조건부 컴파일은 플래그에 따라 컴파일 시 코드를 포함/제외하는 것입니다. Swift에서는 #if DEBUG, Kotlin에서는 BuildConfig.DEBUG입니다. 디버그에서 로깅을 활성화하고 릴리스에서 비활성화하는 데 사용됩니다. 이는 모바일 개발의 구성 관리 핵심 요소입니다.
Podfile은 CocoaPods 작업 시에만 사용됩니다. SPM 또는 Carthage에는 필요하지 않습니다. CocoaPods를 포기한 경우 프로젝트에 Podfile을 남기지 마세요 — 팀과 CI/CD 시스템을 혼란스럽게 합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.