Kuratour — offline‑first multilingual audio tours built with Expo
Key Points
- Offline-first with predownloaded assets
- SQLite with versioned migrations
- High-accuracy GPS + expo-audio for hands-free tours
Summary
Kuratour is an offline‑first, multilingual audio tour app built entirely with the Expo SDK. It delivers GPS-triggered, hands‑free audio narration and offline maps by pre‑downloading assets (map tiles, images, audio), storing metadata and progress in SQLite, and switching automatically between online/offline modes. The app integrates expo-location for high‑accuracy tracking, expo-file-system for mirrored local storage, expo-sqlite for versioned metadata, and expo-audio for layered multilingual playback.
Key Points
-
Architecture
- Entire app built on Expo SDK (new architecture) using first‑party modules and community packages.
- Core modules: expo-location, expo-file-system, expo-sqlite, expo-audio, expo-video, expo-splash-screen, expo-application, expo-apple-authentication, @rnmapbox/maps.
-
Offline strategy
- Pre-download map tiles, audio, and images into the app Documents directory and store local URIs in SQLite.
- Mirror remote directory structure locally to simplify lookups and playback.
- Save tour metadata and visited locations in a versioned SQLite schema; use migrations for schema changes.
-
Data integrity and upgrade handling
- Detect app version changes with expo-application and trigger a Content Validation Bridge to re-verify files.
- Iterate offline tours and confirm each asset exists; queue background re-downloads if files are missing (addresses iOS Documents-directory edge cases).
-
Location and UX
- Implement a high‑accuracy background location watcher with Location.watchPositionAsync for precise, hands‑free triggers (timeInterval, distanceInterval tunable).
- Use a custom useOfflineDetector hook (with useFocusEffect) to prefer local SQLite data when a tour screen is focused.
-
Asset orchestration
- Sequential download flow: directions → main imagery → per-location audio/background tracks; then persist file URIs back to SQLite.
- Use expo-file-system utilities (Directory/File APIs) to create directories and conditionally download files only when missing.
-
Practical implementation notes
- Store complete tour objects as JSON in SQLite to make offline retrieval straightforward.
- Use a currentVersion integer and applyMigrations pattern to safely evolve the DB schema for live users.
- Validate filesystem proactively after upgrades to avoid broken “downloaded” tours.
Actionable takeaways for engineers
- Treat offline as a first-class requirement: design pipelines that mirror remote layout locally and persist local URIs into durable metadata.
- Use versioned SQLite migrations to evolve schema safely and to track downloaded content state.
- Add a version‑check + content validation pass on startup/upgrades to catch iOS file purges and auto‑requeue missing assets.
- Tune Location.watchPositionAsync (accuracy, timeInterval, distanceInterval) for your use case to balance battery vs precision.
- Keep downloads idempotent (skip existing files) and perform orchestration in deterministic steps to avoid partial states.