GeoARSDK with Jetpack Compose
WemapGeoARComposeSDK adds one composable, WemapGeoAR, over WemapGeoARSDK's GeoARView. It is the Compose
counterpart of GeoAR in the iOS SDK's SwiftUI layer.
For the View-based API — and for creating a session, which is identical either way — see GeoARSDK Getting Started. Much of this page mirrors MapSDK with Jetpack Compose; only the differences are spelled out here.
Installation
implementation("com.getwemap.sdk:geo-ar-compose:<version>")
It brings com.getwemap.sdk:geo-ar with it, and requires minSdk 24 and Java 17 — ARCore and SceneView
set that floor, not this module. A Compose BOM of 2026.06.01 or newer is needed.
Usage
@Composable
fun ARScreen(session: CoreSession, locationSource: LocationSource) {
var arView by remember { mutableStateOf<GeoARView?>(null) }
WemapGeoAR(
session = session,
modifier = Modifier.fillMaxSize(),
onLoaded = { view ->
arView = view
view.locationManager.locationSource = locationSource
},
onFailed = { error -> Log.e("GeoAR", "Failed to load the AR view", error) }
)
val coordinate by (arView?.locationManager?.coordinates ?: emptyFlow())
.collectAsStateWithLifecycle(null)
coordinate?.let { CoordinateReadout(it) }
}
Camera permission must be granted before this composable enters composition, and the scene needs a
LocationSource from WemapPositioningSDK attached to locationManager to be positioned at all.
Parameters
| Parameter | Purpose |
|---|---|
session | The session this view renders. Required. Note the type is CoreSession, not MapSession. |
modifier | Standard Compose modifier. |
config | GeoARViewConfig. Read once, at creation. |
isOpaque | Whether the scene draws an opaque background. Read once, at creation; ignored when factory is supplied. |
onLoaded | Invoked with the loaded AR view. Its managers are available from here on. |
onFailed | Invoked with the loading error. |
onPhaseChange | Every LoadPhase transition, including the initial Loading. |
factory | Builds the view — see below. |
What is deliberately missing
- No camera state.
WemapMaphascameraPositionStatebecause a map camera is app state you may want to persist, restore or drive. The AR camera follows the device and the user's position, so there is nothing to drive. This matches the iOS SDK, whereGeoARhas no camera binding either. - No
onTouch. The Map SDK reports taps that selected no POI; the AR scene has no equivalent signal. CollectpointOfInterestManager.touchedPoisfor the taps that did hit something. - No wrapper parameters for the user coordinate, navigation info or POI selection. They are already flows —
locationManager.coordinates,navigationManager.navigationInfoUpdates,pointOfInterestManager.selectionUpdates— socollectAsStateWithLifecycle()reads them directly.
factory is not for a subclass here
WemapMap's factory exists for integrators with a WemapMapView subclass. GeoARView is final, so this
one exists for a different reason: reaching the constructor arguments the composable does not expose, above all
sharedLifecycle.
Supply it when the view tree has no lifecycle owner for the view to discover — a plain ComposeView inside a
Dialog, for example:
val lifecycle = LocalLifecycleOwner.current.lifecycle
WemapGeoAR(
session = session,
factory = { context -> GeoARView(context, sharedLifecycle = lifecycle) }
)
Note this is safe on GeoARView — unlike WemapMapView, where assigning the lifecycle before the view attaches
would drop its save-state registration. GeoARView has no save state.
Everything else
Session ownership, onLoaded not being replayed, and mirroring an event flow into state all work exactly as on
the Map side — see MapSDK with Jetpack Compose.