Stuart Breckenridge

Running Without Apple Watch Workouts

This week I’ve been running every day: five days on the treadmill and one day pounding the pavement. I could have used the Workout app on my Apple Watch to track these workouts, but it lacks basic functionality that all other fitness trackers have, which make it of little use to me.

#####A Lack of Context After completing any workout which is tracked by the Apple Watch, the resulting data set is shipped into Activity app 1 on your iPhone. From there you can see:

  • Type of Workout
  • Active/Total Calories
  • Total Time
  • Total Distance
  • Average Pace (plus Splits)
  • Average Heart Rate

Things you can’t see, which result in a lack of context:

  • Maps (for outdoor activities)
  • Heart Rate at any given point on a run
  • Elevation (for outdoor activities)

Maps are perhaps my most sought after feature. If I want to know where on a route I am gaining or losing time, they are essential. If I want to recall where my Saturday Morning Run was a year ago, they are essential. It’s something Apple could easily implement, given that they have their own mapping service.

These features are available–and have been for a long time–in competitor apps such as RunKeeper or Strava.

#####Inability to Edit Another bugbear is the inability to edit workouts logged by Apple Watch. For outdoor workouts, this is OK, as I’ve found the GPS to be accurate. For indoor workouts, it’s criminal. For every 5KM run I’ve completed on a treadmill, Apple Watch has logged it as somewhere in between 4.25KM and 4.75KM2. Once it’s logged, that’s it, forever inaccurate.

I’ve been using RunKeeper this week. Workouts has been a huge letdown.

  1. And the Health app. ↩︎

  2. This is after several hours of outdoor calibration runs. ↩︎

— Supported by —

Matt LeBlanc to Co-Host New Top Gear

Via the BBC Media Centre:

Iconic American actor Matt LeBlanc has today been revealed as one of the new presenters of the upcoming and eagerly awaited return of Top Gear - the planet’s biggest motoring entertainment show.

LeBlanc’s appointment marks the first time the show has ever had a non-British host in its 39-year history.

In what promises to be an explosive cocktail of car-obsessed entertainers and cultural clashes - the eagerly anticipated return of the revamped show is expected to noisily announce itself on BBC Two and TV screens everywhere this May.

An inspired choice. I genuinely hope that the new Top Gear and the as yet unnamed Clarkson, Hammond, and May show, are good!

Innovation Time. Or Not.

Adrian Kingsley-Hughes for ZDNet:

…Apple is facing a challenge that it’s not previously faced with the iPhone, and that is that sales have plateaued.

Have they? Based on the results of one financial quarter this is quite a statement. I’m sure it takes into consideration the pent up demand that existed for larger screened iPhones that resulted in huge sales for iPhone 6 and 6 Plus. I’m sure it also takes into consideration the 60%1 of users on pre-iPhone 6 devices that haven’t yet upgraded.

On the subject of the innovation needed for the iPhone 7:

Think there’s not much left that Apple could do? Think again! Here are just a few ideas off the top of my head:

  • Waterproof iPhone
  • More durable iPhone
  • VR integration
  • New battery technology
  • Built-in health sensors
  • Gesture control

Waterproofing has been attempted by Samsung and Sony, where it was abandoned by the former and discouraged by the latter2. The iPhone 6s is waterproofed to a degree; making it fully waterproof can’t be classed as innovation.

Is there a durability crisis with iPhones I’m not aware of? Does the use of stronger Gorilla Glass not make iPhones more durable? Or, for that matter, the use of stronger aluminium3?

VR is interesting, but what is the use case for integration in an iPhone and how would it work? VR, to me, makes no sense on an iPhone.

New battery technology: moving from Li-ion to something newer, longer lasting, and faster charging would be innovative. No disagreement here.

Health sensors for a device that’s mostly in your pocket? How would they work?

Gesture control is nothing more than a gimmick. Importantly, gesture control is not innovative as it’s been done before.

It’s a strange set of feature requests, to say the least.

Dev Notes - Questions and Answers

As a little side project, I am rebuilding my long forgotten app Amazing Flag Quiz. I don’t have the original source code, so it’s all being done from scratch. My current task is working on the question and answer model. There are few things it needs to do:

  • generate an array of questions (each element a Question) based on the user’s selected continent (e.g. Europe, Africa…)
  • each Question must contain the correct answer and three wrong answers
  • the array of questions and each Question’s answers must be randomised.

Before getting into coding the app properly, I’ve thrown the below together in a playground.

I have an array of all countries:

let allCountries = ["Afghanistan", "Akrotiri", "Albania", "Algeria",...]

My Question class contains a correct answer and three wrong answers, held together in an Array:

final class Question {
    let correctAnswer:String
    var questionOptions = [String]()
    init(cAnswer:String, qOptions:[String]) {
        self.correctAnswer = cAnswer
        self.questionOptions = qOptions

To track which game option the user picks, I’ve created an enum:

public enum GameOptions
    case All, Africa, Americas, Asia, Australasia, Europe, BritishEmpire, USStates

Finally, in order to create a list of questions, I’ve created a protocol with a default implementation:

protocol Questionable
    func questionsForOption(option:GameOptions) -> [Question]
extension Questionable
     Based on option, will generate and return an array of Question objects.
     - parameter option: GameOptions selected by user.
     - returns: [Question]
    func questionsForOption(option:GameOptions) -> [Question]
        switch option
        case .All:
            var allQuestions = [Question]()
            for q in allCountries
                allQuestions.append(Question(cAnswer: q, qOptions: populateOptions(q)))
            // Shuffle 
            return GKRandomSource().arrayByShufflingObjectsInArray(allQuestions) as! [Question]
            /* ... */
            return []
     Populate answers for question.
     - parameter correctAnswer: String
     - returns: [String]
    func populateOptions(correctAnswer:String) -> [String]
        var countrySet = Set<String>()
        // Get four unique random answers
        repeat {
            let i = GKRandomDistribution(lowestValue: 0, highestValue: allCountries.count - 1).nextIntWithUpperBound(allCountries.count - 1)
        } while countrySet.count < 4
        // Add answers to an array
        var options = [String]()
        for c in countrySet{
        // Shuffle answers
        return GKRandomSource().arrayByShufflingObjectsInArray(options) as! [String]

In terms of usage, I need to generate questions and answers when my GameViewController appears on screen, as part of viewDidLoad, as shown below:

class GameViewController:UIViewController, Questionable {
    var list = [Question]()
    /* ... */
    override func viewDidLoad() {
        list = questionsForOption(.All)

I’m satisfied with this solution: it’s less than 100 lines of code and is easy to follow.

I seem to remember this being much harder when I wrote Amazing Flag Quiz originally and I’m mindful of what Henri Cartier-Bresson once said:

Your first 10,000 photographs are your worst.

That applies to your first 10,000 lines of code as well.

Next up: presentation logic.

Parse to Close

Kevin Lacker:

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

While Parse will be releasing a migration tool to assist with moving existing data to any other MongoDB database, the fact that it is closing will come as a huge blow to developers who make use of the platform.