Flutter Flavors: Полное руководство по нескольким средам в Android и iOS

Flutter Flavors: Полное руководство по нескольким средам в Android и iOS

FlutterPulse

Эта статья переведена специально для канала FlutterPulse. В этом канале вы найдёте много интересных вещей, связанных с Flutter. Не забывайте подписываться! 🚀

Настройте флейворы Flutter для разработки, тестовой среды и продакшена с пользовательскими иконками, названиями и конфигурациями — всё из одного кода.

Флейворы — это нативные конфигурации, которые позволяют создавать несколько версий одного приложения из одного кода — каждая со своими иконками, названиями, конфигурациями и поведением.

Основная цель — изолировать разные среды — разработка (dev), тестирование (stg) и продакшен (prod) — чтобы тестирование, валидация и развертывание были более независимыми и организованными.

С флейворами вы можете устанавливать и тестировать несколько вариантов приложения на одном устройстве, распространять их через магазины приложений или платформы тестирования, такие как Firebase Distribution, и они могут существовать без перезаписи друг друга.

В этой статье я проведу вас через пошаговую настройку флейворов dev, stg и prod в приложении Flutter для Android и iOS.

Оглавление

Флейворы на AndroidФлейворы на iOSОтображение баннера флейвора в приложенииНастройка VSCode

Флейворы на Android

1. Настройте build.gradle

В вашем проекте Flutter откройте файл android/app/build.gradle и внутри блока android добавьте конфигурацию флейворов:

android {
...
flavorDimensions "env"

productFlavors {
stg {
dimension "env"
applicationIdSuffix ".stg"
versionNameSuffix "-stg"
resValue "string", "app_name", "App STG"
}
dev {
dimension "env"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
resValue "string", "app_name", "App DEV"
}
prod {
dimension "env"
resValue "string", "app_name", "App"
}
}
}
  • applicationIdSuffix: Суффикс, добавляемый к идентификатору приложения. Приложение с идентификатором com.example.app собранное с флейвором dev становится com.example.app.dev.
  • resValue: Назначает уникальное название приложения для каждого флейвора.

Замените App, App DEV и App STG на соответствующее название для каждого флейвора вашего приложения.

2. Редактирование AndroidManifest

Откройте файл android/app/src/main/AndroidManifest.xml и обновите свойство android:label:

...
<application
android:label="@string/app_name"

Готово! Теперь ваше приложение имеет настроенные флейворы, и вы можете протестировать его, запустив:

flutter run --flavor dev

3. Создание иконок приложения

Теперь давайте создадим разные иконки для каждого флейвора.

В Android Studio откройте папку android.

Переключите режим просмотра на Project.

Внутри app/src, создайте следующие папки: dev/res и stg/res.

Щелкните правой кнопкой мыши по папке res, которую вы только что создали, и перейдите в New > Image Asset.

Импортируйте иконку, отрегулируйте её размер и сохраните.

Повторите этот процесс для каждого флейвора. Учтите, что иконки для флейвора prod остаются в папке по умолчанию main/res/.

Теперь, при запуске приложения на устройстве Android, каждый флейвор будет отображать свою иконку.

Флейворы на iOS

  1. Создайте схемы

Откройте файл ios/Runner.xcworkspace с помощью Xcode.

В верхнем меню перейдите в: Product -> Scheme -> Manage Schemes.

Нажмите кнопку + и создайте схемы dev и stg:

Переименуйте существующую схему Runner в prod.

Теперь, в левой панели, нажмите на Runner, и под PROJECT, выберите Runner снова. Перейдите на вкладку Info и нажмите кнопку + для добавления новой конфигурации сборки.

Вам нужно дублировать существующие конфигурации Debug, Release и Profile, создавая набор для каждого флейвора.

Переименуйте их в соответствии с каждым флейвором, например: Debug-prod, Release-dev, Profile-stg. В итоге результат будет таким:

Далее, вернитесь к Product -> Scheme -> Manage Schemes, выберите схему и нажмите Edit.

Для каждой схемы флейвора выберите соответствующие конфигурации сборки в левой боковой панели.

  • Для prod, выберите конфигурации, заканчивающиеся на -prod
  • Для dev, используйте те, что заканчиваются на -dev
  • Для stg, те, что заканчиваются на -stg

Повторите это для всех схем.

2. Редактирование bundle.id

Нажмите на Runner под TARGETS, затем перейдите в Build Settings. Поищите "bundle", чтобы найти раздел Packaging.

Добавьте соответствующий суффикс к Bundle Identifier для каждого флейвора:

  • .dev для разработки
  • .stg для staging
  • Оставьте без изменений для продакшена

После этого у каждого флейвора будет уникальный идентификатор, как в примере:

3. Изменить отображаемое имя приложения

Всё ещё внутри TARGETS → Runner, перейдите на вкладку Info. Измените значение Bundle display name на: $(APP_DISPLAY_NAME)

Теперь перейдите в Build Settings, нажмите + и выберите Add User-Defined Setting.

Определите одно значение для каждой сборки. В итоге настройка должна выглядеть примерно так:

Теперь вы можете запустить приложение с помощью: flutter run --flavor dev.

4. Создать иконки приложения

В iOS иконки приложения требуют нескольких размеров. Ручное их создание занимает много времени, поэтому вы можете использовать платформу AppIcon для упрощения процесса.

  • Загрузите свою иконку
  • Выберите iPhone (и iPad, если нужно)
  • Скачайте сгенерированный zip-архив

Внутри скачанной папки скопируйте AppIcon.appiconset из AppIcons/Assets.xcassets.

Вставьте её в свой проект по адресу: ios/Runner/Assets.xcassets/

Переименуйте папку в соответствии с каждой сборкой:

  • AppIcon-dev.appiconset
  • AppIcon-stg.appiconset
  • Оставьте стандартное имя для prod

Затем вернитесь в Xcode. Под TARGETS → Runner → Build Settings, найдите "primary". Вы найдёте настройку Primary App Icon Set Name.

Установите имя для каждой сборки (например, AppIcon-dev). Оставьте стандартное для prod.

Итоговый результат будет таким:

Теперь, когда вы запускаете приложение на iOS-симуляторе или устройстве, каждый флейвор будет отображать свой собственный значок.

Отображение баннера флейвора в приложении

Теперь мы покажем баннер внутри приложения, указывающий, запущено ли оно под флейвором dev или stg.

На данный момент у вас есть два варианта:

  • Использовать один файл main.dart, или
  • Использовать отдельные точки входа (main_dev.dart, main_stg.dart, и т.д.)

Мы рассмотрим оба подхода.

  1. Одиночный файл main.dart

В этом подходе мы передаем флейвор в приложение с помощью параметра --dart-define, как показано ниже:

flutter run --flavor dev --dart-define=FLAVOR=dev

Вот как будет выглядеть файл main.dart:

void main() {
const flavor = String.fromEnvironment('FLAVOR', defaultValue: 'prod');

runApp(
const App(flavor: flavor),
);
}

Теперь мы можем отображать баннер на основе текущего флейвора:

class App extends StatelessWidget {
const App({
super.key,
required this.flavor,
});

final String flavor;

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
debugShowCheckedModeBanner: false,
home: flavor != 'prod'
? Banner(
message: flavor.toUpperCase(),
location: BannerLocation.topStart,
color: Color(0xFF2D808D),
child: const HomePage(),
)
: const HomePage(),
);
}
}

Здесь мы применяем логику: если флейвор не prod, баннер будет отображаться.

2. Несколько файлов main.dart

В этом подходе мы оставляем файл main.dart в качестве точки входа для prod и создаем отдельные файлы для других флейворов, такие как main_dev.dart и main_stg.dart.

Каждый файл жестко закодирован для соответствующего флейвора:

void main() {
runApp(
const App(flavor: 'dev'),
);
}

Для запуска приложения используйте:

flutter run --flavor dev -t lib/main_dev.dart.

Настройка VSCode

Чтобы отлаживать приложение с помощью VSCode с разными вариантами, необходимо правильно настроить файл launch.json.

Настройка зависит от того, используете ли вы один файл main.dart или отдельные точки входа для каждого варианта.

В вашем проекте откройте файл: .vscode/launch.json.

Если вы используете один файл main.dart:

{
"version": "0.2.0",
"configurations": [
{
"name": "App",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"prod",
]
},
{
"name": "App Dev",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"dev",
"--dart-define",
"FLAVOR=dev"
]
},
{
"name": "App Stg",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"stg",
"--dart-define"
"FLAVOR=stg"
]
}
]
}

Или если вы используете несколько файлов main.dart:

{
"version": "0.2.0",
"configurations": [
{
"name": "App",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"prod",
]
},
{
"name": "App Dev",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"dev",
"-t",
"lib/main_dev.dart",
]
},
{
"name": "App Stg",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"stg",
"-t",
"lib/main_stg.dart",
]
}
]
}

Теперь мы завершили полную настройку вариантов Flutter — мощной функции, которая позволяет изолировать различные среды, делая тестирование, проверку и развертывание более организованными и эффективными.

Хотя это нативная функция платформы, варианты работают плавно с Flutter при правильной настройке, позволяя гибридным приложениям в полной мере использовать эту возможность с помощью пользовательских иконок, имен, поведения и разделения сред.

Report Page