Кросплатформна розробка мобільного застосунку на .NET MAUI
.NET MAUI (Multi-platform App UI) — прямий наступник Xamarin.Forms, переписаний під .NET 6+. Головна архітектурна зміна: один проект замість окремих цілей iOS, Android, WinUI, macOS — все через єдиний csproj з умовними залежностями по платформі. Це означає один appsettings.json, один DI-контейнер (Microsoft.Extensions.DependencyInjection), одні моделі.
Якщо ваша команда вже працює з C# та ASP.NET Core, перехід на MAUI технічно мінімальний — паттерни ті ж самі, інструментарій той же (Visual Studio 2022 / Rider), NuGet той же. Для підприємств, де мобільний застосунок є фронтенд до .NET-бекенду, це часто єдиний розумний вибір з точки зору уніфікації команди.
Де виникають реальні проблеми
MAUI рендерить нативні контролі платформи через Handlers — на відміну від Xamarin.Forms з Renderers. На папері це чистіше. На практиці: якщо стандартний Handler не підтримує потрібну властивість, пишемо partial class з залежним від платформи кодом і AppendToMapping. Це нормальний паттерн, але вимагає розуміння нативних API кожної платформи.
Hot Reload працює з обережностями. XAML Hot Reload у Visual Studio 2022 17.6+ нормально працює для простих змін розмітки. Але зміни в C# code-behind або view model вимагають перезапуску — .NET Hot Reload у MAUI ненадійний при складних ієрархіях. На практиці ітерація по UI займає більше часу, ніж у Flutter або React Native.
Розмір бінарника. Базовий APK .NET MAUI застосунку без trimming — 30–50 МБ. З PublishTrimmed=true та RuntimeIdentifier=android-arm64 удається стиснути до 15–25 МБ, але trimming ламає Reflection, на якому будується частина NuGet-пакетів. Кожен додатий пакет потрібно перевірити на сумісність з AOT/trimming.
NativeAOT на iOS — з .NET 8 доступен. Дає кращий startup time та розмір, але вимагає повного відмовлення від runtime Reflection. Якщо проект використовує System.Text.Json з source generators — окей. Якщо Newtonsoft.Json — міграція обов'язкова.
Стек та архітектура
MVVM — стандарт для MAUI. CommunityToolkit.Mvvm закриває 90% потреб: [ObservableProperty], [RelayCommand], [NotifyCanExecuteChangedFor] через source generators. Ніякого boilerplate INotifyPropertyChanged вручну.
Shell-навігація (Shell) для стандартних випадків; для складної навігації з передачею об'єктів — NavigationPage або ReactiveUI.Maui. Prism.Maui — якщо команда з ним знайома по WPF/UWP.
Сітьовий шар — HttpClientFactory через DI, Refit для типізованих REST-клієнтів, Polly для retry/circuit breaker. gRPC-клієнт через Grpc.Net.Client працює на iOS та Android без додаткових настроєнь починаючи з .NET 7.
Локальна БД — SQLite-net-pcl для простих випадків, LiteDB для документ-орієнтованого сховища. Entity Framework Core з SQLite провайдером працює, але в trim-сценарії вимагає EFCore.TrimmingSupport.
Push-повідомлення — Plugin.Firebase.CloudMessaging для FCM; APNs на iOS настроюється через UNUserNotificationCenter у MauiProgram.cs.
Кейс із практики. Корпоративний застосунок для польових інспекторів: оффлайн-робота з формами та фотографіями, синхронізація при появленні мережі. Стек: MAUI + EF Core SQLite + Polly для retry черги + Xamarin.Essentials (тепер Microsoft.Maui.Essentials) для доступу до камери та GPS. Залежна від платформи частина — тільки робота з файловою системою (шляхи різні на iOS Documents vs Android GetExternalFilesDir). CI — Azure DevOps Pipelines з завданнями dotnet publish під кожну платформу, підпис через KeyVault для Android keystore.
Інтеграція з платформою
Доступ до нативних API — через Microsoft.Maui.Essentials: геолокація, акселерометр, Bluetooth, камера, біометрія (SecureStorage + Fingerprint). Якщо потрібен доступ за межами Essentials — DependencyService з залежними від платформи реалізаціями або прямий вклик нативного коду через #if ANDROID / #if IOS у partial класах.
Біндинги до нативних SDK: на Android — Java/Kotlin Binding Library через Binding Project; на iOS — ObjectiveC/Swift Binding через ApiDefinitions.cs. Процедура трудомістка, але відпрацьована.
Терміни
| Масштаб | Терміни |
|---|---|
| Корпоративний MVP, 8–12 екранів | 8–14 тижнів |
| Продукт з оффлайном та синхронізацією | 4–7 місяців |
| Платформа з інтеграцією корп. систем (SAP, 1C) | 6–12 місяців |
Вартість розраховується індивідуально після аналізу вимог та існуючої .NET-інфраструктури клієнта.
На що звертаємо увагу при аудиті
Три речі, які бачимо найчастіше в успадкованих MAUI-проектах: відсутність trimming-сумісності (застосунок важить 60+ МБ), використання застарілих Renderer із Xamarin.Forms замість переходу на Handler, та синхронні операції з БД на UI thread через EF Core без async/await. Останнє — гарантований ANR на Android.







