Barbell Builder

Barbell Builder is an iOS app made to calculate barbell configurations for weight lifting. In addition to the obvious physical effort, weight lifting takes a lot of mental effort. Towards the end of a session, concentrating on even simple computations becomes error prone. This app makes it easy to figure out how much weight you should be lifting, and how to arrange plates on the bar to make those weights.

There are other barbell apps available, but I haven't found any that calculate a barbell progression. In order to prepare the body for lifting a very heavy "working" weight, a lifter will lift progressively heavier weights leading up to it. A common progression is to start with the bar, lift three intermediate weights, and then lift the working weight. Barbell Builder makes it easy to specify how many sets to use in the progression and calculates the intermediate weights.

I started this project when iOS 6 was the current version, and ended up re-doing a lot of the interface work when iOS 7 was announced, because of the new version's very different aesthetic. The process taught me a lot about workflows for editing images (many visual assets need to be produced at a variety of sizes), and I discovered some tricks (compositing layered alpha-blended PNGs, for example) that let me produce subtle effects without code.

One of the most frustrating things I discovered in the process of development was just how non-thread-safe Core Data is. Core Data is Apple's object persistence framework. It's used like a database to store information that is available between runs of the program. Generally, it's quite nice to work with, however it suffers from the problem that an object that was loaded from the data store in one thread cannot safely be used in another thread. Because my initial implementation of barbell calculation was not instantaneous, I moved the processing into a background thread, so the UI would remain responsive. This caused all kinds of problems with Core Data access, prompting me to rewrite the calculations to use non-Core Data objects (and, ironically, to become so fast that they no longer needed to be done in a background thread).

A further problem came when restoring application state after the App was sent to the background (because the user started using a different App) and then returned. Some of that restoration process appears to happen in different threads, causing objects retrieved from the Core Data store unusable. This behavior is not consistent between the development simulator and actual devices, so I didn't discover that some of my assumptions were wrong until late in the development process.

The end result is that I'm now much more careful about how I use Core Data objects, and I know a lot more about threading and application state restoration on iOS.