Miroslav Holec
Premium

Vývoj Blazor Hybrid aplikace (MAUI)

Miroslav Holec   24. září 2024

Poslední neprozkoumaná oblast Blazoru pro mě byla donedávna Blazor Hybrid. Zatímco Blazor Server běží na serveru a Blazor WebAssembly v prohlížeči, Blazor Hybrid je zahostován v komponentě BlazorWebView v .NET MAUI. Samotná .NET MAUI aplikace je multiplatformní a umožňuje nasazení na různé operační systémy. A přesně to jsem potřeboval. Se znalostmi Blazoru vytvořit aplikaci, kterou lze nasadit na macOS a Windows. Jak to dopadlo?

Popis aplikace

Než se pustím do technických detailů, popíšu můj scénář. Před rokem jsem vytvořil webovou aplikaci Textomet, která je k mému překvapení docela úspěšná. Umožňuje méně zkušeným uživatelům používat ChatGPT skrze připravené šablony. Začátkem roku jsem do aplikace přidal i klasický ChatGPT, který se stal postupně nejpoužívanější částí. Proto jsem se rozhodl přenést právě ChatGPT do samostatné desktopové aplikace napojené na Textomet.

Celá desktop aplikace se skládá v první verzi pouze z dvou obrazovek: login a chat.

image-20240922205306729

Znalosti pro vývoj

.NET MAUI je zkratka pro Multi-platform App UI (dále budu zkracovat na MAUI) a jedná se o cross-platform framework pro vytváření nativních mobilních a desktopových aplikací s použitím C# a XAML. Díky MAUI lze tedy vytvářet například aplikace pro mobilní telefony s iOS i Android nebo desktop aplikace pro macOS a Windows. Podpora je ale mnohem širší. Protože je MAUI cross-platform, lze aplikace vyvíjet na macOS i Windows. Já jsem zvolil pro vývoj macOS a aplikaci jsem primárně vytvářel pro Windows. Kromě toho jsem nevyužíval běžné ovládací prvky z MAUI, ale zvolil jsem šablonu projektu Blazor Web App v .NET MAUI. V tomto případě vznikne v rámci MAUI aplikace komponenta BlazorWebView a v ní běží webová aplikace v Blazoru. Pro vývoj tedy stačí znát Blazor, HTML a CSS. Dále je potřeba uvědomit si důsledky tohoto modelu:

  • singleton lifetime services žijí po dobu běhu aplikace (stav uživatele)
  • stav aplikace a uživatele je nutné uchovávat lokálně
  • datová komunikace vyžaduje webovou službu
  • po nasazení aplikace může být problém verzovat API

Nástroje pro vývoj

Pro vývoj lze použít libovolné IDE s aktuální verzí .NETu a doinstalovaným workloadem. Seznam workloadů lze dohledat například pomocí CLI příkazem dotnet workload list. Workloady se vážou na verzi SDK, takže při update SDK je nutné instalovat znovu i workloady.

image-20240922203700817

Samotná šablona je koncipovaná dost prapodivně a ve Visual Studiu na Windows fungovala jen se zapnutým TFM net8.0-android. Čert ví proč jsem tedy musel instalovat i podporu pro Android.

Zde se hodí říct, že mnou vytvářená aplikace byla na pár hodin práce a netrávil jsem žádný dodatečný čas troubleshootingem. Cokoliv nefungovalo jsem se snažil co nejrychleji obejít cestou nejmenšího odporu.

Nic dalšího jsem pro vývoj nepotřeboval. Protože je aplikace v Blazoru, vystačil jsem si se základní šablonou využívající Bootstrap bez dalších komponent.

Koncept aplikace a vývoj

Ani vývoj nebyl nijak složitý. Je to velmi podobné vývoji v Blazor WebAssembly, protože i tady je potřebná webová služba a není k dispozici sdílený stav aplikace. Stav uživatele (zejména autentizační token) je uchován lokálně v počítači. Na straně API jsem připravil jen 4 endpointy:

  • přihlášení pomocí e-mailu a hesla
  • generování odpovědi pro chat
  • healthcheck
  • version

Pro přihlášení jsem použil JWT. Endpoint s verzí slouží k vynucení aktualizace aplikace. Rozhodl jsem se neverzovat API a v případě, že bych musel provést zpětně nekompatibilní změnu bych vynutil u uživatelů update aplikace. Zbytek byla jen skládačka z HTML a CSS.

Během vývoje jsem měl zásadní problémy s laděním. Jednak mi v kombinaci macOS / Rider / Firefox nefungovala inspekce HTML kódu a jednak ani samotný debug mód. Aplikace v MAUI se vždy zkompiluje, nasadí, spustí a vše ostatní už je jen záležitost Blazoru. Kombinaci Windows / VS jsem nezkoušel. Aplikace byla naštěstí triviální a těch pár hodin jsem se bez ladění obešel. Udělal jsem si jen ErrorBoundary, přes které jsem se díval na stack trace.

