GK.Gergely Kovács
← Lab
Lab project

Bonvo Ski Maps

Native appiOS · Tourism2024 — 2026
Bonvo Ski Maps — hero image

Native iOS / macOS / watchOS ski mapping and navigation.

SwiftUI ski-resort mapping app across iOS, macOS and watchOS targets. 120 personal commits, MapKit / Mapbox-integrated rendering and offline routing for backcountry navigation.

Architecture

How it's built

A SwiftUI codebase that ships three targets — iOS, macOS and watchOS — from one shared core. SwiftData persists user state on the device; Supabase REST keeps profiles, saves and follows in sync across platforms; MapKit renders the primary UI while Mapbox carries the vector tiles and offline routing for backcountry slopes. RevenueCat gates the paid surfaces and Firebase + Microsoft Clarity provide the feature flags and session replay.

Data flow
  1. 01App launches — Firebase + Clarity initialise, RevenueCat checks the cached entitlement, Supabase session is restored.
  2. 02User authenticates — the bonvoski:// deep link returns from Supabase OAuth and SwiftData stores the refresh token.
  3. 03Map opens — MapKit lays down the base, Mapbox loads cached vector tiles, Core Location resolves the nearest resort.
  4. 04User saves a slope — the row is written locally (SwiftData) and queued for Supabase; the UI never waits on the network.
  5. 05Going offline — backcountry routing runs against the downloaded Mapbox tiles + Overpass slope data already on disk.
  6. 06User crosses a paywall — RevenueCatUI presents the sheet; on a successful purchase the entitlement is refreshed within 5 seconds.
Design decisions
  • Dual mapping pipeline — MapKit for native look and feel, Mapbox for vector data and offline tile downloads — chosen so backcountry sessions work without signal.
  • Three Apple targets share Core services through SwiftUI's Environment so the watch app is not a port, it is the same code with a smaller surface.
  • SwiftData is the offline canonical store; Supabase rows are reconciled on reconnect — the app never blocks on the network.
  • RevenueCat is polled every 5s while authenticated so an entitlement change (refund, churn) propagates without a relaunch.
  • Deep links via bonvoski:// route directly to resort / slope / lift screens — sharing a slope is a single tap.
External integrations
Supabase RESTMapKitMapbox SDKRevenueCatFirebase (Remote Config)Microsoft ClarityOverpass API