From the beginning of Sprint-o-Mat, I always internally represented distances as an enum with an associated value:

publicenumDistance {casemile(distance: Double)casekm(distance: Double)staticletkmPerMile = 1.60934 }

So, adding kilometer support in Sprint-o-Mat was mostly about adding in some UI.

I added a button to flip the units, but I didn’t want a straight conversion. I wanted it to round to the closest tenth.

publicfuncflipUnitsAndRound() -> Distance {switchself{case.mile(letd):return.km(distance: round(d * Distance.kmPerMile * 10) / 10)case.km(letd):return.mile(distance: round(d / Distance.kmPerMile * 10) / 10) } }

I do the same for paces, and round them to the nearest 15 seconds.

With this done, it was mostly hunting down all of the places I was lazyâ€”mostly inside of my HealthKit code that is getting running distance from the Watch in miles.

I left that as is, but made all of the mathematical operators for `Distance`

work for mixed miles and kilometers, so I could could construct a `.km`

Distance and then `+=`

`.mile`

distances onto it, and the conversion would be automatic, keeping the units of the left-hand side.

publicfunc+ (left: Distance, right: Distance) -> Distance {switch(left, right) {case(.mile(letld), .mile(letrd)):return.mile(distance: ld + rd)case(.km(letld), .km(letrd)):return.km(distance: ld + rd)case(.km(letld), .mile(letrd)):return.km(distance: ld + rd * Distance.kmPerMile)case(.mile(letld), .km(letrd)):return.mile(distance: ld + rd / Distance.kmPerMile) } }func+= (left:inoutDistance, right: Distance) { left = left + right }

If you run in kilometers, check out the new version.