DEV Community

Cover image for Flutter Flavors: Guía completa de implementación para proyectos multicliente en Android e iOS
David Gonzalez Iñiguez
David Gonzalez Iñiguez

Posted on

Flutter Flavors: Guía completa de implementación para proyectos multicliente en Android e iOS

📃 Índice

  1. ⏭️ Introducción
  2. 🎨 Creación de Flavors
  3. 🚀 Launch.json
  4. 🧩 Assets y Variables de aplicación
  5. 📱 Launcher Icon
  6. 🖼️ Splash Screen
  7. 🔥 Configuración de Firebase
  8. 🆔 Package Name / BundleId
  9. 🏷️ Nombre de Aplicación
  10. 🔢 Número de Versión
  11. 🔑 Cuenta de AppleID y Team
  12. 🛠️ Ejecución y Compilación
  13. 📫 Contacto

⏭️ Introducción

En proyectos de desarrollo con múltiples clientes o entornos, es esencial contar con una estructura que permita manejar configuraciones diferenciadas sin duplicar el código base. En Flutter, esto se logra mediante Flavors, una técnica que facilita la administración de distintas versiones de una misma aplicación, ya sea para entornos de desarrollo (development, staging, production) o para clientes específicos.

Esta guía es aplicable a cualquier proyecto Flutter que busque implementar flavors, tanto para entornos de desarrollo internos como para productos entregables a distintos clientes.

Empecemos.


🎨 Creación de Flavors

Dentro de Flutter, los flavors se configuran principalmente en los archivos de plataforma (iOS y Android).

Android

  • Abre el archivo android/app/build.gradle.

  • Si has creado el proyecto con very_good_cli (opción que recomiendo), verás una sección donde ya están definidos los productFlavors (development, production, staging). Si no lo están, crea dicha sección dentro de android { … }.

  • Aquí configuraremos los flavors específicos para cada cliente y/o entorno.

ℹ️ A lo largo de esta guía utilizaremos “cliente1” y “cliente2” como ejemplos de clientes, y “Prueba Flavors” como nombre del proyecto.

Sustitúyelos por el nombre real de tu aplicación o de cada cliente según corresponda.

Modifica la sección productFlavors como sigue:

android {
...
flavorDimensions "default"
    productFlavors {
        production {
            dimension "default"
            applicationIdSuffix ""
            manifestPlaceholders = [appName: "Prueba Flavors"]
            versionName "1.0.0"
            versionCode 1
        }
        staging {
            dimension "default"
            applicationIdSuffix ".stg"
            manifestPlaceholders = [appName: "[STG] Prueba Flavors"]
            versionName "1.0.0"
            versionCode 1
        }
        development {
            dimension "default"
            applicationIdSuffix ".dev"
            manifestPlaceholders = [appName: "[DEV] Prueba Flavors"]
            versionName "1.0.0"
            versionCode 1
        }
        cliente1 {
            dimension "default"
            applicationIdSuffix ".cliente1"
            manifestPlaceholders = [appName: "Cliente 1 App"]
            versionName "1.0.0"
            versionCode 1
        }
        cliente2 {
            dimension "default"
            applicationIdSuffix ".cliente2"
            manifestPlaceholders = [appName: "Cliente 2 App"]
            versionName "1.0.0"
            versionCode 1
        }
    }
    ...
}

Enter fullscreen mode Exit fullscreen mode

IOS

