# MapMap Nav — Boilerplate

A full turn-by-turn navigation app for **iOS and Android**, built on the
**MapMap** SDKs with **Expo** (React Native). Use it as a starting point for
your own MapMap-powered nav app.

**What it does:** search by place, postcode or address (with reverse-geocode
tap-to-place); multiple route alternatives with a tap-to-select picker;
live turn-by-turn with voice, a 3D chase camera and a smoothed location puck,
a current-road banner, on-road manoeuvre arrows, lane guidance, and **posted
speed-limit signs with an over-limit warning**; **off-route GPS-follow +
auto-reroute**; truck/ADR routing profiles; saved places and recents; and a
scripted demo (Simulate) drive for testing without moving.

It ships with a **pure-TypeScript mock** of the MapMap native module, so you
can run and build on the entire app flow — with real online MapMap tiles —
**without a native build or the proprietary native SDK**.

---

## What's in the box

- `App.tsx` — the app shell, navigation, and screen wiring.
- `src/` — screens, UI components, map/route logic, state, replay/demo, theme.
- `modules/mapmap-react-native/` — a working first-draft **Expo module** that
  bridges the native MapMap Swift/Kotlin SDKs to JS. Includes:
  - `src/` — the JS API, typed events, and the **mock** (`mock.ts`) used when
    there's no native runtime.
  - `ios/` — Swift bridge source (`*.swift`, podspec).
  - `android/` — Kotlin bridge source (`*.kt`, `build.gradle`) plus JS-testable
    stubs.
  - `plugin/`, `app.plugin.js` — the Expo config plugin.
  - **Note:** the vendored native binaries (`ios/Vendored/*.xcframework`) are
    **not** included in this boilerplate — see the native-build caveat below.
- `assets/` — icons, splash, map puck/arrow art.
- `patches/` — `patch-package` patches applied to `expo-modules-core` /
  `expo-modules-jsi` needed for the native build.
- Docs: `PLATFORM-GOTCHAS.md`, `CONTRACTS.md`, `NAV-FEATURE-GAPS.md`,
  `DEMO-ROADMAP.md`, `FINDINGS.md`, `VERDICT.md`, plus `store/` and `privacy/`
  listing/policy drafts.
- `showcase/` — screenshots and notes from the reference build.

The generated native projects (`/ios`, `/android` at the repo root) are **not**
included — they are build output. Regenerate them with `npx expo prebuild`
(see the native-build caveat).

---

## Quick start (runs on the mock, no native build)

**Prerequisites:** Node 20 LTS, npm, and the Expo tooling (installed via
`npx expo`). A MapMap API key from <https://mapmap.ai> for the online tiles.

```bash
cp .env.example .env      # then paste your MapMap API key into both vars
npm install
npx expo start            # press i / a to open a simulator, or scan the QR
```

On first run the app uses the **JS mock** of the MapMap native module together
with **online MapMap tiles**, so you can drive the whole flow — search a
destination, build a route, start guidance, watch the puck move, hear voice
prompts, run the demo drive — **without compiling any native code**.

`.env` holds your key. `EXPO_PUBLIC_MAPMAP_API_KEY` is bundled into the app at
runtime (Expo only exposes `EXPO_PUBLIC_*` vars to client code);
`MAPMAP_API_KEY` is for build/tooling scripts. Put the **same** key in both.
**Never commit `.env`** — it is git-ignored on purpose.

Other useful scripts:

```bash
npm run typecheck   # tsc --noEmit
npm test            # vitest (unit tests, incl. the mock and map logic)
```

---

## Mock vs. native SDK — what works where

The module resolves one of two interchangeable handles via
`getMapmapNav(useMock)` (see `modules/mapmap-react-native/src/index.ts`):

| Capability | JS mock (Expo, `npx expo start`) | Real native SDK |
| --- | --- | --- |
| App UI, navigation, screens | ✅ | ✅ |
| Online MapMap map tiles (needs API key) | ✅ | ✅ |
| Search, route building, route lines | ✅ (simulated) | ✅ (real Valhalla routing) |
| Live guidance events + voice prompts | ✅ (scripted/simulated) | ✅ (real map-matching) |
| Location puck / demo drive replay | ✅ | ✅ |
| **Offline territories / offline routing** | ❌ | ✅ |
| **On-device map-matching against the real core** | ❌ | ✅ |

The mock is a faithful simulator of the native contract (`CONTRACTS.md`), which
is why the whole UX runs in Expo Go / a plain simulator. Anything that needs the
actual MapMap core (offline data, real map-matching) requires a native build.

---

## Native-build caveat (read before `expo prebuild`)

Producing a real native binary needs proprietary MapMap SDK access that is
**not** bundled here. Two known blockers — both documented in detail in
**`PLATFORM-GOTCHAS.md`**:

- **Android** — `ai.mapmap:core` is published on **GitHub Packages**, which
  requires a GitHub account and a `read:packages` personal access token even to
  download. Wire your token into Gradle before building.
- **iOS** — the pod links a **vendored `MapMapKit.xcframework`** (plus the
  Valhalla wrapper). Those binaries live under
  `modules/mapmap-react-native/ios/Vendored/` in the reference build and are
  **excluded from this boilerplate**; obtain the xcframework from MapMap and
  drop it in before `pod install`.

Rough native flow once you have SDK access:

```bash
npx expo prebuild          # regenerates /ios and /android
# add your GitHub Packages token (Android) + vendored xcframework (iOS)
npx expo run:ios           # or: npx expo run:android
```

See `PLATFORM-GOTCHAS.md` for the full punch-list (SDK packaging, the
CocoaPods ↔ SwiftPM wall, the `patch-package` patches, and more).

---

## Licence

See `LICENSE`.
