Skip to Content

.NET MAUI SDK

AppSpacer.Maui — Asset OTA updates and crash reporting for .NET MAUI and Xamarin apps.

Update model: App store guidelines prevent native code hot-swap. AppSpacer for MAUI delivers asset OTA updates — JSON configs, images, data files — that your app reads from the OTA cache at runtime.


Requirements

Minimum
.NET8.0
MAUI8.0
iOS target14.2
Android minSdk21

Installation

dotnet add package AppSpacer.Maui

Initialization

Call AppSpacer.InitializeAsync() in MauiProgram.cs or your app startup:

using AppSpacer; public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.UseMauiApp<App>(); return builder.Build(); } } // In App.xaml.cs constructor: public App() { InitializeComponent(); _ = AppSpacer.AppSpacer.InitializeAsync("your_api_key", "1.0.0"); MainPage = new AppShell(); }

Config Options

await AppSpacer.AppSpacer.InitializeAsync(new AppSpacerConfig("your_api_key", "1.0.0") { ServerUrl = "https://api.appspacer.com/api", Strategy = UpdateStrategy.OnInit, CrashReportingEnabled = true, DebugLogging = false, MaxBreadcrumbs = 50, });
PropertyTypeDefaultDescription
ApiKeystringRequiredYour AppSpacer API key
AppVersionstringRequiredCurrent app version
ServerUrlstringhttps://api.appspacer.com/apiCustom backend URL
StrategyUpdateStrategyOnInitOnInit, Background, or Manual
CrashReportingEnabledbooltrueCapture unhandled exceptions
DebugLoggingboolfalseVerbose console logging

Reading OTA Assets

using AppSpacer; // JSON config (e.g. feature flags) var flags = await AppSpacer.AppSpacer.ReadAssetJsonAsync("config/flags.json"); bool showNewUi = flags?.ContainsKey("new_ui") == true && (bool)flags["new_ui"]; // Raw bytes (e.g. image) byte[]? imageBytes = await AppSpacer.AppSpacer.ReadAssetAsync("images/banner.png"); // UTF-8 string string? csvContent = await AppSpacer.AppSpacer.ReadAssetStringAsync("data/products.csv");

Manual Update Check

var result = await AppSpacer.AppSpacer.CheckForUpdatesAsync(); switch (result.Status) { case OTAUpdateStatus.Updated: Console.WriteLine($"Updated {result.UpdatedCount} asset(s)"); break; case OTAUpdateStatus.NoNetwork: Console.WriteLine("Offline — will retry next launch"); break; case OTAUpdateStatus.Failed: Console.WriteLine($"Error: {result.Error}"); break; }

Crash Reporting

// Report a handled exception try { await RiskyOperationAsync(); } catch (Exception ex) { await AppSpacer.AppSpacer.ReportErrorAsync(ex, context: "PaymentFlow"); } // Breadcrumbs AppSpacer.AppSpacer.AddBreadcrumb("User tapped checkout", category: "navigation"); AppSpacer.AppSpacer.AddBreadcrumb("Cart loaded", level: BreadcrumbLevel.Info);

Unhandled exceptions (AppDomain.UnhandledException) and unobserved Task exceptions are captured automatically when CrashReportingEnabled is true.


API Reference

MethodDescription
AppSpacer.InitializeAsync(apiKey, version)Initialize — call at app startup
AppSpacer.CheckForUpdatesAsync()Check and download new assets
AppSpacer.ReadAssetAsync(key)Read cached asset as byte[]
AppSpacer.ReadAssetStringAsync(key)Read cached asset as string
AppSpacer.ReadAssetJsonAsync(key)Read and parse cached JSON asset
AppSpacer.ClearAssetCacheAsync()Delete all cached assets
AppSpacer.CacheSizeAsync()Total cached bytes
AppSpacer.ReportErrorAsync(ex)Report a handled exception
AppSpacer.AddBreadcrumb(message)Add crash context breadcrumb
AppSpacer.SessionIdCurrent session identifier

Backend Integration

GET /api/sdk/maui/manifest Headers: x-api-key: <your_api_key> Query: app_version, current_bundle_id, install_id POST /api/sdk/maui/report-status Body: { release_id, device_id, app_version, status, error_message }

Send install_id (a stable per-device ID) on every manifest call — it is required for staged-rollout targeting and monthly active-user metering. Report installed/failed back to report-status so egress is billed once per device and failed installs can trigger auto-rollback.

Upload asset bundles from the dashboard with --platform maui.

Last updated on