Introducing Workouts++ 2.0

I’m delighted to announce version 2.0 of Workouts++. This update is in many ways the full realization of the initial idea I first had for the app back when it began. Unfortunately, back then the capabilities of watchOS and the Apple Watch didn’t quite allow for it to do everything I wanted it to do. But with the advent of watchOS 4, now I finally can.

Along with the feature updates another significant change with 2.0 is that the app is now totally free. My goal is to allow as many people as possible to use Workouts++ to get them fitter.

The major features in included in this update are:

  • Support for Apple Watch based podcast playback
  • Support for Workout Location tracking and mapping of saved workout routes
  • Support for Swimming workouts

Podcasts on your wrist

As soon as I saw the LTE enabled Apple Watch Series 3, I knew I had to find a way to get standalone podcast playback to work on it. Going out on a run or walk with only my watch is a absolutely delightful experience. Unfortunately, the road to get this working nicely on the Apple Watch was a bit bumpy.

As Marco nicely outlined, there are a number of limitations that watchOS apps currently have that make it awkward to get podcasts working well. However, I’ve been able to get it working well enough. It certainly helped that I also run an RSS Sync Platform, so at least a lot of the usual struggles with podcast backends were already in place for me. There are certainly a few rough edges and things that don’t perform exactly how I’d ideally like them to but the overall experience is there and once you get used to the few necessary quirks it is really great.

You can download episodes either directly on your Apple Watch or transfer them ahead of time using the iPhone app. Direct streaming over LTE is an especially smooth way to get started. Because transfers done between the iPhone and Apple Watch (or Apple Watch downloads done while connected to the iPhone) are done over Bluetooth they are significantly slower than those done over LTE1.

Direct streaming downloads started on your Apple Watch will begin to play as soon as it has buffered enough of the file. Seek controls aren’t enabled until the whole file is downloaded, but playback should typically begin within a few seconds. So you should be able to get started right away.

Once you have a file playing you can control the playback speed using the on-screen control, or just let it use TimeSaver silence removal to speed it up. TimeSaver dynamically shortens the length of silences in the podcast audio, so that you can speed up the podcast without distorting the audio. This typically results in a savings of roughly 5-10%. You can disable this in Settings on your the iPhone if desired.

You can play back the podcast to either a connected bluetooth headset or directly from the Apple Watch speaker. Surprisingly I’ve found that in certain situations the Apple Watch speaker is actually a really nice way to listen. You don’t need to have anything in or covering your ear and the speaker will follow you around wherever you go.

Location Tracking

Since watchOS 3 the built-in workout app on the Apple Watch has recorded the route taken during your outside workouts. These provide a lovely way to go back and examine your workouts. Starting in watchOS 4 it is now possible for 3rd party apps to do the same (and also display any previously recorded routes).

Along with the route taken, the app is also able to collect your elevation. This is graphed above your workout plot to give you a sense of the terrain your navigated. When location tracking is enabled you can also now add Current Elevation as a workout metric displayed during your workout. This is potentially useful as a navigation aid or just for general motivation.

This works anytime your iPhone is with you during your workout, or if you have a Series 2 Apple Watch or better with built-in GPS. Location tracking is optional and can be disabled in the configuration screen of any workout.

Swim Tracking

By far the most requested feature with version 1.0 of Workouts++ was swim workout support. This is now possible in watchOS 4. I’m not a big swimmer myself (just one step up from lightly drowning), but I have been able to work with a few fine beta testers who are, and I think the result is really nice. During your workout you can display things like your length/lap count2, as well as use the High/Low Heart Rate graph to display your stroke history right on your wrist.

Additionally for the app can now display the stroke history of your workout and detailed stats for each stroke when viewed on your iPhone later.

Workouts++ will automatically put your Apple Watch in Water Lock mode at the start of the workout. You can also manually enable Water Lock from the controls screen in the app.

I’ve made automatic Water Lock a feature available (but turned off by default) in all other workout modes too. I’ve found that in certain situations (like outdoor runs in wet weather) it is nice to have the ability to setup a ‘wet workout’ configuration that I can use in challenging environments.

Other Features

