Honua Mobile SDK for .NET

August 13, 2026 · View on GitHub

CI Live Server Integration OpenSSF Scorecard License

.NET MAUI mobile SDK for Honua Server, the multi-protocol cloud-native geospatial server. It gives .NET mobile developers an offline-first foundation for field apps: GeoPackage storage, gRPC-first transport with REST fallback, dynamic field-collection forms, routing, 3D scene metadata, and connectivity-aware background sync. It also ships @honua-io/embed, a framework-agnostic web component package for embedding Honua maps and scenes.

This repo is the SDK (libraries, reference apps, templates). If you want a ready-made field data collection app built on this SDK, see honua-collect.

Status

Pre-1.0, alpha. Package contracts can still change between releases — see the SDK Contract Stability Roadmap for the alpha → beta → stable exit criteria and docs/guides/mobile-sdk-backlog-roadmap.md for the backlog roadmap. The source-backed feature map (what is actually implemented vs. planned) is in docs/features/README.md.

Packages

PackagePurposePublished
Honua.Mobile.SdkTransport, auth, gRPC-first client, REST fallback, routing, and SDK scene metadata adapterNuGet on GitHub Packages, from signed mobile-dotnet-v* release tags
Honua.Mobile.OfflineGeoPackage storage, sync queue, map area download, conflict resolutionsame
Honua.Mobile.MauiMAUI service registration, DI extensions, native display boundaries, native scene anchoring, and device location orchestrationsame
@honua-io/embedFramework-agnostic <honua-map> and <honua-scene> web components (plus React/Vue/Angular wrappers) for ISV embedsnpm on GitHub Packages, via the embed publish workflow (mobile-embed-v* release tags or manual dispatch)

The library packages target net10.0 and build on any platform without the MAUI workload. The reference apps and templates are .NET MAUI (net10.0-android, plus net10.0-ios/net10.0-maccatalyst on macOS and net10.0-windows on Windows). Platform-neutral client logic comes from the honua-sdk-dotnet Honua.Sdk.* packages, pinned as a single release train in Directory.Build.props.

Quick Start

// In MauiProgram.cs
using Honua.Mobile.Maui;
using Honua.Mobile.Offline.GeoPackage;
using Honua.Mobile.Offline.Sync;
using Honua.Mobile.Sdk;

builder.Services
    .AddHonuaMobilePlatformAuth()
    .AddHonuaMobileSdk(new HonuaMobileClientOptions
    {
        BaseUri = new Uri("https://your-honua-server.com"),
        GrpcEndpoint = new Uri("https://your-honua-server.com"),
        PreferGrpcForFeatureQueries = true,
    })
    .AddHonuaRouting()
    .AddHonuaScenes()
    .AddHonuaApiOfflineUploader()
    .AddHonuaMobileFieldCollection()
    .AddHonuaGeoPackageOfflineSync(
        new GeoPackageSyncStoreOptions
        {
            DatabasePath = Path.Combine(FileSystem.Current.AppDataDirectory, "honua-offline.gpkg"),
        },
        new OfflineSyncEngineOptions
        {
            ConflictStrategy = SyncConflictStrategy.ClientWins,
            BatchSize = 50,
        })
    .AddHonuaMapAreaDownload()
    .AddHonuaBackgroundSync();

After sign-in or bootstrap, store the API key or bearer token with IAuthTokenProvider.StoreTokenAsync(...); the platform auth registration persists it in iOS Keychain or Android secure storage.

See docs/getting-started/ for installation, a full tutorial, and the field collector project template (templates/honua-fieldcollector), and examples/ for runnable samples (field data collection, embeds, scenes, AR utility visualization).

Key Features

Offline Sync

GeoPackage-backed offline storage with queue-based sync:

  • GeoPackage storage -- standards-compliant .gpkg files (interoperable with QGIS, ArcGIS)
  • Sync queue -- queued edits with claim/lease semantics to prevent duplicate processing
  • Conflict resolution -- ClientWins, ServerWins, or ManualReview strategies
  • Background sync -- connectivity-aware with periodic timer and semaphore gating
  • Map area download -- offline basemap packages with path traversal protection
  • Delta sync -- replica-based incremental downloads with cursor persistence
  • Cache governance -- per-layer TTL eviction and R-tree-backed bbox lookups for replicated features