En iOS, trabajamos dentro de Xcode para configurar los Schemes y los Configurations. Vamos a crear los esquemas y configuraciones adicionales para cliente1 y cliente2.

  1. Abre Xcode y abre el proyecto ios/Runner.xcworkspace.

  2. Duplicar las configuraciones de build:

  • En Xcode, selecciona el proyecto Runner en el panel de la izquierda.

  • Ve a la pestaña "Info" y verás las configuraciones de build existentes para Debug, Release y Profile.

  • Duplicaremos estas configuraciones para cliente1 y cliente2. Haz clic en el icono de + de la parte inferior del menú de Configurations y duplica Debug , Release y Profile.

  • Nombra las nuevas configuraciones como Debug-cliente1, Release-cliente1, Profile-cliente1, y así con cada cliente / flavor.

  1. Crear esquemas para los nuevos flavors:
  • Ve al menú de esquemas en la parte superior de Xcode y selecciona "Manage Schemes".

  • Duplicamos los esquemas existentes (como development) para los clientes. Nombra estos esquemas cliente1 y cliente2.

  • Edita cada esquema y asegúrate de que esté asociado con la configuración de build correcta (por ejemplo, para el esquema cliente1, usa Debug-cliente1 para Debug y Release-cliente1 para Release).


🚀 Launch.json

El archivo .vscode/launch.json permite ejecutar y depurar tu app con diferentes flavors en VSCode. A continuación, se muestra un extracto de la configuración para el flavor cliente1 en modo debug.

{
    "name": "Launch cliente1 (debug)",
    "request": "launch",
    "type": "dart",
    "program": "lib/main_cliente1.dart",
    "flutterMode": "debug",
    "args": [
      "--flavor",
      "cliente1",
      "--target",
      "lib/main_cliente1.dart"
    ]
},
Enter fullscreen mode Exit fullscreen mode

Configura los demás flavors y modos (debug, release, profile) según las necesidades de tu proyecto.

Ahora, si usas VSCode, puedes ejecutar y depurar cada flavor en un modo específico desde la pestaña Run and Debug:

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente


🧩 Assets y Variables de aplicación

Cada flavor podrá tener variables específicas (por ejemplo, el nombre de la app, el nombre de la empresa, la url base de tu api, y más) así como assets propios (como los logos, entre otros).

Para resolver esto, crearemos un archivo dart de configuración que cargue las variables y rutas de assets correspondientes dependiendo del flavor. Estas variables serán usadas dentro del código de la aplicación.

Primero, crea un archivo lib/core/clients_config/config.dart, tal que:

// ignore_for_file: no_default_cases
enum Flavor { development, production, staging, cliente1, cliente2 }

class Config {
  static Flavor appFlavor = Flavor.development;

  //
  // APP VARIABLES
  //

  static String get appName {
    switch (appFlavor) {
      case Flavor.cliente1:
        return 'Cliente 1 App';
      case Flavor.cliente2:
        return 'Cliente 2 App';
      case Flavor.development:
        return 'Development App';
      case Flavor.production:
        return 'Production App';
      case Flavor.staging:
        return 'Staging App';
    }
  }

  static String get companyName {
    switch (appFlavor) {
      case Flavor.cliente1:
        return 'Cliente 1 Company';
      case Flavor.cliente2:
        return 'Cliente 2 Company';
      default:
        return 'Default Company';
    }
  }