There are also a whole host of other features I have added to the app including:

  • Display of V02 Max values
  • Siri integration (e.g. “Start Outdoor Walking workout in Workouts”)
  • Redesigned custom workout configuration system
  • Redesigned workout detail display
  • Dark mode
  • Added Stopwatch, Round counter, Average pace/speed and Activity ring metrics for display during workout
  • Added Distance and Duration Alerts

I hope you enjoy the app. If you have any feedback please let me know, I’ve learned a lot from my users of this app. Everyone seems to have a slightly different approach to how they workout and I try to make Workouts++ flexible enough to accommodate most of them.

  1. Somewhat amusingly a little trick you can use to speed up transfers between the iPhone and Apple Watch is to start a transfer going and then turn off Bluetooth temporarily on your iPhone. Assuming you are somewhere with a good WiFi network the transfer will switch over to WiFi and go much quicker. Then you can turn back on Bluetooth once it completes.

  2. There seems to be no consensus around the meaning of the terms laps and lengths. For the purposes of Workouts++ a length is the swimming taken to move from one wall on of the pool to the other. A lap is two lengths.

David Smith




The Tesla Flat Tire Process

One of the more peculiar things I discovered during the sales process for my tesla was that it doesn’t have a spare tire. This seems like a general trend across car manufactures, either shrinking their spares to sometimes comical sizes or eliminating them altogether. The weight and space savings are obvious but it did make me wonder what happens when you get a flat.

When I was investigating this before I got my car I couldn’t find a straightforward description of the process from an owners perspective, and instead pieced it together from forum posts and the like. I recently experienced my first flat and so can now speak from my own experience. This post is my attempt to help anyone else who is curious about how the process goes and what to expect.

1. The Flat

While driving along we started to receive low tire pressure warnings on the main dashboard. Initially these were just the regular “Low Pressure” warning that I’ve gotten a few times when I just need to top up a tire. So we added a bit of air to the tire in question and kept driving.

A few miles later the warning returned and now quickly escalated from ‘hey, one of your tires might need some air’ to ‘woah there, you need to pull over right now.

As soon as we safely could, we pulled the car over (in our case in a residential neighborhood). After a quick visual inspection the tire was definitely a full on flat now.

2. Roadside Service

As the car has no spare the next thing to do was to call Roadside Service. They answered right away and were able to lookup my account profile information from Caller ID, so we very quickly moved right to sending over help. The representative had a good balance of friendliness and directness.

He said the nearest tow service with a tire for me was about 30-60 minutes away and would be able to provide me with a loaner spare to get me moving again and the tow truck driver would then take my flat tire to my nearest Tesla service center for evaluation. He also then quite helpfully said that I should expect a call from him in around an hour to check that things were moving along.

The tow truck driver called and asked to confirm the tire size and specs for my vehicle. He also let me know that he couldn’t guarantee that the rim for the loaner spare would exactly match my other wheels (in my case it did but I appreciated the warning).

He arrived around 40 minutes later and proceeded to remove my flat tire and put on the loaner spare. He then took the broken tire with him and said he would drop it off with Tesla later that day, and then I should expect a call from Tesla with next steps for getting it fixed or replaced. From talking to him it sounded like Tesla had provided his tow truck company with a few spare tires that they cycle through as needed. He was efficient and helpful. The whole process took around 10 minutes.

Before he took away the old tire I was able to locate the source of my trouble…I’m no mechanic but I’m pretty sure this isn’t good:

3. The Loaner Spare

The same customer service representative from Roadside Service called me back to make sure everything had worked out correctly. He also sent over a simple document for me to e-sign regarding the loaner spare. Basically a general waiver of liability and an agreement that I’d bring back the tire to Tesla within 3 business days (or later if mutually agreed to).

So basically rather than carrying a spare in my truck, when I needed one it was delivered to me on the side of the road and I could then use it until a proper replacement could be arranged. The tire I got was a full size regular tire, and didn’t have any use restrictions. There was no cost for either the roadside service or loaner spare (though I think that after my car is beyond a certain age their might be).

The only downside of the loaner spare was that the tire pressure system wasn’t connected to it so I had this warning every time I drove until it was replaced.

