iOS App for Data

Hi all,

I am a huge fan of and everything David has created here. I write apps as a hobby, and with David’s permission have created a fairly simple app called “FitnessFatigue” for iPhone allowing you to quickly see your Fitness, Fatigue and Form, as well as some overview information for individual workouts. I mostly created this as I wanted to have my Fitness, Fatigue and Form displayed on a “widget” on the Home Screen, this is also available.

Unfortunately I won’t be able to work on this app any further or add any new features as this was mostly created as a personal education project and I have a job in an entirely different field. However the code is open source and available here if anybody wishes to develop this project further.

The app itself is available here for anyone interested.

One caveat: The fitness and fatigue stats calculated for each day vary slightly from the website (usually by no more than 1). I think this is just a rounding issue that I’ve been unable to solve, but could potentially be fixed if David were able to provide this data through the API in the future (I’m well aware how busy he is…).

A screenshot of the widget is below, views of the rest of the app are available at the App Store link above.


Hi Matt,

Thank you for posting this. This looks really good… it would be good if someone could take this on and expand it further and add an Apple Watch app as well.

thanks for sharing this with the community.


That’s pretty cool. Thanks!
I wish I could code. Anyone who is going to take this on, I get get an Error: unable to retrieve data from server. :face_with_monocle:

@Matthew_Roche Cool!!

I actually had something coded up many months ago (Oct 2021 it seems). Never published, the code is still in the app, just not “used”

My Goal was just to populate this week’s summary data, Form/Fitness/Fatigue and some stats - eventually replacing what I’m using TrainingPeaks Free for.

I left the work “sitting” as the thought of the UI portion of it made my head spin… I just might poke around your UI and use that as “inspiration”, since i’m nearly done w/ my HR Target feature set, which is looking quite good if I do say so myself.

May I know your license terms?

Here’s the raw output dump which at a cursory glance, seems to tally. Tho I’ve not checked in detail in case some of the API output data has changed.

week#16 [Apr 18 - Apr 24]
 Current Load:38  Time:57m Dist:224.5 D+:0m   kJ:350  
 Current Fit :5   Fat:5   Form:0  
 Planned Fit :5   Fat:5   Form:0  

  Ride   : Load:200%[38/19] Time:77%[57m/1h 14m] Dist:100%[224/0km]
  Run    : Load:0%[0/0] Time:0%[00m/00m] Dist:0%[0/0km]
  Swim   : Load:0%[0/0] Time:0%[00m/00m] Dist:0%[0/0km]
  Others : Load:0%[0/0] Time:0%[00m/00m] Dist:0%[0/0km]
  All    : Load:200%[] Time:77%[] Dist:0%[]

====== START User Pref =========
  icuWeight:91 RestingHR:89
  0 userPref ["Ride", "VirtualRide"] - indoorFTP:100 FTP:200
  1 userPref ["Run", "VirtualRun"] - indoorFTP:123 FTP:123
  2 userPref ["Swim"] - indoorFTP:200 FTP:200
  3 userPref ["Other"] - indoorFTP:0 FTP:0
====== END   User Pref =========

=== ATL by Day ====
 "2022-04-18"	0
 "2022-04-19"	0
 "2022-04-20"	0.23
 "2022-04-21"	4.79
 "2022-04-22"	5.26
 "2022-04-23"	4.51
 "2022-04-24"	3.87
=== ATL by Day ====

  ==> Weekly Plan
       Load:["Ride": 19]
       Time:["Ride": 4440]
  ==> Weekly Real
       Load:["Ride": 38] Overall:38
       Time:["Ride": 3450] Overall:3450[57m]
       Dist:["Ride": 224569.648] Overall:224.6 km
       Elev:["Ride": 0.0] Overall:0 m
       Work:350 kJ
  ==> Weekly Target
  ==> Weekly Zones Times
       PwrPlan    :["Ride": [3882, 258, 120, 180, 0, 0, 0]])
       PwrReal    :["Ride": [1696, 1754, 0, 0, 0, 0, 0, 0]]
       HRReal     :["Ride": [1720, 0, 0, 0, 0, 0, 1730]]
       AllPwrPlan :[3882, 258, 120, 180, 0, 0, 0]
       AllPwrReal :[1696, 1754, 0, 0, 0, 0, 0, 0]
       AllHrReal  :[1720, 0, 0, 0, 0, 0, 1730]
  ==> Compliance
       Load:["Others": 0, "Run": 0, "Ride": 200, "Swim": 0]
       Time:["Ride": 77, "Swim": 0, "Others": 0, "Run": 0]
       Dist:["Ride": 100, "Run": 0, "Others": 0, "Swim": 0]
       All :["Dist": 0, "Load": 200, "Time": 77]
 ==> Fitness Status
       FIT(CTL):["2022-04-19": 0.0, "2022-04-24": 4.59, "2022-04-22": 4.81, "2022-04-23": 4.70, "2022-04-20": 3.91, "2022-04-18": 0.0, "2022-04-21": 4.70]
       FAT(ATL):["2022-04-23": 4.5, "2022-04-21": 4.79, "2022-04-18": 0.0, "2022-04-24": 3.87, "2022-04-20": 0.23, "2022-04-19": 0.0, "2022-04-22": 5.26]
       FORM    :["2022-04-18": 0.0, "2022-04-22": -0.26, "2022-04-23": 0.18, "2022-04-19": 0.0, "2022-04-24": 0.72, "2022-04-21": 0.20, "2022-04-20": 3.76]
1 Like

Nice! The fitness and fatigue data is now in the API. You can fetch it along with wellness data:

GET /api/v1/athlete/{id}/wellness{ext}?oldest=2022-04-20

If you use .csv then you need to supply a cols parameter: cols=atl,ctl,atlLoad,ctlLoad etc

1 Like

Well done, potential is there to add so much more.
Think of the possibility to add other metrics that give an all round score.

Just downloaded it, nice app and i’m keen to see more metrics there in future!

1 Like

Thanks for the feedback! I’ve just added an MIT license to the Github repository.

1 Like

Thanks for letting me know. I’ll take a look when I get a chance!

Any guess why I get this error?

I got the same error, and then changed the settings at the authorization step to read and write. Then it works. Not sure if that is the problem, but it worked for me.

Yeah, I tried that too. Also disabled my ProtonVPN temporarily to see if that was blocking something. Still no go.

Just downloaded it and its working seamlessly for me. Really clean and tidy interface too. Many thanks Matthew.


Omg please let there be an android dev who could knock one of these out on that platform too.

Hmmm. Thanks for letting me know, and sorry it doesn’t work for you. Not sure why this is happening, my best guess would be that your data is in a slightly different format to mine when it comes from the server. Do you sync from Strava or somewhere else?

Sorry you had the same problem. The app shouldn’t need any write permissions, so maybe this was a coincidence?

All my data goes directly from the devices to, or at least as directly as possible (i.e. FIT file in Dropbox if not direct sync). No Strava. No TP.

Mine is working, after I ticked all the boxes at the login stage.

Yup, tried that.

OK. My best guess is that the dates returned from the server for your activities are in a different format from those that come through Strava etc. This was a personal project so there was very limited testing and I have no remote debugging, sorry it’s not working for you.

I think I’ve probably found a work around, but would like to test it first. If you’re happy to do so could you send an example FIT file to