  //
  // APP ASSETS
  //
  static String get logoAsset {
    switch (appFlavor) {
      case Flavor.cliente1:
        return 'assets/cliente1/logos/logo_cliente1.png';
      case Flavor.cliente2:
        return 'assets/cliente2/logos/logo_cliente2.png';
      default:
        return 'assets/common/logos/logo_default.png';
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

ℹ️ Para los assets puedes crear la jerarquía de carpetas que prefieras. Sin embargo, la recomendación es crear carpetas separadas para cada flavor / cliente, manteniendo así esta diferenciación en todos los ámbitos del proyecto.

Asegúrate de hacer referencia a las rutas de tus assets en el archivo pubspec.yaml:

flutter:
  assets:
    # common assets
    - assets/common/logos/

    # cliente1
    - assets/cliente1/logos/

    # cliente2
    - assets/cliente2/logos/
Enter fullscreen mode Exit fullscreen mode

A continuación, en cada archivo main_<flavor>.dart, inicializa el flavor correcto:

import 'package:prueba_flavors/bootstrap.dart';
import 'package:prueba_flavors/clients_config/config.dart';
import 'package:prueba_flavors/src/features/app/app.dart';

void main() {
  Config.appFlavor = Flavor.cliente1; // Inicialización del flavor

  bootstrap(() => const App());
}
Enter fullscreen mode Exit fullscreen mode

Finalmente, utiliza las variables de tu archivo Config dentro de la aplicación.

import 'package:prueba_flavors/clients_config/config.dart';

return Scaffold(
    appBar: AppBar(
      title: Text(Config.appName), // Usamos la variable appName
    ),
Enter fullscreen mode Exit fullscreen mode

💡 Esto no es una idea fija, aprovecha el concepto que acabamos de ver a tu favor creando más archivos Config si así lo deseas. Por ejemplo, podrías tener uno para las variables y otro para los assets, en caso de que tu proyecto tenga muchos recursos diferentes para cada cliente.


📱 Launcher Icon

Para la configuración de un launcher icon por cada flavor, vamos a utilizar el paquete flutter_launcher_icons. Para ello, necesitamos realizar una serie de configuraciones previas.

Para empezar, deberemos crear los archivos flutter_launcher_icons-<flavor>.yaml en la raíz del proyecto. Dentro de cada uno de estos, deberemos estructurar las opciones del paquete según nos interese. En este caso, como queremos configurar los iconos tanto para iOS como Android, el archivo tendría el siguiente aspecto.

flutter_launcher_icons:
    android: true
    ios: true
    image_path_android: 'assets/development/launcher_icon/android_launcher_icon.png'
    image_path_ios: 'assets/development/launcher_icon/ios_launcher_icon.jpg'

Enter fullscreen mode Exit fullscreen mode

En este caso, cuando indicamos las variables android e iOS como true, estamos indicando que queremos que se sobreescriba el icono que Flutter nos instaura por defecto para estas plataformas, mientras que image_path_android e image_path_ios nos llevan al lugar donde tenemos guardada la imagen que queremos convertir en nuestro icono.

Por otro lado, también existe la posibilidad de tener una única imagen para icono, no diferenciando entre android e iOS. Para construir un archivo con estas características, deberíamos editar ligeramente nuestro código.

flutter_launcher_icons:
    android: true
    ios: true
    image_path: 'assets/development/launcher_icon/android_launcher_icon.png'
    remove_alpha_ios: true

Enter fullscreen mode Exit fullscreen mode

Como podemos ver, hemos sustituido image_path_android e image_path_ios por image_path, donde indicamos el mismo archivo con transparencias (png) que asignábamos anteriormente a image_path_android. Además, hemos añadido una nueva variable remove_alpha_ios, la cual marcamos como true.

Esto se debe a que los iconos para iOS no deben tener transparencia, por lo que con esta configuración conseguiríamos quitarle esa propiedad a la imagen del image_path.

Una vez se tienen todos los archivos debidamente configurados, ya podemos utilizar el siguiente comando para la creación de todos los iconos en sus correspondientes tamaños.

dart run flutter_launcher_icons -f flutter_launcher_icons*
Enter fullscreen mode Exit fullscreen mode

Con este comando, no debería ser necesario hacer ninguna configuración extra para que los iconos estén listos para Android. Se pueden comprobar que todas las imágenes han sido creadas en la ruta android/app/src/<flavor>/res en cada una de las carpetas mipmap.

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

Sin embargo, para terminar la configuración en iOS hace falta entrar en Xcode y modificar la variable Primary App Icon Set Name. Para ello, entramos en Runner → Build Setting con las pestañas All y Combined seleccionadas y buscamos el término Asset. Con esto, debería aparecernos una sección llamada Asset Catalog Compiler - Options, donde encontraremos la variable anteriormente citada. Esta variable nos aparecerá desglosada por nuestros flavors, pero con el mismo valor en todos ellos. La modificación que debemos hacer es adaptar el valor a cada uno de estos flavors, como en la siguiente imagen.

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

Con esto debería ser suficiente para tener todos nuestros iconos modificados, tanto para Android como para iOS.


🖼️ Splash Screen

Para la gestión de la splash_screen por cada flavor hemos utilizado el paquete flutter_native_splash.

Primero, en la raíz del proyecto, debemos crear un archivo flutter_native_splash-<flavor>.yaml por cada flavor. Cada uno de esos archivos debe contener lo siguiente:

flutter_native_splash:
  android: true
  ios: true
  color: "#ffffff"

  image: "assets/common/splash_icon/splash_icon.png"

Enter fullscreen mode Exit fullscreen mode

En este ejemplo, colocamos el color del background que queremos en la variable color y la imagen deseada en la variable image.

Una vez creados todos los archivos pertinentes, ejecutamos el comando para crear todas las splash images necesarias.

dart run flutter_native_splash:create --flavors <flavor1>,<flavor2>,<flavorN>
Enter fullscreen mode Exit fullscreen mode

Para Android no sería necesario hacer nada más, pero para iOS necesitamos hacer un par de configuraciones:

  • Entra en la ruta ios/Runner/Base.lproj y selecciona los nuevos .storyboard que se hayan creado a raíz de tus flavors. Por ejemplo, si tienes como flavors development, staging y production, se te habrán creado los archivos LaunchScreenDevelopment.storyboard, LaunchScreenStaging.storyboard y LaunchScreenProduction.storyboard.

  • Abre el proyecto en XCode y pega estos archivos a la misma altura que los otros .storyboard que ya tengas por defecto.

    Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

  • Después de esto haz clic en el proyecto Runner (normalmente arriba del todo en la parte izquierda). A continuación, a la izquierda del centro de la pantalla, haz clic en Runner en el apartado de Targets.

  • Después, en la parte alta selecciona ‘Build Settings’, y asegúrate de tener seleccionadas las pestañas ‘All’ y ‘Combined’.

  • Al lado de estas pestañas se encuentra el botón ‘+’, púlsalo y elige la opción ‘Add User-Defined Setting’. Esto hará que Xcode cree una nueva variable para su uso.

  • Cambia el nombre a esta variable por el de LAUNCH_SCREEN_STORYBOARD (nombre sugerido).

  • Una vez que hagas esto, tendrás que asignar a cada Flavor un nombre concreto de variable, todos a raíz del nombre que tengan los archivos .storyboard que hemos añadido al proyecto en pasos anteriores (sin añadir la extensión .storyboard). La variable se debería de quedar configurada de una forma similar a la siguiente:

    Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

  • Después de este paso, hay que modificar nuestro archivo Info.plist. Entra en el archivo (lo verás dentro de la carpeta Runner, en la columna izquierda de XCode) y busca la variable ‘Launch screen interface file base name’.

  • El valor por defecto será 'LaunchScreen'. Cámbialo por la variable que hemos creado antes. Si has seguido los pasos exactamente, el nombre de la variable será LAUNCH_SCREEN_STORYBOARD, por lo que deberás poner $(LAUNCH_SCREEN_STORYBOARD).

¡Listo! Esto sería todo lo que tienes que hacer para configurar tu SplashScreen correctamente tanto en Android como en iOS.

ℹ️ Todo este apartado ha sido generado como una versión traducida del tutorial que ofrece la propia página del paquete en pub.dev en su apartado 'Flavor Support'. Si esta ayuda te resulta confusa en algún punto o ha quedado desfasada, recomiendo visitar la entrada original: https://pub.dev/packages/flutter_native_splash.


🔥 Configuración de Firebase

Si utilizas Firebase en tu proyecto Flutter, requerirás de varios archivos de configuración, los cuales pueden ser distintos para cada flavor. A continuación vamos a ver dónde guardar y utilizar dichos archivos.

💡 Para más información sobre cómo implementar Firebase con Flutter Flavors, echa un vistazo a este artículo:
https://codewithandrea.com/articles/flutter-flavors-for-firebase-apps

firebase_options

Dentro de lib/src/core/firebase/firebase_options/ (normalmente esta carpeta se crea automáticamente al generar los firebase_options) guarda los archivos firebase_options_<flavor>.dart que hayas generado.

Para usar estos archivos, añade en cada main_<flavor>.dart el siguiente código, asegurándote de importar el archivo firebase_options correspondiente.

  await Firebase.initializeApp(
    name: 'distribucion-app-dev',
    options: DefaultFirebaseOptions.currentPlatform,
  );

Enter fullscreen mode Exit fullscreen mode

Por ejemplo, para el flavor development, añadiremos este código en main_development.dart e importaremos 'package:/…/firebase_options/firebase_options_development.dart'.

Google_services.json

Dentro de android/app/src/ crea una carpeta para cada flavor (si no están ya creadas) y guarda ahí los archivos google_services.json de cada uno.

android/
    app/
        src/
            cliente1/
                google_services.json
            cliente2/
                google_services.json

Enter fullscreen mode Exit fullscreen mode

Google_service-info.plist

Primero, dentro de ios/Runner/ crea una carpeta config/ y dentro crea una carpeta para cada flavor, guarda ahí los archivos google-service-info.plist de cada uno.

ios/
    Runner/
        config/
            cliente1/
                google_services-info.plist
            cliente2/
                google_services-info.plist

Enter fullscreen mode Exit fullscreen mode

A continuación, debemos asignar a cada flavor su archivo google_service-info.plist correspondiente. Esto podemos hacerlo manualmente desde la pestaña BuildSettings de XCode, sin embargo, se puede volver algo tedioso hacerlo con cada nuevo cliente, por lo que vamos a automatizar este proceso de la siguiente manera:

  • Abre el proyecto en XCode.
  • Navega hasta Targets → Runner → Pestaña BuildPhases.

  • Haz clic en el botón “+” en la parte superior izquierda de la lista de BuildPhases y selecciona New Run Script Phase.

  • Copia y pega el siguiente script:

#!/bin/sh
# Nombre del archivo plist que estamos buscando
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist

# Determinar el flavor (esquema) actual basado en el nombre de la configuración
# El $CONFIGURATION variable puede tener valores como Debug-cliente1, Debug-prod, etc.
if [[ $CONFIGURATION =~ -([^-]*)$ ]]; then
  environment=${BASH_REMATCH[1]}
fi

echo "Environment: $environment"

# Rutas de los archivos GoogleService-Info.plist
GOOGLESERVICE_INFO_FILE="${PROJECT_DIR}/Runner/config/${environment}/${GOOGLESERVICE_INFO_PLIST}"

# Asegurarse de que el archivo GoogleService-Info.plist existe
if [ ! -f "$GOOGLESERVICE_INFO_FILE" ]; then
  echo "Error: No se encontró el archivo GoogleService-Info.plist para el environment ${environment} en ${GOOGLESERVICE_INFO_FILE}."
  exit 1
fi

# Copiar el archivo GoogleService-Info.plist a la ubicación esperada por Firebase
PLIST_DESTINATION="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
echo "Copiando ${GOOGLESERVICE_INFO_PLIST} al destino: ${PLIST_DESTINATION}"

cp "${GOOGLESERVICE_INFO_FILE}" "${PLIST_DESTINATION}"

Enter fullscreen mode Exit fullscreen mode

Este script seleccionará automáticamente el archivo GoogleService-Info.plist correcto dependiendo del flavor.

  • En el campo Shell selecciona /bin/sh.
  • Asegúrate de que el script esté en la parte superior de la lista de BuildPhases, justo después de “Target Dependencies”.
  • Elimina el GoogleService-Info.plist original del proyecto (si lo hay), alojado en la carpeta ios/Runner, ya que ahora usaremos diferentes archivos según el flavor.

🆔 Package Name / BundleId

Android

Para modificar el packageName de Android, usaremos el paquete change_app_package_name.

Primero añade el paquete en tu pubspec.yaml y usa el comando para renombrar el packageName en Android. Para ello, ejecuta:

flutter pub add -d change_app_package_name
flutter pub get
dart run change_app_package_name:main com.new.package.name --android

Enter fullscreen mode Exit fullscreen mode

Sustituye com.new.package.name por el nombre que desees. Este nombre será el packageName base del proyecto.

A continuación, para que cada flavor tenga su propio bundleID, vamos a añadirles un prefijo personalizado. Abre tu archivo build.gradle dentro de android/app, y modifica la variable applicationIdSuffix para cada flavor dentro del productFlavors.

Aquí un extracto del productFlavors modificado:

productFlavors {
    cliente1 {
        ...
        applicationIdSuffix ".cliente1"
    }
    cliente2 {
        ...
        applicationIdSuffix ".cliente2"
    }
    ...
}

Enter fullscreen mode Exit fullscreen mode

De esta manera, si nuestro packageName base es com.pruebaflavors.app, el packageName para el flavor cliente1 será com.pruebaflavors.app.cliente1.

IOS

En IOS, esta operación debe realizarse manualmente, ya que el Bundle Identifier está muy vinculado a la configuración del proyecto en Xcode. Lo haremos de la siguiente manera:

  • Abre el proyecto en XCode.
  • Navega hasta Targets → Runner → Pestaña BuildSettings.
  • En el buscador de arriba a la derecha, busca “Product Bundle Identifier”.
  • Modifica esta variable para cada configuración de flavor.

Ejemplo de configuración del Product Bundle Identifier por flavors:

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

Por último, asegúrate de que la variable PRODUCT_BUNDLE_IDENTIFIER está definida en tu info.plist tal que:

    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>

Enter fullscreen mode Exit fullscreen mode

🏷️ Nombre de Aplicación

El nombre de aplicación es el nombre que aparece en la pantalla de inicio, en las stores, en las configuraciones de aplicación del dispositivo, entre otros. Es posible adaptar un nombre de aplicación para cada flavor.

Android

Primero, debemos añadir la variable appName al archivo android/app/src/main/AndroidManifest.xml, de la siguiente manera:

...
<application
    android:label="${appName}"
    ...
</application>

Enter fullscreen mode Exit fullscreen mode

Ahora, en tu archivo android/app/build.gradle , asigna diferentes nombres de aplicación (appName) para cada flavor dentro de la configuración de productFlavors.

productFlavors {
      cliente1 {
        ...
        manifestPlaceholders = [appName: "Cliente 1 App"]
    }
    cliente2 {
        ...
          manifestPlaceholders = [appName: "Cliente 2 App"]
      }
      ...
}

Enter fullscreen mode Exit fullscreen mode

IOS

Para IOS lo haremos utilizando el archivo info.plist, mediante la variable FLAVOR_APP_NAME.

Primero, asegúrate de que esté definida en el info.plist que se encuentra en ios/Runner de la siguiente manera:

<key>CFBundleDisplayName</key>
<string>$(FLAVOR_APP_NAME)</string>
<key>CFBundleName</key>
<string>$(FLAVOR_APP_NAME)</string>

Enter fullscreen mode Exit fullscreen mode

A continuación,

  • Abre el proyecto en XCode.
  • Navega hasta Targets → Runner → Pestaña BuildSettings.
  • En el buscador de arriba a la derecha, busca “FLAVOR_APP_NAME”.
  • Modifica esta variable para cada configuración de flavor.

Ejemplo de configuración del FLAVOR_APP_NAME por flavors:

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente


🔢 Número de Versión

Android

Para Android, en tu archivo build.gradle dentro de android/app, puedes asignar diferentes versionCode y versionName para cada flavor dentro de la configuración de productFlavors.

Aquí un extracto del productFlavors modificado:

productFlavors {
    cliente1 {
        ...
        versionName "1.0.0"
        versionCode 1
    }
    cliente2 {
        ...
        versionName "1.0.0"
        versionCode 1
    }
    ...
}

Enter fullscreen mode Exit fullscreen mode

ℹ️ VersionName es la versión que los usuarios verán en Google Play Store.

VersionCode es el número de versión que se usa internamente para saber si una versión es más nueva que otra. Debe incrementarse con cada nueva versión que subas a la Play Store.

IOS

Para IOS lo haremos utilizando el archivo info.plist, mediante las variables FLUTTER_BUILD_NAME y FLUTTER_BUILD_NUMBER.

Primero, asegúrate de que estén definidas en el info.plist que se encuentra en ios/Runner de la siguiente manera:

<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>

Enter fullscreen mode Exit fullscreen mode

A continuación,

  • Abre el proyecto en XCode.
  • Navega hasta Targets → Runner → Pestaña BuildSettings.
  • En el buscador de arriba a la derecha, busca “Versioning”.
  • Modifica los valores de Current Project Version y Marketing Version para cada Flavor.

ℹ️ VersionName es la versión que los usuarios verán en Google Play Store.

Marketing Version es la versión que los usuarios verán en Apple Store. Corresponde a la variable FLUTTER_BUILD_NAME del Info.plist, y a la variable VersionName de la configuración de Android.

Current Project Version es el número de versión que se usa internamente para saber si una versión es más nueva que otra. Debe incrementarse con cada nueva versión que subas al Apple Store. Corresponde a la variable FLUTTER_BUILD_NUMBER del Info.plist, y a la variable VersionCode de la configuración de Android.


🔑 Cuenta de AppleID y Team

Cada flavor en tu proyecto de Flutter puede tener diferentes configuraciones de AppleID, Team de Apple, y otros detalles relacionados con la firma y distribución de la app (como perfiles de aprovisionamiento y certificados).

  • Abre el proyecto en XCode.

  • Navega hasta Targets → Runner → Pestaña Signing&Capabilities.

  • Aquí podrás ver una sección de configuración por cada flavor que hayas creado, lo único que debes hacer es modificar el apartado “Team”:

Guía de Implementación de Flavors en Flutter para Proyectos Multicliente

Recuerda configurar un Bundle Identifier distinto para cada flavor, como se explica más arriba en este documento, ya que las Stores no permiten tener dos identificadores iguales para distintas aplicaciones.


🛠️ Ejecución y Compilación

Ejecución

Utiliza el siguiente comando en tu terminal, reemplazando <flavor> por development, staging,production, cliente1 o cliente2 y <mode> por debug, profile, o release según sea tus necesidades:

```text
flutter run --flavor <flavor> --target lib/main_<flavor>.dart --<mode>
```
Enter fullscreen mode Exit fullscreen mode

Ahora deberías ser capaz de ver la aplicación corriendo en tu dispositivo o emulador.

ℹ️ Alternativamente, si estás utilizando Visual Studio Code, puedes seleccionar y ejecutar cada configuración desde el menú de "Run and Debug" basado en el archivo launch.json(Ver sección Launch.json).

Compilación

Utiliza el siguiente comando en tu terminal para generar una APK de Android del proyecto, reemplazando <flavor> por development, staging,production, cliente1 o cliente2 y <mode> por debug, profile, o release según sea tus necesidades:

flutter build apk --flavor <flavor> --target lib/main_<flavor>.dart --<mode>
Enter fullscreen mode Exit fullscreen mode

Los archivos generados se encuentran en build/app/outputs/apk/<flavor>/<mode>


🎉 ¡Fin! ¡Felicidades por llegar hasta aquí!


📫 Contacto

👋 Artículo escrito por David González Íñiguez

💌 davidgab08@gmail.com
🔗 linkedin.com/in/davidgonzaleziniguez

🧡 Si este post te ha sido útil: deja una reacción
🔖 Guárdalo en tu Reading List
💬 Comparte dudas o feedback en los comentarios.

👨‍💻 Abierto a colaboraciones y oportunidades relacionadas con Flutter.
Escríbeme por email o conéctame en LinkedIn.

Top comments (0)