4. The Replacement

I got a text message from Tesla service later that day after the tow truck driver delivered the tire to them.

First, let me say how much I loved that this was a text and not a phone call. While a bit silly I really loved that I could handle the entire process of scheduling the replacement over text message. That way I could just pick up the conversation as I was free and didn’t feel like it intruded into my day very much.

As I’d guessed when I saw that big chunk of metal sticking out of my tire I was told that I needed a new tire and that the cost for the replacement would be $350. Which is a bit higher than I may have hoped for, but certainly not unreasonable. I was able to authorize the work to begin changing the tire on my rim and schedule a time for me to drop in to have it put on. This ended up being 5 days after I got the flat because that worked best for me.

I brought my car in and they replaced the tire, reset the tire pressure monitoring system and gave it a good wash. The appointment was quoted at around an hour, but ended up more like 2 hours.

General observations

This happened to me in probably one of the more ideal circumstances. We were driving on quiet roads and were able to pull over into a neighborhood. The nearest Telsa Service center is only 10 miles away and the tow truck was within an hour. I’d expect that if this had happened to me out on the highway, in the middle of nowhere things would have been a bit more tricky or at least taken much longer. But hopefully the general process would follow the same smooth progression.

Overall, I was very pleased with the process. The lack of spare had given me a bit of pause when we were first considering the car but this process went off without a hitch and was about as painless as I could hope for given the circumstances. In a funny way it is slightly liberating to not have a spare in the trunk, so no matter what happens I have to call for professional help. This mean I’m never having to put myself in a potentially awkward or dangerous situation roadside.

David Smith




Apple Watch Apps Head to College

The thing I was most excited about during yesterday’s Apple Event was the addition of LTE to the Apple Watch. While the new iPhones are great, and a 4K Apple TV is useful, I see this new capability on the Apple Watch as being potentially transformative to how I use technology on a daily basis.

While I’ll have to live with it for a few weeks to see if it really pans out, imagining a future where my iPhone is no longer a ‘must carry’ device is remarkable.

The more, however, I think about this prospective future the more I think I’ll have to fundamentally change the way I consider and approach the development of my own Apple Watch apps.

Even though watchOS is only three years old we’ve already seen it grow from a hyper dependent toddler (WatchKit 1), to a slightly more independent adolescent (watchOS 2/3/4), to now suddenly a college student heading out of the home for the first time on its own. Asserting its independence while still holding on to a bit of a parental safety net.

Each evolution of the Apple Watch platform has made it less and less dependent on its parent iPhone. The addition of LTE takes all of this quite abruptly to another level.

I am now thinking about my watchOS apps as though they must be able to fully function out on their own with only minimal help and supervision from their iPhone. If they don’t, I suspect I’ll find them to be quite frustrating.

While previously there have been technical capabilities where watchOS apps could connect to external services without their iPhone present, the expectation I think has always been that this would be rare and unusual. Now it may very well be common and expected.

Practically I see this impacting my own apps in a few ways. These are mostly speculative at this point, so after living with an LTE watch for a few weeks they may change but I think these are going to be important considerations for watchOS developers moving forward.

Sync

Firstly, I’m going to need to do some management of application state and data via a web service rather than relying solely on the direct connection between the Apple Watch and iPhone.

I can imagine a situation where I configure a workout in Workouts++ and then immediately head out for a run. In this case if for some reason the new workout configuration hadn’t yet synced to the Apple Watch (via WatchConnectivity), right now the user would just be stuck. However, with LTE they would have a reasonable expectation that this new data would just be loaded over their cellular connection.

So I’m going to have to work through how to create a seamless experience for syncing application state between the Apple Watch and iPhone, where they are treated more like peers.

Application Dead-ends

Secondarily, while Apple Watch apps will still need to be simple and concise, I think I will need to make sure that there are very few ‘dead-ends’ where I’d currently punt the user to their iPhone to complete an action or do some setup.

These escape hatches were a great way to keep watchOS apps dead simple, but never really were particularly elegant. But in a world where the Apple Watch may be used for extended periods without being next to its iPhone they could become infuriating.

