Občas je nutné vyrobit aplikaci, která má stejný codebase, ale na základě flavors má jiné bundleId, napojený firebase, ikonky a název – běžně to jsou klony pro různé klienty.
Ve Flutter se s flavors pracuje docela jednoduše, zkrátka při buildu přidáte flag –flavor a přidáte libovolný string. Jestliže se tím mění pouze nějaká logika uvnitř dart kódu, nemusíte dělat žádné další úpravy. Pro Android je potřeba definovat Flavors v /app/build.gradle, kde si následně nadefinujete jednotlivé proměnné, včetně jména aplikace. https://developer.android.com/build/build-variants, následně pak proměnné můžete používat v AndroidManifestu.
V app/build.gradle to pak vypadá asi takto:
android {
.
.
.
.
flavorDimensions "env"
productFlavors {
flavor1 {
dimension "env"
applicationId "cz.name.app"
resValue "string", "app_name", "Nazev1"
resValue "string", "launch_icon", "@mipmap/ic_launcher_flavor1"
}
flavor2 {
dimension "env"
applicationId "de.name.app"
resValue "string", "app_name", "Nazev2"
resValue "string", "launch_icon", "@mipmap/ic_launcher_flavor2""
}
}
}
A v AdroidManifest.xml třeba takto:
<application
.
.
.
android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@string/launch_icon">
Větší problém vidím ale u iOS, tyto definice se tam takto jednoduše nedají zapsat a musí si je člověk vyklikat v XCode. Pro začátek je nutné definovat různá Schema pro Runner. Následně pak v Runner->Info->Configurations udělat kopii pro Debug, Profile a Release. Tyto konfigurace pojmenujte jako Debug-Flavor, kde „Flavor“ je váš flavor, který jste si před tím sami nadefinovali a podle kterého jste pojmenovali Vaše nové Schema, pak postupujte stejně i pro Profile a Release.
Tím jste získali možnost buildovat aplikaco pro iOS s flavors. Jenže to nám zatím vůbec nic neřeší. Ale když se podíváte do různých nastavení, zjistíte, že pro každý flavor (resp. Configuration) si můžete navolit vlastní hodnoty. Doporučuji se v přednastavených hodnotách moc nehrabat. Ale můžeme si nadefinovat User-defined Setting. A to v Runner->Build Settings-> + -> User-Defined Setting. Určitě by se vám mohlo hodit mít možnost v rámci buildování aplikace zpřístupněný název vašeho flavor v rámci swift, ale třeba i pre-build scriptů. Proto je dobré si třeba nadefinovat „SchemeName“ a dále třeba „AplicationName“, obojí lze pak vkládat do info.plist, tudíž pak nemusíte mít více info.plist pro různé flavors.
<key>CFBundleDisplayName</key>
<string>$(AplicationName)</string>
<key>CFBundleName</key>
<string>$(SchemeName)</string>
Kde toto opravdu oceníte je, když potřebujete pro Firebase více různých nastavení. Pro začátek si stáhněte všechny GoogleService-Info.plist soubory (pro každý bundleId/flavor), tyto soubory si uložte do /ios/google/_FLAVOR_/, kde _FLAVOR_ je SchemeName z User-Defined setting. Teď, když se pokusíte aplikaci zbuildit, nejspíše se build nepodaří, protože se jednotlivé GoogleService-Info.plist soubory snaží nakopírovat do jednoho adresáře. XCode totiž „Bundle resources“, kam patří i tyto soubory, v rámci Build Phases kopíruje do build adresáře. Soubory mají stejné jméno a build kvůli tomu padá. Proto je nutné tyto soubory z Build Phases -> Copy Bundle Resources odstranit. Nyní to při buildu na této fázi nespadne. Ale spadne Vám to velice pravděpodobně v ios/Runner/AppDelegate.swift, kde máte kód pro konfiguraci FirebaseApp.
FirebaseApp.configure()
Tento kód hledá v buildu GoogleService-Info.plist, který tam teď není. Jako ověření a debugování si můžete vypisovat obsah tohoto souboru v AppDelegate.swift takto:
let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist", )!
let data = NSData(contentsOfFile: filePath) as! Data
print(String(data: data, encoding: .utf8))
Jak tedy dostat zpět nastavení pro Google? Ano, v Build Phases spustíme script, který za nás vybere správný soubor a nakopíruje ho na správné místo. Využijeme u toho právě proměnnou SchemeName:
.
.
.
.
GOOGLESERVICE_INFO_PLIST=${PROJECT_DIR}/google/${SchemeName}/GoogleService-Info.plist
# Make sure the dev version of GoogleService-Info.plist exists
echo "Looking for ${SchemeName} in ${GOOGLESERVICE_INFO_PLIST}"
if [ ! -f $GOOGLESERVICE_INFO_PLIST ]
then
echo "No ${SchemeName} GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 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}"
cp "${GOOGLESERVICE_INFO_PLIST}" "${PLIST_DESTINATION}"
Tento kód vložíme na konec Run Script v Build Phases. Šlo by to udělat bez těch checků, zda soubor existuje a vypisování debug hodnot. Pokud build proběhne v pořádku, tyto informace se nikde nevypíší, tudíž nás nebudou otravovat. Ale pokud se něco pokazí, tak se vám tyto informace mohou hodit. Script si ověří, zda soubor existuje ve složce /ios/google/flavor/, a pak jej zkopíruje do build adresáře, aby byl dostupný pro další fázi běhu programu.
A to je vše. Takto máte nakonfigurované potřebné proměnné pro build s flavors na iOS.

Napsat komentář