For about five months, I was logging my climbs in a Google Sheet. For each climb I attempted I would take note of the date and location, the grade, the climb’s style (overhanging, crimpy etc.), how many attempts I had made, whether I had sent it and any other notes like how it felt, why it was hard or specifics about how I climbed it. It was alright but it was often frustrating and I didn’t feel like I was getting much value out of it.

  • I was using my phone to log data throughout my session and while a spreadsheet on a phone is never going to be enjoyable, it felt particularly cumbersome to navigate and read, especially mid-session.
  • My input was prone to typos and errors. I would often use the wrong keywords such as overhanging instead of overhung as a climb category or sent instead of send as the send type. These inconsistencies made the data difficult to to parse effectively.
  • Attempts were logged in chronological order with no unique identifier which lead to several common issues:
    • It was difficult to find previous attempts for a given climb. This meant it was hard to check if I had previously attempted or completed a climb and any notes I left myself for future use were often not considered.
    • There was no way to know if a given climb had been removed from the gym as part of the bi-weekly reset.
    • There were sometimes overlaps and confusion if there were multiple climbs of a certain style before and after a reset.
    • It was impossible to track metrics across sessions.

It became the case that all I was really tracking was the volume of climbing session to session, and the difficulty of climbs I was trying. I had ideas for much more interesting metrics but my current data wasn’t useful so I went looking for a better option.

Alternatives

There are other platforms which aim to provide a similar feature set none of them were suitable for my use case.

The Crag is an excellent platform which documents an enormous number of outdoor climbs across the world by allowing the climbing community to maintain documentation, photographs, topos and access information. It also allows users to log their attempts and track their progress over time. I personally use it as a guidebook and to track my outdoor climbs, but its features do not extend indoors and it requires logging to be done in batches, only making it useable after a session is finished.

Vertical Life and Toplogger are two apps which are purpose built for tracking indoor climbs and are supposed to be quite good. The issue is that they require the gym to sign up to the platform and provide all of the information about their current set of climbs, which none of mine have. I believe this is their method of monetising the platform, charging the gym for support and as such ndividual users don’t have the ability to create climbs.

With that, I decided to write my own app with the aim to be a flexible middle ground which offers enough structure to avoid the issues I found with my Google Sheet but enough flexibility to allow anyone to start tracking their climbs regardless of whether they are climbing in a gym, a home wall or outside.

Design

Requirements

I started by outlining what I needed sendrax to do differently from what I had tried and what was already available. I needed it to:

  • Be easy to add and remove climbs.
  • Support custom grade sets.
  • Be easy to use throughout a session.
  • Minimise opportunities for, and impact of, input mistakes.
  • Provide useful analysis and representations of the data.
  • Make navigation of the climb history easier so that I could quickly:
    • View a climb’s previous attempts.
    • Check which climbs have been repeated or sent.
  • Work offline as many climbing areas have spotty reception.

Technology

I wanted to take the opportunity to learn some new technologies and decided to write the app in Flutter. Flutter allows for one codebase to be compiled to mobile, web and desktop, ships with an excellent set of UI widgets and has an incredible development environment with hot reload in Android Studio.

I also decided to use Firebase for the data storage and the authentication. I do believe using a local SQLite store would have been more appropriate for this project due to the offline requirements and my desire to have all data available for the analysis. However, I wanted to learn to use Firebase, I wanted to try out Flutter’s Firebase support and Firebase’s Firestore offers robust offline data persistance out of the box.

Finally, I decided on the architectural pattern I would use for the app’s state management. Having used and enjoyed Redux before (See my use of redux in newtab) I decided to try BLoC, which distributes the application state across multiple stores, isolates the state from the UI and relies exclusively on streams for input and output.

This stack ended up being super enjoyable to use and allowed me to maintain a well structured and extensible codebase. All source code for this project is available on github.

Sendrax

Rather than wax philosophical about how this app gave my life meaning and how it could change yours as well, we will briefly visit each of the requirements and see how it was satisfied.

