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.
-
10 July 2026 v1.8
v1.8 — Background import and friends on the shared map
Activities sync while the app is closed, and friend summits land on the shared map.
Read more
Strava activities now import passively in the background: GPS tracks from Garmin, COROS, Wahoo, Suunto and Polar watches sync automatically through Strava without opening the app. Friends' summits can be plotted directly onto the shared map, giving a unified view of where your climbing partners have been. And peak and collection detail screens are now fully customisable — sections can be reordered or hidden entirely to put the information you care about most first.
-
22 July 2026 v1.9
v1.9 — Connections that repair themselves, and lighter Strava imports
Stalled friend connections surface with a one-tap fix, and route detail loads on demand.
Read more
Friend connections that had quietly gone stale now surface in a "needs attention" list with a single action to reconnect or repair them, instead of failing silently and leaving both people guessing. Strava imports moved from fetching every route up front to pulling the detail only when a route is opened, which makes a large history far quicker to bring in. Long lists gained a consistent "view all" affordance rather than truncating without saying so, and a searchable FAQ landed alongside a settings search that finds options by what you are trying to do rather than by what the setting happens to be called.
-
23 July 2026 v1.10
v1.10 — Aerial 3D on the main map, and the trail catalogue doubles
A cinematic orbit of any summit, and roughly twice as many trails to follow.
Read more
Aerial 3D moved out of a small inset and onto the main map: choose a peak and the camera flies in and orbits the summit over terrain and satellite imagery until you touch the screen to take over. The trail catalogue roughly doubled — including a corrected set of Scotland's Great Trails — and trails gained a tagging model, so they can be browsed by the kind of walk they are rather than only by name. Peak detail also folded weather into the same reorderable section layout as everything else, so it can be moved or hidden like any other section.
-
24 July 2026 v1.11
v1.11 — Image-forward browsing
A cards view across every content type, with photography leading.
Read more
Peaks, trails and achievements all gained an image-forward cards view, so browsing leads with photography instead of a column of names. Favourite and pin became one consistent gesture everywhere — the same swipe, the same long-press menu, the same badges — across peaks, routes, summits, collections, trails and photos, replacing several near-identical implementations that had drifted apart. Card images are now fetched ahead of being scrolled to, so a grid fills in rather than resolving under you.
-
8 August 2026 v1.12
v1.12 — One layout system behind every list
Every tab and detail view rebuilt on a shared section host, so sorting, filtering and display modes work the same way everywhere.
Read more
Peaks, summits, routes, collections, trails and achievements had each grown their own version of the same screen. They now share one compositional host: the same section headers, the same sort and filter menus promoted into the toolbar, and the same list, cards and gallery display modes, with sensible defaults per surface and a migration so existing choices carry over. "View all" destinations inherit the mode of the section they came from rather than resetting to a plain list. Cards mode got the attention it needed along the way — long-press now targets the card under your finger instead of the first one in the row, previews show real content, tiles are square, and favourite and pin badges render consistently across rows, cards and map annotations. Elsewhere: panning during an Aerial 3D orbit hands control straight back to you, trails cluster on the map and shift their icon into frame when only partly visible, and an expanded weather day covers the whole day rather than cutting off before sunset.
-
8 August 2026 v1.13
v1.13 — Pinning that holds, and a calmer first run
Pinned content stays put and sorts first across every list, and launch explains what it is still doing.
Read more
Pinning became a promise rather than a preference. Pinned peaks, routes, summits, collections and trails now stay in the "in view" lists even when the map has moved off them, and they sort to the top with an animation — the same rule on every content type, annotated in the sort menu so it isn't a surprise. Launch and onboarding got their own pass: the step icons animate the search they describe and take their colours from the map, work that carries on in the background after launch is surfaced as a summary card with a post-launch indicator, and widget deep links survive a cold start instead of being dropped while the launch views still own the screen. Aerial 3D gave up its orbit and became a map style you stay in control of — satellite imagery, elevation and a steep pitch, held rather than animated at you. Trails read better on the map too, with the right cluster colour, an in-view list that matches what is actually on screen, and faster annotations. Strava activity titles no longer risk leading with a street address.