Nasazení

Všechno, co jsem doposud popsal jsem měl hotové za cca 7 hodin práce. Tedy jednoduché API i samotnou aplikaci. Funkčnost jsem si ověřil na macOS i na Windows. Dalších 5 dní trval proces publikace do Windows Store.

Nasazení aplikace do Windows Store je průchod peklem. To, co u Apple funguje dekádu nebyl Microsoft za celé roky schopen dostat do funkčního stavu. Vůbec se nedivím, že většina vývojářů (včetně těch z Microsoftu) publikuje aplikace v jiných kanálech a celý Windows Store umírá ode dne, co vznikl.

Naprosto tristní podpora ve Visual Studiu se ještě zkomplikovala problémem, který Microsoft řeší snad milion let. Přepínání mezi firemním a osobním účtem. Deploy do Store končil vždy na chybě s neplatným certifikátem a protože jsem měl asi 7 teorií ohledně příčiny, nechtěl jsem každou izolovaně řešit. Trvalo by to týdny.

Takže jsem založil nový hotmail účet, registroval se znovu v MS Partner Center a zaplatil další developerské výpalné (442 Kč). Založil jsem virtuální stroj v Azure a v něm nainstaloval znovu Visual Studio v Community edici. Přihlásil jsem se tím jediným účtem a vypublikoval prázdnou šablonu MAUI aplikace. Ta byla už průchozí, takže jsem do ní nakopíroval pečlivě zdrojáky mé aplikace a zázrakem se mi podařilo package zvalidovat.

Update: po další investigaci se zdá, že VS v jeden moment použilo certifikát jednoho z mých účtů a CN zapsalo do csproj. Windows Store pak s tímto CN nebyl spokojený. Dost možná by tedy stačilo odstranit z csproj řádek s CN. Tuto teorii jsem si neověřoval, byť je vysoce pravděpodobná.

Aplikace nicméně neprošla certifikací.

  1. screenshot byl z macOS a ne z Windows
  2. špatně jsem nastavil age ratings

První problém chápu, takže jsem přidal screenshoty z Windows. Druhý problém mě rozsekal. Tzv. age ratings jsou totiž rozsáhlý formulář, na jehož konci dostane aplikace řadu nálepek, jako například:

image-20240922213914075Ano, známe to z her a bohužel stejně šílený formulář se vyplňuje i u aplikací. Když uděláte chybu, dozvíte se jen, že něco je špatně, ale nevíte co.

Druhý pokus také nevyšel. Zkrátka jsem to netrefil a age ratings byly opět chybně. Místo, abych jasně dostal feedback, co je špatně, tak pokračují mé pokusy, které obě strany stojí zbytečný čas.

image-20240923073129261

Ani třetí pokus nevyšel. Jednak ani tentokrát jsem nevyplnil age ratings správně a druhak mi nově byl odmítnut odkaz na privacy policy. Opět nevím proč, protože v mých obchodních podmínkách jsou uvedeny i vazby na GDPR. Udělal jsem tedy speciálně stránku GDPR a nalinkoval ji. Age ratings jsem naposledy tipnul s tím, že jestli to nebude OK, tak příště to odklikám tak, jako by to byla hra s nebe volajícím násilím. Protože jsem tuto žádost posílal v sobotu ráno, čekal jsem na další reakci celý víkend. V pracovních dnech trvá reakce cca 6 až 10 hodin a zřejmě mé schvalování probíhalo na západě. Čili i v pozdních pátečních hodinách je dobrý nápad aplikaci odeslat.

V tuto chvíli už žádám o připojení do kanálu Windows Development, abych předal zpětnou vazbu k celému procesu.

image-20240922220419189

Čtvrtý pokus mezitím opět nevyšel, takže jsem u věkového nastavení naklikal takové nesmysly, že aplikace je vhodná jen pro uživatele od 18 let a už není co kontrolovat.

image-20240923073129261

Tady se hodí menší odbočka. Věkové hodnocení se nastavuje pro různé trhy a Windows Store na počátku publikace automaticky nastavuje publikaci na všechny trhy. To jsem zjistil až později. V zásadě jsem mohl nastavení změnit a přepsat na CZ + SK a tím by se (možná) formulář pro nastavení věku obešel. Když ale certifikace selže, tato jediná položka už nejde změnit.

Na pátý pokus se mi povedlo aplikaci do Windows Store vypublikovat.

image-20240924092043990

Závěr

Pro vývojáře se znalostí Blazoru je být vývoj desktopové aplikace pro macOS a Windows s Blazor Hybrid snadný. U větší aplikace bych strávil více času nastavením ladění a v případě častějšího nasazování by se hodilo nastavit CI/CD. Pro účely UI bych se poohlédl po komponentách, které by pomohly aplikaci lépe zasadit do vizuálního stylu dané platformy než používat webový Boostrap. Celkově asi jediný bolestivý bod bylo publikování aplikace do Windows Store. To ostatní fungovalo dobře.