Easy to add and remove climbs

You first create a location (left), representing a climbing area, which can be anywhere you want to log climbs. A name and an image allow you to tell it apart from the others. You then select the grade set (optionally creating your own, see below) and add the list of sections, should your crag or gym have them.

You can then start adding climbs (right). Whether the climb is outdoors, and therefore named and more permanent, or indoors where it likely is unnamed, it is easy to fill out the form. The dropdowns are populated with the available sections and grades, and the user defined climb categories are laid out to minimise the time needed to add a climb mid-session.

When a climb at the gym is reset, you simply archive it (left) and keep going. Since many gyms rotate their sections through a reset schedule, you can archive an entire section with one tap (right).

Support custom grade sets

By default sendrax supports many of the major grading systems including YDS, French and Ewbanks for roped climbing and Font and V Scale for bouldering. However if your gym, like mine, uses their own banded or colour-coded system, you are often forced to make conversions to another scale in order to log them. This conversion adds a source of inaccuracy to any data collected as climbs which fit your style will feel relatively easier than those in your antistyle. Sendrax allows you to create your own custom grade set, thus eliminating this source of uncertainty and removing an extra step from your logging.

Easy to use throughout a session

Once you’re in a location, the climbs are listed by section and then by grade alongside their identifying information. The dropdowns at the top also provide the ability to filter the list of climbs ensuring that no time is lost searching for a specific climb.

Once in a climb, it takes as few as three taps to add a new attempt while the ability to add additional notes is also immediately available.

Minimise possibility and impact of input mistakes

By using dropdowns, there is no chance of incorrect input as there was in the Google Sheet while form validation ensures there is nothing missing (left). Any mistakes are easily rectified as you are able to edit your attempts as well as existing climbs and locations (middle). Finally, potentially destructive actions, such as deleting an attempt, are reversible (right).

All of these features ensure that even as the session is nearing an end, the mental load of using the app is minimal and the data doesn’t suffer fot it.

Provide useful analysis and representations of the data

Sendrax keeps track of many useful metrics including:

  • The number of attempts, split by send type, and tracked against
    • Date
    • Day
    • Time
    • Grade
    • Location
    • Climb category
  • Average attempts required to send a climb for a given grade
  • Average number of times a climb is repeated for a given grade
  • Proportion of climbs downclimbed, split by send type, for a given grade
  • Highest grade for a given send type tracked against time
  • Average grade for a given send type tracked against time

The attempts used to generate these plots are further filterable by grade, timeframe, location, send type and category.

View a climb’s previous attempts

Attempts are already grouped by climb so once a climb is open, all previous attempts are available (left). However Sendrax also provides a history view for digging through past sessions and viewing climbs which have been archived from a location. If you’re looking for a specific you are able to use this view to apply filters to track it down (right).

Check which climbs have been repeated or sent

Within a location, all climbs have a status icon to show whether they have previously been sent or repeated. Climbs can also be filtered by theses attributes allowing you to guide your session toward unsent, sent but unrepeated or only repeated problems.

Work offline as many climbing areas have spotty reception

This requirement is fulfilled by Cloud Firestore as it provides offline data persistance by maintaining a cache on the the device. While offline, this cache can be accessed and queried through the SDK in the same way as if you were online and any changes to the local data is synchronised when connection is restored (even across app usage sessions). By setting the cache size to CACHE_SIZE_UNLIMITED it is possible to maintain a local copy of all documents which ensures all data is available for analysis and minimises the data usage of the app.

Future Development

Using the app to track my climbs for ~2 months before covid hit, it honestly felt feature-complete. However I would like to:

  • Take advantage of Flutter’s multi-platform capabilities and release builds for web and desktop.
  • Investigate CodeMagic’s builds to release an ipa for iOS.
  • Develop an accompanying dashboard to track other training activities such as hangboarding or campus boarding. Though I really don’t want to write the world’s thousandth workout app…