As an example, I’m thinking that for Workouts++ I may want to add the ability to do some very basic workout configuration on the Apple Watch, so that you aren’t stuck if you decide to do an activity you haven’t previously setup on your iPhone while you are out.

I’ll have to be extremely careful to not make the app overly complex as a result, but I’ll be on the lookout for these ‘dead-end’ spots.

New Opportunities

Lastly, I’m going to look for opportunities for what type of watchOS apps might now be possible with a persistent connection. In much the way that having an always internet connected iPhone opened a wide range of completely new use cases, I suspect a similar thing will be made possible on the Apple Watch. Some uses may be limited by the form factor of the Apple Watch but I suspect that a bit of creativity should allow many to become possible.

As someone who has been making apps for the Apple Watch from the beginning this new hardware addition has be more excited than ever for the platform.

David Smith




Introducing Pedometer++ 3.0

Today I’m delighted to announce Pedometer++ 3.0. I’ve been steadily working on Pedometer++ now for nearly four years. Over that time the core conceit of the app has remained the same, to motivate you to be more active. It has done this with colors, confetti, complications and streaks. Now I’ve added another tool to hopefully motivate, achievements!

Achievements





You can now earn badges within the app for the reaching certain milestones. These include:

  • The biggest number of steps you have taken in a day
  • The longest streaks you have been able to reach
  • Your lifetime steps taken
  • Your lifetime floors climbed
  • Special badges for meeting certain criteria


I hope to add several more of these categories over time based on the feedback this initial set receives.

The sweet artwork for the badges was done by excellent Louie and Alexa over at Parakeet.

Widget

With iOS 11 just around the corner there is increasingly an emphasis on the use of widgets in iOS. So this update also updates the widget Pedometer++ provides to be more capable by adding a daily detail view of your steps each day.

Enjoy!

David Smith




A favorite hack

In my latest update to Pedometer++ I had to remove the feature where you could badge your app’s icon with your current step count. In doing so I also removed one of the all time favorite hacks I’ve ever written. I felt that this deserved a little send off before it departs off into my Git history.

First, the back story. During the introduction of iOS 7 one of the random side effects of the wide reaching changes to the iOS user interface was that app icon badges started to get truncated whenever they got above 4 digits long.

This usually isn’t a problem since if you have more than (say) 10,000 unread emails you are likely long past caring about the precise number anymore. But for my little hack of using the badge to show specific counts this caused a problem.

At first, I thought I’d have to remove the feature in iOS 7, until one fateful afternoon (while taking a shower, of course) I had the insight that I might be able to work around this. My realization was that the numbers were getting truncated based on their displayed width and not their digit count. Thus a number with a lot of 1s in it would not get truncated because the 1s are so thin, whereas a number with a lot of 4s in it would be truncated because they render much wider.

So I then set out to alter the numbers that were displayed so that if I thought it would get truncated I would replace the least significant digits with 1s until it would no longer be truncated. After a bit of experimentation I found that I needed for a 5 digit number to contain at least two 1s in it in order to be assured that the number wouldn’t truncate. Usually, but not always, the first of these would be the leading digit since getting above 20,000 steps is quite a full day of walking.

Kind of awkwardly though, I realized that in order to achieve this I’d have to calculate how many 1s there were in the number. I poked a round a bit on the mathematical side of this but couldn’t work out a way to count how many 1s there were in a given number via mathematical means. There might be a way to do this, but I couldn’t find it.

So instead I figured that I could just write a really crude method using strings. I just cast the number to a string, then compared its length to a string where I replace all the 1 characters with the empty string. From here I could work out if I should change the last digit to a 1 (in the case of it already having another 1), or if I should replace the last two digits (if no other 1s are found).

Here is the final result:

I’ll be sad to see this little hack go. While it might sound a bit funny to have a favorite line of code, I think this was mine. I just loved how silly of a hack it was, but yet how effective it proved to be.

Though one small consolation for it being gone now is that I can publish it here and the world can see it for all of its silly goodness.

P.S. And yes, if you are wondering if I really did just have that inscrutable block of code entirely undocumented in the app…I did. I suppose that’s the blessing and curse of being an independent developer. 😇

David Smith