iOS · Active development
Peaking
Discover peaks, verify summits from your own routes, and track iconic hiking lists — offline-first.
For hikers and mountaineers who track summits, routes, and collection progress.
Jun 2024 → Present · iPhone · iOS 17+
Screenshots
-
Discover peaks on the map -
3D peak detail -
Mountain weather for every peak -
Browse published collections -
Track collection progress
Peaking is a mountain companion for hillwalkers and mountaineers. It maps the peaks around you, confirms a summit from the route you actually walked, and tracks your progress across the classic hiking lists — and it keeps working when the signal does not.
The interesting part is the verification: instead of a manual check-in, Peaking matches a summit against the GPS track from your Apple Watch or Strava activity, so your list of completed peaks reflects where you genuinely stood.
Features
- Interactive peak discovery map with clustering, filtering, and rich metadata.
- Route imports from Apple HealthKit (Apple Watch primary, with bridge-app support for Garmin / Polar / Suunto via HealthFit or RunGap) and Strava, with automated summit matching and GPX export for portability.
- Published and user-created collections (for example Munros and Wainwrights) with completion tracking.
- Offline-first cache layers for map tiles and peak data with cloud-synced personal progress.
Built with
- SwiftUI
- SwiftData
- CloudKit
- MapKit
- Overpass API (OpenStreetMap)
- HealthKit
- Strava API
- PhotosUI
- Charts
Development log
-
9 June 2023
First commit — the idea
A map that knows which summits you have actually stood on.
Read more
Peaking began as a simple question: could an app confirm a summit from the route you walked, rather than trusting a manual check-in? The first commit laid down a SwiftUI shell and a MapKit view. There was no persistence layer, no sync and no accounts — just enough to prove the map could hold a location and a pin. Everything else was deliberately deferred.
-
1 March 2024
SwiftData models and a summit record
The idea gets a data model — peaks, summits, and a real onboarding flow.
Read more
After a long quiet stretch the project resumed with a proper data layer: SwiftData models for summits, a create/delete flow for logging one, and an onboarding sequence that decoded a bundled peak list from JSON. Filtering by elevation and cross-checking against Strava downloads showed up early, establishing the core idea that a summit should be checkable against something external rather than just ticked by hand. The navigation was still a single list; tabs and a proper map came later.
-
11 March 2025
The OSM rewrite
A working-but-slow MapKit prototype is stripped back and rebuilt on OpenStreetMap data.
Read more
A first attempt at a map-first version shipped internally but performed poorly and its import pipeline did not work reliably, so it was deliberately stripped back to the key layout elements and rebuilt on new SwiftData models. The rebuild moved peak data onto OpenStreetMap nodes and relations via the Overpass API, with a dedicated map controller and an actor-isolated API layer to keep large node sets off the main thread. This is the point the app stopped being a demo and became an engineering problem: rendering thousands of peaks on a map without stalling it.
-
1 August 2025
CloudKit sync, HealthKit and Strava route matching
Route-based summit verification arrives, backed by CloudKit and an offline tile cache.
Read more
Collections (the app's name for hiking lists such as the Munros) were generalised across element types, and models were adjusted ahead of CloudKit compliance so a user's summits could sync across devices. This is when the verification idea from day one finally landed in code: a route summit search actor checked HealthKit workouts and, shortly after, Strava activities against nearby peaks to confirm a summit from the GPS track rather than a manual tap. A tile cache with a quick-load-then-refresh pattern kept the map usable offline, which set the pattern the app has followed ever since — local-first, sync second.
-
15 November 2025
Friends and achievements land before the tags do
Social features and progress tracking arrive ahead of any formal versioning.
Read more
Friends and Achievements tabs were added to the navigation, giving the app its social dimension — seeing what peaks friends had summited — well before the project adopted version tags. This period also carried the CloudKit migration warnings that come with any SwiftData-backed sync model: renaming a field is a one-way door once records exist in production, a lesson that shaped how cautiously the schema was changed from here on.
-
16 April 2026 v1.0
v1.0 — first public TestFlight
The map, collections, and route-verified summits reach a shippable whole.
Read more
The map, published collections (Munros, Wainwrights, and other classic UK hill lists), and HealthKit/Strava-verified summit tracking came together into something worth handing to external testers. Patch releases in the following days fixed onboarding and import edge cases surfaced immediately by real devices and real accounts, rather than the simulator.
-
20 April 2026 v1.1
v1.1 — DoBIH catalogue widening
A second UK hills database is folded in alongside OpenStreetMap.
Read more
The peak catalogue widened to include the Database of British and Irish Hills alongside OpenStreetMap, with cascading import, pre-matched merges against the existing mirror registry, and UI to surface DoBIH-only peaks inside downloaded collections. Getting two independent data sources to agree on the same hill without duplicating it turned out to be a bigger job than the map rendering that came before it.
-
22 May 2026 v1.2
v1.2 — Accolades, disambiguation, and a rebuilt launch flow
Achievements grow a proper identity system, search matures, and onboarding gets a full rewrite.
Read more
This cycle replaced the ad-hoc maintenance/processing screens with a single unified startup flow and folded onboarding into the same presentation system, so first-run and every-run app entry share one code path. A disambiguation formatter was built to distinguish peaks that share a name — surprisingly common — and wired through every list, map annotation, and picker in the app. Achievements ("Accolades") gained a record-holder type, and location-based search shipped alongside a first pass at tokenised full-text search across the whole peak catalogue.
-
4 June 2026 v1.3
v1.3 — Strava as a primary source
Strava graduates from optional extra to a primary way of confirming a summit.
Read more
Strava import was promoted from a secondary signal to a primary source alongside HealthKit for the Friends & Family beta, which meant tightening up route deduplication so activities recorded a year apart no longer merged into one. A collection-structure rubric was also introduced and enforced at import time, codifying rules for which sub-peaks belong inside a list versus standing alone — a decision that had previously been made by hand, list by list.
-
9 June 2026 v1.4
v1.4 — Grouped achievements and searchable settings
Achievements gain hierarchy, and Settings becomes searchable rather than browsed.
Read more
Achievements grew a parent/child structure so a family of related peaks could roll up into one meta-achievement, with a recursive evaluator and a dedicated peakingctl command to publish the hierarchy to CloudKit. Settings also stopped being something you scrolled to find: a search catalogue and pure matching engine were built and wired into every screen, including the developer tools, on the view that a growing app needs a way to find its own switches.
-
17 June 2026 v1.5
v1.5 — Making friend invites actually reliable
Connecting with a friend gets a typeable fallback and self-service recovery.
Read more
Friend invites had been fragile — a share link that failed silently, or a connection that got stuck with no way to tell why. This cycle added a typeable short-code as a fallback to the tappable CKShare link, plus visible connection status and self-service repair when a sync stalled. Underneath, several CloudKit zones needed a legacy-keyed rehydration path so existing connections survived the change rather than quietly breaking for anyone who had already added a friend.
-
22 June 2026 v1.6
v1.6 — A Photos tab and real-time friend activity
Photos become a first-class content type, and friend activity starts to feel live.
Read more
A new Photos tab unified photo feeds from every source into one gallery, with clustering on the map, cross-links back to the route or summit a photo was taken on, and deep links from a peak straight to photos taken there. Friend activity moved from a static list to something closer to real-time: notifications on a logged summit or earned achievement, plus a fix so removing a friend actually revoked their CloudKit access straight away rather than on the next sync.
-
30 June 2026 v1.7
v1.7 — Collections Browse convergence and a performance pass
Every collection surface adopts one shared browsing pattern, then gets a speed audit.
Read more
Collections, Summits, Routes, Friends and Achievements were brought onto a single shared "Browse" pattern — one List/Cards toggle and one inline sort-and-filter menu instead of several bespoke ones — closing out a rollout that had been running behind a feature flag for weeks. That convergence was followed immediately by a performance pass: friend-profile navigation that had been hanging for several seconds, and in one case nearly a minute, was traced to over-eager recomputation and fixed by fetching projections lazily instead of eagerly.