See docs/guides/offline-sync.md.

Field Collection

  • SDK-owned contracts -- Honua.Sdk.Field owns form schemas, validation, calculated fields, duplicate detection, and record workflow
  • Mobile capture adapters -- local media paths stay mobile-owned and convert to portable SDK attachment metadata before sync
  • Validation and workflow DI -- AddHonuaMobileFieldCollection() registers a mobile adapter over SDK field services

gRPC Transport

gRPC-first with automatic REST fallback:

var request = new QueryFeaturesRequest
{
    ServiceId = serviceId,
    LayerId = layerId,
    Where = "1=1",
    OutFields = new[] { "*" },
};

using var features = await client.QueryFeaturesAsync(request);

await foreach (var page in client.QueryFeaturesStreamAsync(request))
{
    using (page)
    {
        ProcessFeaturePage(page.RootElement);
    }
}

Transport security enforced -- API keys and bearer tokens are never sent over HTTP unless AllowInsecureTransportForDevelopment is explicitly set.

Routing

Experimental GeoServices-compatible NAServer client for directions, service areas, closest facility, and route optimization:

var route = await client.Routing.GetDirectionsAsync(
    RoutingLocation.FromLatitudeLongitude(21.3069, -157.8583, "Start"),
    RoutingLocation.FromLatitudeLongitude(21.2810, -157.8037, "Finish"));

var optimized = await client.Routing.Route()
    .From(currentLocation)
    .Via(jobSite)
    .To(depot)
    .WithTraffic()
    .AvoidTolls()
    .ExecuteAsync();

var reachable = await client.Routing.GetServiceAreaAsync(depot, TimeSpan.FromMinutes(30));

3D Scene Metadata

Scene discovery resolves server-managed 3D Tiles and terrain URLs before a renderer loads them:

using Honua.Sdk.Abstractions.Scenes;

var scene = await client.Scenes.ResolveSceneAsync(
    "downtown-honolulu",
    new HonuaSceneResolveRequest
    {
        RequiredCapabilities = new[] { HonuaSceneCapabilities.ThreeDimensionalTiles },
    });

var tilesetUrl = scene.TilesetUrl;
var terrainUrl = scene.TerrainUrl;

Migrating from the ArcGIS Maps SDK for .NET

Moving a MAUI/Xamarin field app off the ArcGIS Maps SDK? See the migration guide (API-idiom mapping table, phased reimplement plan, transition bridge) and the honua-migrate-maui codemod CLI under tools/. For platform-agnostic field-platform migrations (Fulcrum, Survey123, KoBo) see the Migration Guide.

Validation Status

LayerStatusRun onCoverage
Unitevery PRAcross the SDK, Offline, FieldCollection, and MAUI .NET projects
Integration (in-process loopback)every PRHonua.Mobile.ServerIntegration.Tests against a real ASP.NET Core loopback server
Smokeevery PRHonua.Mobile.Smoke.Tests (quality-gates job)
Embed DOMevery PRjsdom suites under src/Honua.Embed/tests/
Live server (Docker image)every PR via the Live Server Integration workflow (hard gate)LiveHonuaServerInteractionTests (incl. unary + server-streaming live gRPC); Testcontainers spins up honuaio/honua-server:nightly + PostGIS with the vendored seed at tests/seed/mobile-offline-demo-v1.sql
Cloud acceptance (staging)🟡manual workflow_dispatchDisconnectedFieldWorkflowAcceptanceTests; production promotion blocked on honua-server#965
Physical device🟡deferred to GAAR/VR field workflow follow-ups in docs/guides/native-scene-anchoring-requirements.md; emulator/simulator platform smoke covers part of the surface

