Organización de sabores en Flutter

¿Para qué sirven los sabores?


Imagine la situación: hay una aplicación con análisis. Hay un equipo de desarrollo, probadores y usuarios finales. Tanto esos como los que usan una versión de la aplicación. Supongamos que queremos analizar qué tan interesante es la característica A para los usuarios. ¿Qué hacemos en este caso? Vamos a la analítica y vemos cuántos usos tenía esta función (por ejemplo, transiciones a la pantalla). Pero qué vemos: un número prohibitivo de transiciones, que de ninguna manera es imposible para la audiencia actual, y todas estas transiciones se realizaron en un cierto período de tiempo. Vamos más allá y entendemos que en este momento se llevaron a cabo pruebas de esta característica. Y un poco antes su desarrollo. Al mismo tiempo, también se enviaron análisis. En pocas palabras: el análisis es sucio y deficiente.


Aquí puede reemplazar el análisis de palabras con cualquier otro: notificaciones push, informes de fallas, etc.


Y en esta situación, nos salvamos dividiendo la aplicación en dos versiones que difieren mínimamente, por ejemplo, ID de paquete (nombre del paquete). Los desarrolladores y probadores usan solo una versión de desarrollo especial, y los usuarios usan una versión de ventas.


Esta es solo una de las tareas de los sabores. Aquí se utilizará el sabor, ya que este es el nombre utilizado por Flutter. Las personas que están familiarizadas con el desarrollo de Android, creo que reconocieron de inmediato este mecanismo.



¿Saborizante aleteo?


Bueno, descubrimos la tarea. ¿Pero cómo implementarlo? ¿Es todo tan simple como dicen?
Decidamos de inmediato: la organización de sabores es una tarea puramente nativa. La información sobre ellos no estará disponible en el código de dardos. Por lo tanto, para las formas de organización, iremos al desarrollo móvil nativo.


Androide


. android. : « buildType?», .


, , :


flavorDimensions "release-type"

    productFlavors {
        dev {
            dimension "release-type"
            applicationIdSuffix  ".dev"
            versionNameSuffix "-dev"
        }

        prod {
            dimension "release-type"
        }
    }

, :


flutter run --flavor dev

android .


: « buildType?» : Flutter buildType . , .


.
, builtTypes. IOS.
:


AndroidIOS
build typesbuild configurations
flavorstargets

— , ( ). flavor’ target’ — .


, , «»...


Runner — .


, target flavors iOS . , Flutter . , . . .


IOS


: (dev, prod, ).


:


  1. .
  2. .
  3. !

.



: dev, prod. :


    #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug-dev.xcconfig"
    #include "Generated.xcconfig"
    #include "common.xcconfig"

    bundle_suffix=.dev
    IDENTIFIER=$(identifier)$(bundle_suffix)

, bundle_suffix.


, Flutter Release Debug. bundle_suffix. , IDE.


IDENTIFIER — .


, :


ios/Flutter/dev.xcconfig
ios/Flutter/prod.xcconfig

XCode ( , ). Runner → New File → Configuration Settings File → .


Build Configurations. .


. Runner.xcworkspace Xcode Project.


«+» Configurations : Release Debug, .


:



, , IOS .


Scheme


, .



. : — Runner.
Edit Scheme .


Info.plist


(: ) — Bundle Identifier Info.plist


$(PRODUCT_BUNDLE_IDENTIFIER)$(bundle_suffix)

...


, , Android , fastlane gym iOS — . , IOS - … .


No Provisioning Profile


— . , .


, Info.plist , gym PRODUCT_BUNDLE_IDENTIFIER, .
common.xcconfig IDENTIFIER? .


, , , PRODUCT_BUNDLE_IDENTIFIER.


:


identifier=your.bundle.identifier

include User Defined
IDENTIFIER:


#include "common.xcconfig"

IDENTIFIER=$(identifier)$(bundle_suffix)

Xcode. Build Settings:



Product Bundle Identifier ( Packaging):



:


$(IDENTIFIER)


Info.plist bundle suffix, :


$(PRODUCT_BUNFLE_IDENTIFIER)

. .


bundle id


. Firebase, ( ).


— google-services.json(Google-Services.Info.plist). Android : flavor’ .


IOS - .



, . :



: XCode. . XCode — IDE, Add to target.
.



, . - , .


Run Script (setup firebase ):



, !


, :


# Name of the resource we're selectively copying
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist

# Get references to dev and prod versions of the GoogleService-Info.plist
# NOTE: These should only live on the file system and should NOT be part of the target (since we'll be adding them to the target manually)
GOOGLESERVICE_INFO_DEV=${PROJECT_DIR}/${TARGET_NAME}/Firebase/dev/${GOOGLESERVICE_INFO_PLIST}
GOOGLESERVICE_INFO_PROD=${PROJECT_DIR}/${TARGET_NAME}/Firebase/prod/${GOOGLESERVICE_INFO_PLIST}

# Make sure the dev version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_DEV}"
if [ ! -f $GOOGLESERVICE_INFO_DEV ]
then
echo "No Development GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1 # 1
fi

# Make sure the prod version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_PROD}"
if [ ! -f $GOOGLESERVICE_INFO_PROD ]
then
echo "No Production GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1 # 1
fi

# Get a reference to the destination location for the GoogleService-Info.plist
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"

# Copy over the prod GoogleService-Info.plist for Release builds
if [[ "${CONFIGURATION}" == *-prod ]]
then
echo "Using ${GOOGLESERVICE_INFO_PROD}"
cp "${GOOGLESERVICE_INFO_PROD}" "${PLIST_DESTINATION}"
else
echo "Using ${GOOGLESERVICE_INFO_DEV}"
cp "${GOOGLESERVICE_INFO_DEV}" "${PLIST_DESTINATION}"
fi


. , , Flutter ( ). , . .


All Articles