Android, iOS, Flutter, and React Native remain distinct release and lifecycle boundaries.
One capability. Four runtimes. Six lifecycle states.
Choose the exact mobile path you are shipping. The matrix preserves current version evidence, exposes missing overview coverage, and makes the host application—not the provider UI—the owner of durable state.
Place search, nearby, directions, geofence, and feedback are evaluated independently.
Every pairing is represented, including gaps in the current first-party overview.
The remaining 3 paths require product selection—not a guessed package.
Directions UI for React Native
- Documentation
- v2.0.0
- Component
- Direction Widget
- Version
- 2.0.1
- State model
- session
The current React Native overview lists Direction Widget 2.0.1 under documentation v2.0.0. Confirm the exact package, configuration, callback schema, and entitlement in the selected guide before binding the adapter.
Twenty paths. Every gap visible.
“Not listed” means the current overview does not establish a package. It does not mean the capability is impossible, and it never licenses reuse of another platform’s package.
Make every return, cancellation, and late callback explainable.
The generated scaffold deliberately stops at an application-owned candidate. Your repository decides whether and how that candidate becomes durable.
idle
No provider controller, route, Promise, delegate, or listener is active.
launching
One generation ID binds configuration, owner, and launch time.
active
Background, recreation, close, and duplicate-launch behavior are observable.
returned / cancelled / failed
Exactly one typed terminal result wins; late results are ignored.
candidate
Validate and normalize application route request/revision identity; provider ui is not a navigation session before committing.
committed
Persist the normalized selection/draft with version, actor, source, and audit event.
type PlaceSelection = { version: 1; mapplsPin: string; label: string };
interface MapplsPlaceWidget {
selectPlace(): Promise<unknown>;
}
async function choose(widget: MapplsPlaceWidget, generation: number) {
const value = await widget.selectPlace();
if (!isFocused() || generation !== currentGeneration()) return;
if (!isPlaceSelection(value)) throw new Error("invalid_widget_result");
commitCandidate(value); // Store normalized data, never the opaque native object.
}
function isPlaceSelection(value: unknown): value is PlaceSelection {
const item = value as Partial<PlaceSelection> | null;
return item?.version === 1 && /^[A-Za-z0-9]{6}$/.test(item.mapplsPin ?? "") && typeof item.label === "string";
}The widget is a collaborator, not your database.
One focused screen owns the native Promise, bridge generation, AppState changes, cancellation, and normalized JavaScript result.
Parse unknown bridge data into a versioned TypeScript value; do not store an opaque native result object.
Promise rejection, native cancellation, screen blur/unmount, bridge reload, and malformed data are typed separately.
The durable record is application route request/revision identity; provider ui is not a navigation session; never retain a provider view/controller or opaque bridge result.
Test the lifecycle you cannot demo.
Happy-path selection proves almost nothing about a production mobile integration.
Public repository and developer-documentation version drift is resolved before dependency pinning
Peer native SDK versions are compatible
Only the focused mounted screen accepts a Promise result
Bridge data is schema-validated
Fast Refresh and native recreation do not double-commit
Permission/configuration denied
Offline and slow provider response
Cancel before and after a candidate appears
Host edit invalidates a stale selection
Duplicate callback/Promise result commits once
Accessibility, focus return, and a non-widget fallback