Настройка Flavors/Schemes для разных версий мобильного приложения
Один репозиторий, несколько приложений. White-label продукт для трёх клиентов. Бесплатная и платная версия с разными пакетами и иконками. Staging-сборка для QA с другим bundle ID, которую можно установить рядом с продакшн-версией. Это всё — задача для Product Flavors (Android) и Schemes/Targets (iOS).
Android: Product Flavors
Product Flavors в Android создают отдельные варианты приложения с разными applicationId, ресурсами, кодом и зависимостями.
android {
flavorDimensions += listOf("environment", "tier")
productFlavors {
create("dev") {
dimension = "environment"
applicationIdSuffix = ".dev"
versionNameSuffix = "-dev"
resValue("string", "app_name", "MyApp Dev")
}
create("staging") {
dimension = "environment"
applicationIdSuffix = ".staging"
versionNameSuffix = "-staging"
resValue("string", "app_name", "MyApp Staging")
}
create("production") {
dimension = "environment"
}
create("free") {
dimension = "tier"
applicationIdSuffix = ".free"
}
create("paid") {
dimension = "tier"
}
}
}
Матрица вариантов: devFreeDebug, devPaidRelease, productionFreeRelease, и т.д. Обычно используют только нужные комбинации и явно указывают остальные через variantFilter.
Ресурсы по flavors хранятся в src/dev/res/, src/staging/res/, src/production/res/. Kotlin-код, специфичный для flavor — в src/dev/kotlin/ и т.д.
iOS: Targets и Schemes
В iOS роль Flavors играет комбинация Targets + Schemes + xcconfig.
Один target, несколько Schemes + Build Configurations — для случая staging/production:
- Создаём конфигурации: Debug, Staging, Release
- Создаём Schemes: MyApp, MyApp-Staging
- Каждый Scheme запускает нужную Configuration
Несколько Targets — для white-label или существенно отличающихся версий (разный код, разные capabilities):
- Каждый Target имеет свой
PRODUCT_BUNDLE_IDENTIFIER, иконку, Info.plist - Общий код → Shared framework или просто общие файлы, добавленные в оба Target
- Подход тяжелее в поддержке, но даёт максимальный контроль
Targets:
MyApp → com.myapp.ios → AppIcon → Release.xcconfig
MyApp-ClientB → com.clientb.myapp → AppIconClientB → ClientB.xcconfig
MyApp-Staging → com.myapp.ios.staging → AppIconStaging → Staging.xcconfig
Flutter: Flavors
Flutter поддерживает flavors нативно, под капотом они маппятся на Android Product Flavors и iOS Schemes:
flutter run --flavor staging -t lib/main_staging.dart
flutter build apk --flavor production -t lib/main_production.dart
main_staging.dart инициализирует приложение с staging-конфигурацией, main_production.dart — с production. Конфиг передаётся через --dart-define или через отдельный app_config.dart на каждый flavor.
В pubspec.yaml можно использовать flutter_flavorizr для генерации boilerplate — создаёт нужные Targets/Schemes на iOS и Product Flavors на Android из одного конфиг-файла.
Типичные ошибки
- Добавление нового flavor без обновления CI — пайплайн собирает только старые варианты
- Дублирование кода вместо использования
src/<flavor>/overlay — maintainability падает - Разные
versionCode/CFBundleVersionдля разных flavors одного релиза — путаница в тестировании
Процесс
Аудит требований к вариантам → выбор подхода (Flavors vs Targets) → создание структуры ресурсов → настройка CI для сборки нужных вариантов → тест установки рядом друг с другом → документация.
Срок: 2–3 дня для стандартной схемы, до 5 дней для white-label с несколькими брендами. Стоимость рассчитывается индивидуально.







