Представьте: ваш финтех-стартап выпускает white-label приложение для трёх банков. У каждого — свой дизайн, свой API endpoint, свой бандл. При этом QA нужно тестировать staging без риска задеть production данные. Без правильной настройки Flavors/Schemes вы получите путаницу с package name и невозможность установить две версии рядом. Мы решаем эту задачу за 2–5 дней, используя Product Flavors (Android), Schemes/Targets (iOS) и конфигурации Flutter. За 5 лет выполнили более 30 проектов — от финтеха до b2b-white-label. Гарантируем, что после настройки вы сможете устанавливать все версии одновременно на одно устройство, не опасаясь конфликтов.
Как настроить Flavors на разных платформах?
Android: Product Flavors — настройка flavor scheme
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. Apple Developer Documentation рекомендует такой подход для разделения конфигураций.
Один 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 из одного конфиг-файла.
Что выбрать: один Target или несколько?
Ответ зависит от объёма отличий. Если разница только в bundle ID, API-endpoint и иконке — достаточно одного Target с несколькими Schemes. Если нужен разный код, разные push-капабилити (APNs/FCM) или third-party SDK — берите несколько Target (iOS) / flavorDimensions (Android). На Android с flavorDimensions легко комбинировать free vs paid и staging vs production одновременно. По нашим замерам, один Target с несколькими Schemes в 3 раза быстрее в настройке, чем несколько Target.
Почему разделение конфигураций экономит время и нервы?
Представьте: QA тестирует staging-сборку, случайно удаляет production-базу? С разными bundle ID это невозможно — приложения воспринимаются системой как разные. Dev-версия стоит рядом с production, и вы можете мгновенно сравнить поведение. Кроме того, в App Store Review Guidelines (Section 4.2) требуется, чтобы тестовая версия не смешивалась с продуктивной. Мы это учитываем.
Пример из практики: white-label для сети кофеен
Настроили 4 бренда с разными иконками, цветами и API-ключом Geopush. Использовали 2 flavorDimensions (brand, environment) на Android и 4 Targets на iOS. CI собрал релиз за 3 дня. Экономия времени на каждое обновление — 40%.Типичные ошибки при настройке Flavors
| Ошибка | Последствие | Решение |
|---|---|---|
| Новый flavor без обновления CI | Сборка не появится в пайплайне | Добавить lane в Fastlane |
| Дублирование кода | Снижение maintainability | Использовать src/ |
| Разные versionCode для одних flavor | Путаница в версиях | Централизованное управление версиями |
Процесс работы
- Аудит требований к вариантам (сколько версий, какие отличия, кто будет собирать)
- Выбор подхода: Flavors vs Targets vs комбинированный
- Создание структуры ресурсов и кода (resource overlays, конфигурационные файлы)
- Настройка CI (Fastlane + GitHub Actions / GitLab CI) для сборки всех вариантов
- Тест установки рядом друг с другом (проверка, что не пересекаются по package name)
- Документирование процесса добавления новой версии
Сравнение платформ
| Критерий | Android (Product Flavors) | iOS (Targets + Schemes) |
|---|---|---|
| Сложность настройки | Низкая (через Gradle) | Средняя (через Xcode Project) |
| Поддержка нескольких версий | Отлично (flavorDimensions) | Хорошо (но Targets требуют синхронизации) |
| White-label (разные бренды) | Легко (разные ресурсы в папках) | Тяжелее (нужен Shared framework) |
| CI/CD интеграция | Просто (Gradle task) | Средне (Fastlane + xcodebuild) |
| Проверка App Store | Не требуется | Нужно отдельное внимание для каждого Target |
Сроки и стоимость
Срок: 2–3 дня для стандартной схемы (staging/production), до 5 дней для white-label с несколькими брендами. Стоимость рассчитывается индивидуально после аудита. Получите консультацию — свяжитесь с нами, оценим ваш проект и предложим оптимальное решение.
Закажите настройку flavors под ключ — ваш проект будет готов к масштабированию без архитектурных конфликтов.