Exact test counts are intentionally not pinned here (they drift every PR); the authoritative numbers are the per-project totals reported by each CI run. See docs/guides/validation-strategy.md for the per-capability coverage matrix, known gaps, and which CI workflow runs which bucket, and Disconnected Field Workflow Harness for the live-server workflow's scope and triggers.

Repository Structure

src/
  Honua.Mobile.Sdk/           Core mobile client: transport, auth, gRPC/REST, routing, scenes
  Honua.Mobile.Offline/       GeoPackage storage, sync engine, conflicts, map download
  Honua.Mobile.Maui/          MAUI platform integration, native display, location, scene anchoring
  Honua.Embed/                @honua-io/embed web component package (tests/ inside)
apps/
  Honua.Mobile.App/           Reference MAUI application
  Honua.Mobile.FieldCollection*/  Field collection reference app + core library
tools/
  Honua.Migrate.Maui*/        ArcGIS Maps SDK -> Honua migration codemod + CLI
templates/                    honua-fieldcollector project template
examples/                     Field collection, embed, scene, and AR samples
tests/                        Sdk / Offline / FieldCollection / Maui / ServerIntegration /
                              Smoke / PlatformSmoke test projects; tests/seed has the vendored seed SQL
contracts/                    Cross-repo SDK contract harmonization fixtures
docs/                         Getting started, guides, feature map, API reference

Building

Fresh checkouts need access to the private Honua GitHub Packages feed for Honua.Sdk.* packages. Use a GitHub token that can read packages in the honua-io organization:

gh auth refresh -s read:packages
export HONUA_GITHUB_PACKAGES_USER="$(gh api user --jq .login)"
export HONUA_GITHUB_PACKAGES_TOKEN="$(gh auth token)"

Then run the local validation baseline:

scripts/validate-local.sh

The script restores, builds, runs .NET tests and smoke tests, verifies format for the core source projects, and runs the @honua-io/embed npm build/tests. It uses a temporary NuGet config for HONUA_GITHUB_PACKAGES_TOKEN and removes it on exit. Without those environment variables it falls back to any existing NuGet credentials already configured for the github-honua source.

Equivalent manual commands:

dotnet restore Honua.Mobile.sln
dotnet build Honua.Mobile.sln
dotnet test Honua.Mobile.sln
dotnet test tests/Honua.Mobile.Smoke.Tests/Honua.Mobile.Smoke.Tests.csproj
npm ci --prefix src/Honua.Embed
npm run build --prefix src/Honua.Embed
npm test --prefix src/Honua.Embed

Building Android targets requires a configured Android SDK; iOS/Mac Catalyst targets require macOS with Xcode. The library projects target net10.0 and build on any platform without the MAUI workload.

The server integration project starts a real ASP.NET Core loopback server and exercises the SDK, offline, FieldCollection auth, and mobile exception-reporting HTTP paths without external infrastructure. Opt-in live Honua image tests run when HONUA_MOBILE_LIVE_SERVER_TESTS=1 is set (Testcontainers or a pre-started Honua URL; see docs/guides/offline-sync.md). The smoke test project can also run an optional live Honua query when HONUA_MOBILE_SMOKE_BASE_URL, HONUA_MOBILE_SMOKE_SERVICE_ID, HONUA_MOBILE_SMOKE_LAYER_ID, and optionally HONUA_MOBILE_SMOKE_API_KEY are set.

Release workflow, branch-protection, package metadata, Dependabot, Trivy, and platform smoke guardrails are documented in Repo Scaffolding Gates.

Documentation

RepoWhat it is
honua-serverFlagship multi-protocol geospatial server this SDK talks to
honua-collectOffline-first field data collection app built on this SDK
honua-sdk-dotnetPlatform-neutral Honua.Sdk.* .NET packages this repo consumes
honua-sdk-jsJavaScript/TypeScript SDKs + MCP server
honua-consoleUnified web console (Studio, Catalog, Operate, Share)
honua-helmHelm chart for deploying Honua Server on Kubernetes

Security

Report vulnerabilities to security@honua.io -- see the org security policy. Do not open public issues for security reports.

License

Apache 2.0