HERE SDK Explore for .NET MAUI
Cross-platform .NET MAUI bindings for the HERE SDK Explore Edition v4.25.5.0, supporting Android (API 24+) and iOS (15.2+).
📖 Full documentation — guides, architecture, and the complete API reference (DocFX).
Features
- Unified C# API — One idiomatic interface for both Android and iOS
- Map display — MapView control with camera, gestures, schemes
- Search — Text search, category search, auto-suggest, place details with dual-input origin/destination UX
- Routing — Car, truck, pedestrian, bicycle, scooter, EV routing with maneuvers and visual route display
- Traffic — Real-time traffic flow and incident queries
- Location — Device location via
ILocationService(cross-platform, MAUI Geolocation-based) - Map items — Markers, polylines, polygons, arrows, circles (polygon-approximated), 3D markers
Prerequisites
- .NET 10 SDK — Download
- .NET MAUI workloads —
dotnet workload install maui - macOS + Xcode 15+ — Required for iOS binding (Native Library Interop)
- Android SDK — API 34+ recommended
- HERE SDK credentials — Access Key ID and Secret from HERE platform
Quick Start
1. Install the NuGet package
<ItemGroup>
<PackageReference Include="HereSdk.Explore.Maui" Version="4.25.5.0" />
</ItemGroup>
2. Initialize in MauiProgram.cs
using Here.Explore.Maui;
builder.UseHereSdkExplore(new HereSdkOptions
{
AccessKeyId = "YOUR_ACCESS_KEY_ID",
AccessKeySecret = "YOUR_ACCESS_KEY_SECRET"
});
3. Add the map to your XAML
xmlns:here="clr-namespace:Here.Explore.Maui.Controls;assembly=HereSdk.Explore.Maui"
<here:HereMapView
x:Name="Map"
MapScheme="NormalDay" />
4. Use services
// Search
var results = await searchService.SearchAsync(
new TextQuery("coffee nearby"),
new SearchOptions());
// Routing
var route = await routingService.CalculateRouteAsync(
new[] { new Waypoint(start), new Waypoint(end) },
new RoutingOptions(TransportMode: SectionTransportMode.Car));
// Location
var location = await locationService.GetCurrentLocationAsync();
Reference App
The included reference app (HereSdk.Explore.Maui.RefApp) shows the library end-to-end: one shared map with overlay panels switched by a bottom tab bar, so routes, markers, and traffic drawn on one panel stay visible on all others.
- Explore — Text and category search with autocomplete suggestions, reverse-geocode place card on map tap
- Directions — Dual-input origin/destination routing with transport mode picker (car, truck, pedestrian, etc.), maneuver list, and isoline mode
- Traffic — Real-time traffic flow overlay with jam-factor color legend, incident list with severity indicators
- Tools — Drawing tools (Marker, Polyline, Polygon, Circle) added via tap gestures on the map, demo gallery presets, map style switching (5 schemes), dark mode toggle, Reset Map
Architecture
flowchart TD
MAUI["HereSdk.Explore.Maui<br/>Unified idiomatic C# API<br/>(Models, Services, Controls, Handlers)"]
AND["Android Binding<br/>(AAR → C#)"]
IOS["iOS Binding<br/>(NativeBridge → Sharpie → C#)"]
AAR["HERE Android SDK (AAR)"]
NB["NativeBridge Swift wrapper framework"]
SWIFT["HERE iOS SDK (Swift-only)"]
MAUI --> AND
MAUI --> IOS
AND --> AAR
IOS --> NB
NB --> SWIFT
NuGet Packages
| Package | Description |
|---|---|
HereSdk.Explore.Maui |
Cross-platform MAUI library (depends on platform bindings) |
HereSdk.Explore.Android.Binding |
Android AAR binding |
HereSdk.Explore.iOS.Binding |
iOS NativeBridge binding |
Most consumers should reference only HereSdk.Explore.Maui.
Why NativeBridge for iOS?
The iOS HERE SDK is Swift-only. Its ObjC bridge header exposes only 4 types — insufficient for binding. We create a Swift wrapper framework (HereSdk.Explore.iOS.NativeBridge) that re-exposes all APIs via @objc annotations, then bind that with Objective-Sharpie.
This is the standard pattern recommended by the MAUI Community Toolkit for Swift-only SDKs.
Building from Source
Android
# Build Android binding
dotnet build src/HereSdk.Explore.Android.Binding -c Release
iOS
# Build NativeBridge xcframework (requires Xcode + XcodeGen)
cd src/HereSdk.Explore.iOS.NativeBridge
xcodegen generate
cd ../..
./scripts/build-ios-native.sh
# Run Objective-Sharpie + fix bindings (optional — ApiDefinition.cs is already maintained)
./scripts/bind-ios.sh
# Build iOS binding
dotnet build src/HereSdk.Explore.iOS.Binding -c Release
MAUI Library
# Build for both platforms
dotnet build src/HereSdk.Explore.Maui -f net10.0-android -c Release
dotnet build src/HereSdk.Explore.Maui -f net10.0-ios -c Release
# Or use the build script
./scripts/build.sh
Reference App
# Android
dotnet build src/HereSdk.Explore.Maui.RefApp -f net10.0-android -c Debug
# iOS (requires macOS + Xcode)
dotnet build src/HereSdk.Explore.Maui.RefApp -f net10.0-ios -c Debug
Tests
# Unit tests (no device needed)
dotnet test tests/HereSdk.Explore.Maui.Tests -c Release
# RefApp in-process UI tests (ViewModel commands, control behavior, flows)
dotnet test tests/HereSdk.Explore.Maui.RefApp.UITests -c Release
# Appium Android smoke tests (requires emulator; runs in ui-tests-android.yml)
dotnet test tests/HereSdk.Explore.Maui.UITests -c Release
# Device tests (requires emulator/simulator)
dotnet test tests/HereSdk.Explore.Maui.DeviceTests -f net10.0-android -c Release
dotnet test tests/HereSdk.Explore.Maui.DeviceTests -f net10.0-ios -c Release
scripts/test.sh runs all four test suites end-to-end.
Packaging
# Pack all NuGet packages
./scripts/pack.sh
# Or with a custom version
./scripts/pack.sh 4.25.5.0-beta1
Packages are output to artifacts/.
Project Structure
here-sdk-for-maui/
├── src/
│ ├── HereSdk.Explore.Android.Binding/ # Android AAR binding
│ ├── HereSdk.Explore.iOS.NativeBridge/ # Swift wrapper (Xcode project)
│ ├── HereSdk.Explore.iOS.Binding/ # iOS C# binding
│ ├── HereSdk.Explore.Maui/ # Cross-platform MAUI library
│ └── HereSdk.Explore.Maui.RefApp/ # Demo/reference app
├── tests/
│ ├── HereSdk.Explore.Maui.Tests/ # xUnit unit tests (no device)
│ ├── HereSdk.Explore.Maui.RefApp.UITests/ # xUnit in-process VM/control/flow tests
│ ├── HereSdk.Explore.Maui.UITests/ # NUnit Appium Android smoke tests
│ └── HereSdk.Explore.Maui.DeviceTests/ # Platform device tests
├── scripts/ # Build, test, pack, docs scripts
├── docs/ # DocFX site (rendered to /site by DocFX)
├── Version.props # Centralized version numbers
└── tmp/ # SDK archives (gitignored; use HERE_SDK_CACHE)
Roadmap
| Phase | Scope | Status |
|---|---|---|
| 0 | Foundation: scaffolding, bindings, build infrastructure | Complete |
| 1 | MapView + SDK Init: map display, camera, gestures, markers | Complete |
| 2 | Search + Routing: full search & routing on both platforms | Complete |
| 3 | Traffic + Advanced: traffic, map items, advanced features | Complete |
| 4 | Polish + NuGet: coverage, packaging, CI/CD, ref app UX | Complete |
| 5 | Documentation: XML docs, DocFX pipeline, how-to guides | Complete |
| 6 | Final Release: pre-release gate, artifacts, GA publish | In Progress |
For per-phase task breakdowns and the live operational backlog see PLAN.md.
Key Design Decisions
- Unified API over platform exposure — Consumers use one C# interface; platform details are hidden
- Native Library Interop for iOS — Swift wrapper framework bridges the Swift-only gap
- MAUI Handler pattern — For
HereMapView, not legacy custom renderers - Record types for models — Immutable value types (GeoCoordinates, Route, Waypoint, etc.)
- Interface-driven services —
IMapService,IRoutingService, etc. for testability - TDD — Write tests first, then implement
Known Limitations
- No Windows/macOS Catalyst support — HERE SDK is Android + iOS only
- No CarPlay/Android Auto in unified API — platform-specific only
- iOS
RefreshRouteOptionsis deprecated and will NOT be bound - iOS binary size — xcframework is ~831 MB (stripped for release)
- macOS required for building iOS bindings (Xcode dependency)
- iOS feature gaps: map pick returns null (NativeBridge search-by-picked-place not yet wrapped)
- Location service uses
Microsoft.Maui.Devices.Sensors.Geolocationas primary source; HERE native positioning not yet exposed in iOS NativeBridge - Map circles are approximated as polygons (HERE SDK has no native circle primitive)
License
MIT