O tom, proč se zakladatelé ECT rozhodli poskytnout milovníkům výběrové kávy mobilní aplikaci, jsme psali při spuštění iOS appky. Pojďte se s námi však podívat na to, jak probíhal vývoj pro Android, co jsme od iOSáků mohli převzít (jestli vůbec něco) a jaké jsme využili technologie.
Jako první jsme potřebovali sepsat potřeby uživatele, abychom mohli připravit koncept struktury mobilní aplikace. Důležitá pro nás byla především jednoduchost a snadná orientace uživatele.
Základní uživatelský scénář byl najít kavárnu v okolí, kde vaří výběrovou kávu. Obvykle, když něco v okolí hledáte, otevřete mapu. Proto jsem i my zvolili tuto strukturu, kde v aplikaci vidíte své umístění a modrý špendlík reprezentující kavárnu. Navíc v roce 2023 k nim přibyl i červený pro odlišení kaváren, které finančně podporují ECT.
V rámci zlepšení uživatelského zážitku při cestování jsme se rozhodli, že aplikace bude informace z mapy udržovat offline, a to především kvůli těm uživatelům, kteří mají omezený datový tarif, nebo cestují mimo bezplatný roaming. První otázka byla, kolik dat musí uživatel stáhnout při prvním spuštění appky a při případné aktualizaci databáze kaváren.
Při testování jsme počítali s 3 000 kaváren, kdy velikost dat v JSON byla okolo 3 MB v nekomprimované podobě. Díky kompresi na HTTP se však přenese pouhých 530 kB. Pro představu jde o ekvivalent dvou obrázků v Instagram feedu.
Možnou alternativou byl Protobuf, a ač s ním máme bohaté a pozitivní zkušenosti, bohužel nejsme správci dat (backendu). Argumenty pro Protobuf byly jasné (velikost, struktura a dobrá migrovatelnost). V závěru jsme však zvolili JSON, který zvýšil objem dat, ale na druhou stranu dovoloval jednodušší implementaci a úpravu backendu. Zároveň má jednodušší podporu pro případné webové aplikace.
Díky prvotnímu vývoji pro platformu iOS nám při vývoji Android verze aplikace European Coffee Trip odpadlo mnoho starostí. Nemuseli jsme například vymýšlet s backendem datovou strukturu, metadata, podle kterých keš pozná, že se má invalidovat apod. Takže za nás platí: Dbejte na dobrou dokumentaci komunikačních kontraktů. Zrychlí návrh a případné implementace na dalších platformách. Navíc máte verzovanou dokumentaci a víte, jak API kdy vypadalo.
Do vývoje androidí verze jsme se pustili zhruba dva měsíce před World of Coffee v Miláně 2022, kde chtěl klient nalákat co nejvíc uživatelů. To s sebou neslo nejen výzvu technickou, ale i designovou.
Původní design aplikace byl navržen pro iOS. Navíc nevyužíval Material Design, který je dobrým standardem pro uživatele Androidů. Rozhodli jsme se, že v rámci minimalizace nákladů na designování obrazovek grafikem zvolíme trochu nestandardní postup.
Ukázali jsme designérovi European Coffeee Tripu, co je Material 3 a poprosili ho, aby nám dodal základní rozhodnutí, například barevné palety, které potřebujeme do Android aplikace ve formátu respektující Material Design. Ušetřili jsme tak spoustu času a aplikaci poskládali hlavně z nativních designových komponent a s designérem dořešili akorát detaily.
Velkou výzvou bylo zvolení technologie. Půjdeme ověřeným způsobem tvorby obrazovek pomocí XML a fragmentů, nebo využijeme moderního nástupce? Zvážili jsme přínosy a rizika, a zvolili jsme Jetpack Compose.
A proč jsme se rozhodli pro Compose? Za prvé, pozorovali jsme intenzivní vývoj a pozitivní ohlasy v komunitě ohledně Compose. Za druhé, při rozhodovacím procesu jsme zjistili, že určité úlohy je možné svěřit komunitě. Ve vývoji mobilních aplikací čelíme často opakujícím se úkolům, pro které komunita již vytvořila užitečné knihovny. Tyto knihovny mohou vývojářům ušetřit mnoho cenného času, který mohou následně věnovat implementaci nových funkcí.
U nových technologií bývá výzvou vytvoření finálního a stabilního API. Proto Google vyvinul knihovnu Accompanist, kterou jsme využili pro sledování stavu oprávnění, integraci webových stránek (pomocí WebView) a pro stránkování v galeriích. Implementace galerie byla díky tomu velmi jednoduchá a rychlá.
Všechny fotografie kaváren jsme zobrazili prostřednictvím knihovny Coil, která efektivně zvládá ořezávání obrázků do určeného prostoru, lazy loading a kešování obrázků, což minimalizuje opakované načítání dat přes mobilní připojení. Dalším prvkem naší aplikace byly mapy.
Mapy jsou velmi komplexní a dynamický prvek obsahující vlastní stav (aktuální pozice, rotace a náklon mapových podkladů atd.). V minulosti bylo pro použití Google Maps v Compose zapotřebí mapy obalit do dynamické AndroidView, nyní však existuje knihovna od tvůrců Google Map. V prvních verzích byla jednoduchou obálkou nad AndroidView a proto ani v době našeho vývoje knihovna neobsahovala clustering.
Nebyl to však žádný problém, protože algoritmus pro clustering nad WGS84 souřadnicemi je součástí utils knihovny, takže předat předpočítané clustery k překreslení obrazovky podle viditelné plochy je triviální. A na druhou stranu, nemuseli jsme do Compose přenášet všechny body a tím urychlili aplikaci samotnou.
Už při psaní androidí aplikace šlo vidět, že komunita knihovny a vývojáři kolem Jetpack Compose jsou velmi aktivní. Netrvalo dlouho a clustering přidali v experimentálním módu, pro nás bohužel až po tom, co jsme aplikaci spustili.
Compose se vyznačuje především svou schopností efektivně zpracovávat vykreslování. Nicméně aplikace obvykle obsahují mnoho vzájemně propojených obrazovek, mezi kterými uživatelé očekávají plynulé přechody. V této souvislosti přichází do hry Navigation knihovna od Googlu, která je dostupná i pro Compose. Klíčem k jejímu úspěšnému využití je správné použití dependency injection prostřednictvím nástrojů jako jsou Hilt nebo Koin. Tím je zajištěna snadná kompatibilita s ViewModely, což umožňuje efektivní správu stavů a dat mezi různými obrazovkami aplikace.
Při návrhu obrazovek jsme dbali na osvědčené postupy pro Android uživatele, což zahrnovalo i implementaci Material Design 3 (M3). Nicméně jsme narazili na určité komponenty, které nebyly v M3 dostupné, nebo byly k dispozici pouze ve verzi Material Design 2 (M2). Integrace M2 komponent se ukázala být přímočará, avšak vyžadovala od nás nastavení určitých základních parametrů (pomocí 'CompositionLocalProvider'), aby bylo možné používat tematizaci včetně tmavého režimu. Díky flexibilitě Material Design konceptů jsme byli schopni bez problémů implementovat tmavý režim pro naše Android uživatele.
Pokud se rozhodujete pro integraci BottomSheet do vaší aplikace, máme na výběr ze dvou variant: standardní 'BottomSheet' a komplexnější 'BottomSheetScaffold'.
BottomSheetScaffold' nabízí řešení pro celou obrazovku, kde klíčovým rozdílem oproti standardní variantě je možnost interakce uživatele s obsahem, který zůstává za sheetem viditelný a přístupný. To se hodí zejména pro mapové aplikace, kde uživatelé potřebují přecházet mezi různými body zájmu, jako jsou kavárny. Naopak, modální 'BottomSheet' zneprůhlední a znepřístupní obsah na pozadí, což je ideální pro situace, kdy chcete, aby se uživatel soustředil na konkrétní akci, jako je výběr filtrů.
V době, když jsme začínali s iOS aplikací, byl Jetpack Compose velmi mladý nástroj a jsem rád, že vývoj Android verze se odložil. S blížícím se vydáním Jetpack Compose ve verzi 1.3 se mnoho detailů doladilo a zároveň vznikl kvalitní designový framework Material 3 s implementací pro Jackpack Compose, který jsme mohli použít.
Jak jsme už zmínili, databáze kaváren se stahovala do telefonu, a to byl relativně časově nákladný úkon. Nabízí se kešování dat, dále řešíme kešování v rámci HTTP, aby se uživateli nestahovala po intervalu celá databáze, i když nedošlo k žádné změně na straně backendu.
Na Androidu jsme šli ještě dál a využili potenciál nástroje WorkManager. Ten nám dovoluje stáhnout databázi na pozadí, a to v nejlepších podmínkách pro uživatele, aniž by musel mít aplikaci zrovna zapnutou. V situaci například v hotelu, kde máte WiFi a nabíjíte přes noc telefon, najdete ráno připravenou nejaktuálnější databázi a nemusíte během dne čekat na stažení případných změn.
V průběhu vývoje jsme řešili, že odhad vývoje byl přibližně na necelé dva pracovní měsíce, avšak řekli jsme si, že by byla super příležitost boostnout vývoj a doručit aplikaci do data World of Coffee v Miláně, kde Aleš (zakladatel ECT) může na světové úrovni prezentovat aplikaci pro obě platformy. Jedna možnost byla, že bychom aplikaci vyvinuli ve spolupráci s externími vývojáři. Můj postoj byl, že prvně vyzkoušíme, jak rychle mi dovolí Compose projekt posunout. A za mě na to byla ideální příležitost. Jak jinak než tripem!
První prototyp jsem částečně vytvořil den před odletem na můj trip do Velké Británie. V letadle jsem dodělal funkční prototyp. Měl jsem tak aplikaci poskytující body na mapě, otevírací dobu a pár dalších informací. Byl to totální základ, ale v tento moment jsem věděl, že Compose je cesta, která mi dovolila aplikaci velmi efektivně vytvořit. Mimochodem, na prototypování si v Cookielabu zakládáme, je však třeba připomenout Paretovo pravidlo. Vývoj 80 % funkcionalit aplikace zabere 20 % času.
Všechno se stihlo, Jetpack Compose nám o polovinu urychlil čas vývoje oproti klasickému postupu, World of Coffee 2022 se blížil a pak…
Pak přišlo schvalování v Google Play. Tady jsme však narazili. I když za nás bylo všechno hotové a připravené, Google nám aplikaci neschválil tak rychle, jak jsme očekávali a celkem čekala na schválení 14 dní.
Co se však rozhodně povedlo:
P.S.: Podpořte tým European Coffee Trip a kupte jim v aplikaci virtuální kávu! Pomůže jim to!
A k té pro jablka zase sem.