Para que servem os sabores?
Imagine a situação: existe um aplicativo com análises. Há uma equipe de desenvolvimento, testadores e usuários finais. Esses e aqueles usam uma versão do aplicativo. Suponha que desejemos analisar o quão interessante o recurso A. é para os usuários. O que fazemos neste caso? Vamos à análise e veremos quantos usos desse recurso foram (por exemplo, transições para a tela). Mas o que vemos: um número proibitivo de transições, o que não é de modo algum impossível para o público atual, e todas essas transições ocorreram em um determinado período de tempo. Vamos além e compreendemos que, neste momento, foram realizados testes desse recurso. E um pouco mais cedo seu desenvolvimento. Ao mesmo tempo, a análise também foi enviada. Conclusão: a análise está suja e abaixo do padrão.
Aqui você pode substituir a palavra análise por qualquer outra: notificações push, relatórios de falhas, etc.
E nessa situação, somos salvos dividindo o aplicativo em duas versões que diferem minimamente, por exemplo, ID do pacote (nome do pacote). Os desenvolvedores e testadores usam apenas uma versão de desenvolvedor especial, e os usuários usam uma versão de vendas.
Esta é apenas uma das tarefas dos sabores. Aqui o sabor será usado, pois esse é o nome usado por Flutter. Pessoas que estão familiarizadas com o desenvolvimento do Android, acho que imediatamente reconheceram esse mecanismo.

Flavoring Flutter?
Bem, nós descobrimos a tarefa. Mas como implementá-lo? Tudo é tão simples como eles dizem?
Vamos decidir imediatamente: a organização dos sabores é uma tarefa puramente nativa. As informações sobre eles não estarão disponíveis no código do dardo. Portanto, pelas formas de organização, iremos para o desenvolvimento móvel nativo.
Android
. 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.
:
— , ( ). flavor’ target’ — .
, , «»...
Runner — .
, target flavors iOS . , Flutter . , . . .
IOS
: (dev, prod, ).
:
- .
- .
- !
.
: 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 ( ). , . .