Considerations for New iOS Versions

This time of year there is always a murmur amongst app developers, blinded by shininess of the new iOS, to consider whether to drop support for older versions of iOS and jump fully to requiring the new stuff. Doing so can make your life a whole lot simpler and your code a lot cleaner.

There are two major considerations to make before doing this: one more obvious, the other more subtle.

Existing Users

If you drop support for older versions of iOS, existing users who haven’t updated but who have the app already downloaded will continue on as though nothing happened. Should they delete and want to re-download the app they can do so from their App Store history. Generally speaking their only impact is that they won’t get any new updates, which could include bug fixes or improvements which would benefit them.

iOS generally has really good adoption of new versions. With the vast majority of devices which can update running it within a few months of release.

Looking at Widgetsmith today I see that 86.5% of my users are on iOS 18.

Which means that 9 months in, if I went iOS 18+ only today I would be locking around 13% of my users onto the current version (with a reasonable expectation that more would subsequently update to either iOS).

New Users

Things get a bit more complicated when considering the impact on the future growth of the app. While existing users will continue to be offered the last compatible version of your app by the App Store, new users will not be able to acquire it. If they open the App Store they will be told this app is not compatible with their device.

While I would, in some ways, prefer it if Apple instead showed them the last compatible version for download, I can understand how that would cause confusion. But as an app developer it means that any time I increase my required iOS version I’m also reducing my prospects for future growth.

When I look at my current new downloads by platform version I see a distribution broadly similar to the one in for usage but skewed slightly newer.

For example, if I went iOS 18 only today I’d exclude around 9% of my current new users from acquiring the app. Which from my perspective is kinda huge. If I could do something which boosted my downloads by 9% I’d be delighted.

The story gets even more complicated for newly released versions of iOS, the initial adoption of iOS versions is very metered (I imagine while Apple ensures all is smooth and well with the update). So if you were to require the latest version on launch day you’d dramatically reduce your audience for a while, until adoption broadened out.

Here is the distribution of new downloads by platform version for Widgetsmith for the iOS 18 release cycle:

While I saw an initial surge of downloads on iOS 18 (peaking around 60% on launch weekend), it then quickly retreated to 40% and then slowly increased from there. There is a big jump (to about 80%) at the end of November when Apple enabled broad automatic updates.

Every app is different but this gives a general idea of how you’ll reduce your new downloads by requiring newer versions.

 This data can be found for any app in App Analytics > Metrics > New Downloads (viewed by Platform Version)

Thoughts

My general approach is to only increase my requirement once the new download rate drops to a percent or so. The technical and practical benefits become justifiable to me once I’m only loosing that many users. Otherwise it feels like I’m doing something to make my technical life a bit easier but my business meaningfully worse. That tradeoff will vary by app and business goals, but generally I consider it wise to take a cautious approach whenever possible.

David Smith




Don‘t Liquid Glass All the Things

Design Diary

I was fortunate enough to get one of the Design Labs late last week, which meant that I spent Friday morning frantically doing as many first-pass updates to the new design as I could. I then was able to discuss many of them during the lab and learned a bunch.

Something in particular which I heard a few times was that I was overusing Liquid Glass. Which I suppose makes sense, it is the literally shiny new thing. Looking back at these early redesigns, I was mostly just rounding everything and adding Liquid Glass to all interactive elements.

Here is a basic example of this in action:

For the Route list, I just added the .glass button style to the share and delete buttons. When you’d tap on them, they’d then get the cool lift-up fluid effect.

Something my design lab consultant said, which was really clarifying for me, was that Liquid Glass should generally be used to highlight content underneath the button. So if that content is plain/flat, then it is likely not appropriate. In this case, if the button was over the map preview, then it might be appropriate, but since the whole section is tappable, then I’d have two levels of interactivity, which is generally not great.

In this case after the lab I took another attempt at redesigning the route chooser rows and ended up with this:

This isn’t definitely done yet but feels much better, and more in keeping with the general look of the new design language. I still need to do work on the overall layout here, but moving the buttons into the row’s selection sheet feels much better and gives me much more flexibility about how I layout this page.

As will likely often be the case for posts like this, I can finish with the relevant page in the HIG.

Be careful how much you use the new shiny new Liquid Glass effect. A good new design isn’t one which uses that everywhere; it is one which uses it to great effect.

David Smith




Rule #1: No HIG Exceptions, No Custom UI

Design Diary

Yesterday’s announcement of the new Liquid Glass design system has made me think it is a good time to dust off my old Design Diary series of blog posts. I expect I will be spending a good part of this summer working through what the new design system means for my apps.

The Road Ahead

The very first thing I did once I got the new Xcode versions installed was a simple build-and-run of my apps to see how far I have to go with adopting the new design. The result showed just how far I have to go.

Having now watched a bunch of the Session Videos about the new Design is clear that Apple has done a lot of thinking about this new direction they want their platforms to head and it is gonna be far more than just a simple coat of paint.

While the core functionality of my apps will remain the same I expect I will need to do some deep thinking and exploration of how I can best adjust the hierarchy, layout and adornment of my apps to fit in.

This talk “Get to know the new design system” by Maria Hristoforova in particular lays out the fundamental concepts which undergird the thinking I need to adjust to adopt.

Rule #1: No HIG Exceptions, No Custom UI

I’m also learning (the hard way) that I will need to be careful to properly understand the new system before I get carried away with my ideas for adopting things.

Something I have a tendency to do is want to build lots of little custom interactions, which serves me well in some contexts but here it would be rather unwise. Apple has spent a lot of effort crafting this new design system and likely explored and tried a great number of different paths which they now advise us to avoid.

As a result, my first rule I’m adopting for myself in this initial redesign is that I will 100% follow the system guidance and use all default system behaviors.

There might come a time when I have enough knowledge, experience and confidence to go my own direction with a design element, but what I should do first is be completely default in my implementation. I’m going to try and hold myself to a rule that I don’t do anything custom.

I think should try to follow the proverb “Imitate, then Innovate”. Until I know the design system backwards-and-forwards, I not going to think I know better than the defaults.

Getting a head of myself

This rule is top of mind for me right now because of a little exploration I did this morning. I saw how in a few places the new design will have a search button as an element along the bottom trailing edge of the Tab Bar.

I saw that and was like “ooo, I wonder what it would be like to put a universally accessible action button there”, like maybe I could put a “Start Workout” button in there for Pedometer++.

Trying to implement this I immediately discovered that there was no default, system method in the new design’s API to do this. The Search button is a specifically unique action which the system supports.

That didn’t stop me from trying to see if I could do it anyway. So a bit of hacking around with onChange and other abuse of SwiftUI I got something working.

Then I caught myself and gave myself a metaphorical slap on the wrist. Nope, don’t do that. This summer is all about learning the common path, the default path. I shouldn’t spend time hacking around the system.

This was then confirmed all the more when I started reading the new Human Interface Guidelines and what should I see when I get to the Tab Bar section.

The exact thing I wasted a few hours working on was specifically called out as a bad idea.

So that is now my mission for the summer. I want to adapt Widgetsmith and Pedometer++ into the new system without a single hack. If I can do that then I should reach a point where I deeply understand things and then maybe at that point I could starting thinking about places where I might be able to reasonably innovate on top of it. But until then it would be hubris and folly to think I know better.

David Smith




Essential Nature of Adventure: My Bob Graham Round

Six months ago, I found myself really demotivated with my health and fitness. For a long time I’d been on a good run with working out and staying fit but I found that I was struggling to head to the gym and keep consistent with taking care of myself. This isn’t the first time this has happened to me but as I get older I am very aware that it is vital that I continue to fight against this tendency because the longer I let it go the harder it will be to come back. What I needed was a project.

I tend to work best when I a working towards something specific rather than just “general health”. As much as it would make sense to be working towards “a long and healthy life”, the reality is that just doesn’t get me out of bed. I needed something more tangible and short term. I need something which lets me tell myself that if I slack off now, I’ll pay for it later, and soon.

Last week I turned 42. Which ended up being the seed of the plan I came up with. My favorite place on earth is the English Lake District. Its combination of water, mountains and culture resonates with my soul at a fundamental level. I am never so happy as I am when I am out in the fells1. The relevant part of the Lake District’s mountain culture for me is the concept of the “Rounds”, long circular routes which circumnavigate the area.

The most famous of which is the Bob Graham Round. This is a roughly 66 mile route which visits 42 high fell tops in a wide reaching loop of most of the Lake District, involving around 26,000 feet of elevation gain and loss.

There are some fell runners which attempt (and remarkably complete!) the entire round in 24 hours. That didn’t appeal to me (nor the health of my knees), but I thought I might try completing it in 42 hours instead.

42 peaks in 42 hours at 42 years old. I liked the sound of that, and so a project was born.

I now had a reason to get up each morning to exercise. A reason to manage my diet and a goal to work towards both physically and logistically.

The Plan

So I began planning towards my Round. Timing wise it looked good for me to plan to come up to The Lakes for my kids school holiday at the end of May (right after my 42nd birthday). I’d come up here for a week and plan to attempt my round on the best two days of weather.

My plan was to complete the first 35 miles of the round on Day One. Starting at dawn and hiking until dusk, then having a brief rest and then heading out at dawn again on Day Two to complete the final 31 miles.

One of the essential rules I have for this kind of expedition is that I avoid any and all unnecessary risk so I didn’t want to travel in the dark. Especially since I am doing this attempt solo/self-supported it isn’t wise to be out in the wilderness by myself after dark. Thankfully the Lakes is pretty far north (54° 36’ N), so in mid-summer the days are very long. I’d have around 18 hours of usable light to work with each day.

I also began to learn and explore the world of ultra trail running. While I would only need to maintain a pace of roughly 2.0 mi/hour for the 18 hours of daylight to complete each of my legs, the terrain I’d need to cover is rough and rocky in sections so I‘d have to run whenever I could to offset these slower sections.

I‘ve been a runner my whole life but never over terrain and in the mountains. I had to learn about the different way you need to pack your gear, fuel yourself and techniques for maintaining your footing on uneven ground.

This was all very fun to me. I love learning new things, indeed that is a huge reason I undertook this challenge. In addition to the physical conditioning it required, it also provided a new venue for me to learn and explore. Something which at 42, I am very aware that if I don’t regularly stretch my mind it will become much less limber.

The Attempt

So this brings me to Tuesday, May 27 at the lower door of the Moot Hall in Keswick (the traditional start of the Round), at 3:30am.

There was a bit of comedy in the weather surrounding this expedition. For most of April and May England has been experiencing the sunniest and driest Spring on record. With long periods of fair, dry weather across the entire country. Indeed, I’d had to start making contingency plans for dealing with a lack of water along the route, as high mountain streams were likely all dry. It turned out, however, that those plans were not needed as the day I arrived in the Lakes the drought was broken and the rain arrived.

Rather than the full days of sunshine the last several weeks had seen, I instead needed to find the best 42 hour period I could and hope for the best. The forecast for the day when I started was to be beautiful for most of the day until late-afternoon when a storm would arrive. The nature of my Day One route was that hopefully by then I would have gotten past all the highest peaks for the day and be low enough that I’d be able to weather the storm without much fuss. I am no stranger to rain in the Lakes.

The first part of the day went largely as expected. I reached the first of my 42 fell tops after a steady initial climb.

From there things went better than I could have hoped for the next several peaks. I was in a good flow and actually was a full hour ahead of schedule. My training and planning seemed to have been successful and I was able to move quickly and efficiently over the route. Owing to my very early start I had the mountains completely to myself and was thoroughly enjoying my adventure.

That is until just after I reached the top of my eleventh peak (Red Pike).

Here things took a rapid and undesirable turn. The storm which had been forecast to arrive mid-afternoon blew in from the Irish Sea, and with a strength and vigor beyond which was expected. Things quickly went from high clouds and gentle breezes to drenching rain, dense fog, and buffeting winds.

My wife has always been very supportive of my heading out on solo adventures in the wilderness. She knows how much I value this time and how helpful it is to my mental and physical health. But we have two rules which I must steadfastly follow:

  1. She must always know exactly where I am.
  2. I must always make wise choices and avoid any unnecessary risks.

I’ve spent a lot of time in the wilderness, in all manner of weather and conditions, I know when things are fine and when they are definitively “not fine”. I was well equipped for bad weather with high strength rain gear, multiple thermal layers and a warm puffy jacket. But I also was about to reach my final “bailing point” before I headed up into the Scafell ridge where I’d reach the highest point of my Round (and indeed the highest point in all of England).

I put on all of my storm gear and proceeded on for a few miles but it very quickly became clear that it was not wise for me to continue. Something I often say is that the key to staying safe in the wilderness is to be very conscious about what assumptions you are making. I was warm and safe in that moment but I was also at the limit of what the gear I had brought could support. If things got much worse, or if I had a minor accident and needed to slow down or stop for a rest, I would be in real trouble. The early and aggressive turn in the weather had consumed all of my safety margin.

So it was in that moment that I made the very disappointing, but correct, decision to bail off the mountain ridge I was on and drop down into the nearest valley as quickly as possible. While I was extremely disappointed that I wouldn’t be able to complete the route I had planned, reassuringly it wasn’t a difficult decision. I was 100% confident it was the correct thing to do, that it was the only safe path forward.

I dropped down off the ridge and made for the nearest car park and called my wife to come and pick me up. As I descended out of the howling wind I felt warmer and warmer, and as I looked up into the mountains, still wreathed in fast moving clouds, I became more confident in my choice.

So Day One ended up being just shy of 25 miles, with 7,600ft of elevation gain. Not quite what I’d planned but still a big day out.

The Essential Nature of Adventure

A number of friends and family were following along my adventure (in realtime via a custom website I had created). After it was clear I wasn’t going to complete my planned hike for Day One they reached out with sympathy and encouragement. Which was lovely to receive but strangely I found it wasn’t too much needed. There was certainly a bit of disappointment, but what I found was a certain peace too. What I kept coming back to was that in order to have a true “Adventure”, there has to be a high degree of likelihood that you won’t complete it as planned. If the outcome is all but a foregone conclusion when you begin, then you aren’t exploring, you aren’t finding the edges of your abilities.

That uncertainty is a big part of why I wanted to attempt this Round. Sometimes we get to choose the challenges in our life, but often we don‘t. There have been countless times in my life when brutal, unforeseen circumstances have borne down on me. I’ve gotten through those with the help and support of loved ones, but also to some degree by cultivating the skill of perseverance.

When life isn’t bearing down on me, if I choose challenges which stretch me I will become more comfortable with difficulty. So when the external pressures do arrive they are a little bit less overwhelming.

In this case the essential uncertainty of a wilderness adventure helped to build my resilience, and so I am less disappointed.

Persistence

Next I had to answer the question of what to do the following day. I clearly wasn’t going to be able to complete the Round in 42 hours as originally planned, so should I continue along? I decided to push on as planned. So I got up very early the next morning and headed out for Day Two of the planned adventure.

This would be a roughly 31 mile section with about 10,000ft of elevation gain. It covered my favorite part of the route and included long beautifully runnable sections way up in the mountains (the Dodds section if you‘re familiar with it). I decided to head out with a renewed sense of fun. I no longer had the self imposed “pressure” of trying to hit my goal, it was now just about enjoying the fitness I had built to get here and having a lovely big day out.

I went through the 31 miles of that day with a big smile on my face. I was out in my favorite place, doing my favorite activity and was feeling healthy, fit and safe.

The weather wasn’t perfect, but it was the kind of mix I was fully prepared for, so didn’t cause much trouble.

After eleven hours of steady work I summited the final fell of the route (Skiddaw). While not the specific accomplishment I had been planning towards, it was nevertheless a wonderful moment to crest the final hill and see the whole Lakes ahead of me. From that vantage point I could see nearly the entire route laid out before me. It was wild to see how far off in the distance several of the mountains I had been walking on hours before now seemed.

Now there was just the matter of getting down off this final mountain ridge and making my way back to where I had begun.

I touched the door at the Keswick Moot Hall at 7:20pm, 38 hours after I had set out initially. The route between those two points was not as planned, but still took me to wonderful places both physically and personally.

Reaching the end, there was really only one thing to be done. Sit down at the aptly named “The Round” pub next door and enjoy a lovely meal with my family.

The final stats for the trip where:

  • 55.5 miles (89.3 km)
  • 17,452 feet of elevation gain and loss (5,319 m)
  • 22h 3min of moving time (avg 2.52 mph, 4.1 kph), 38h 10 min total.

Technology

Now I couldn’t finish a trip report like this without discussing the various bits of technology which supported and help me along this adventure. I built a number of features specially to help me on this outing, which will now serve as the basis for major updates I expect to roll out in my apps over the next coming months.

Expedition mode for Pedometer++

While I could have tracked and navigated this adventure using my app Pedometer++. I was concerned that if Day One had extended out to the full 17 hours that my schedule predicted that the battery life in my 18 month old Apple Watch Ultra 2 wouldn’t have. So I set out to build a custom variant of Pedometer++ which was optimized solely for battery life.

I learned a tremendous amount about how to extend the battery life of an Apple Watch app from this experience. I was eventually able to get the battery consumption on my 18 month old watch down to around 3.5% per hour, which would extrapolate out to around a 28 hour max adventure duration. That is with full-time on wrist navigation and guidance.

I also made a few other speciality improvements to the app, for example, increasing the size of the time shown in the top right corner to make it more legible and building a pre-caching system to fully download the route‘s maps to my watch before setting out to further avoid any power intensive operations while walking.

Many of these improvements will now filter back into Pedometer++ itself. The new dual map/statistics view is especially something I’ve found to be excellent for the kind of quick checks I was regularly doing.

Estimate

Because this was a time-based expedition, having an accurate prediction for how long various segments would take me was of incredible help. Pedometer++ already has a basic form of time estimation based on the Naismith Rule, but I needed something a bit more robust.

So I built a tool which analyzes past workouts to build a personalized speed profile for me. This segments the workout based on elevation gradient and determines your typical speed for that kind of terrain. Once this model was built I could then take the GPX route file of my planned trip and apply the speed estimates to it to build a prediction of my time for each segment.

In practice this estimate proved extremely accurate for me. I took the output of this and made a super simple Lock Screen wallpaper for my iPhone which showed my predicted time arriving at different points along the route, aligned so that I could see the Pedometer++ live activity below showing my current stats. So every time I pulled out my iPhone I could check-in about whether I was on track or not.

VO2 max

I didn’t build this but I nevertheless found it incredibly motivating during my training. The Apple Watch can generate a predicted VO2 max value whenever you do an outdoor walk or run. I have no idea about the clinical accuracy of the number it generates but I have found that it is incredibly good at measuring my relative fitness.

You can clearly see in the graph above how my fitness was slowly diminishing towards the end of last year and then how once I set the goal of my Bob Graham Round it started to gradually rise until it peaked right before I started my attempt.

So much of training is about putting in repetitions hoping that you’ll see improvement, but that progress is so often impossible to perceive in the short term. The VO2 number is something tangible and encouraging to keep me going when I feel like I’m putting in the work, but not yet seeing the result.

Peak Weather

I recently came across the incredibly helpful Peak Weather app by Piotr Knapczyk.

This is a weather app with a hiking oriented twist which I found super helpful in my planning. Rather than just showing the forecast at a particular location, it gives elevation based forecasts as well. So it gives you a sense of what to expect at different parts along the climb of a summit.

While I never was able to find 42 hours of good weather in my trip, this tool was very helpful in identifying the best 42 hours I possibly could.

Beacon

I wanted to give my family and friends a way to track my progress along the attempt (and also give my wife additional peace of mind with knowing my current position for safety purposes). I used a personal tracking beacon for this purpose which reports back my location to a central service every few minutes. The backend system for that service was not something which is particularly feature rich so I built a custom tracking website which pulled my data from their backend API.

This allowed me to overlay my location not just with a map, but also an annotated route map showing my progress along the 42 peaks. Thus giving folks a sense of how far I was along and how much more I had to do.

This was one of my first times doing some proper “vibe coding”. I’m not all that up to date with Javascript development so I worked with an AI to build the site. The process went very well and I was generally impressed with how much you can do with a little bit of know how and a lot of AI help.

  1. In the Lake District, mountain peaks are referred to as “fells”, from the old Norse word fjall

David Smith




Let‘s Get Started

For the last few years I’ve gotten into the habit of heading out for a nature-oriented holiday two weeks before WWDC (the penultimate week if you are studying for the SATs).

Typically, this time of year it makes little sense to start any major new projects, so heading out on a break before the intensity of the WWDC-to-September season makes a lot of sense.

This year in particular, this time away has been incredibly helpful.

The last 12 months have been a very turbulent period for developer relations at Apple. It feels like there has been situation after situation which has challenged our relationship and made it tricky to feel awesome about being an Apple developer.

With the benefit of a week away, I feel way more excited about once again heading to Cupertino for WWDC1.

Nothing externally has changed, but my perspective has improved and I was able to remind myself of a few fundamental truths about my job.

The Work to be Done

I love making apps. It really is that simple. My very first job 25 years ago was developing handheld railroad inspection software for the Palm V, and I haven’t looked back since.

The ability to have an idea, open Xcode, and then a few hours later see that idea exist in reality is truly magical.

There isn’t another job I’d rather be doing. For however long I am able to keep making my livelihood doing the exact thing I love, I will be incredibly grateful.

A 166 Million-to-One Opportunity

Every now and then I’ll open App Store Connect and pull up the “Lifetime Units” tab to see how many downloads my apps have accumulated over the years. Right now that number stands at 166 million(!).

How can a single developer pick up their MacBook Pro, write a bit of code, and then publish it to 2.5X the population of the United Kingdom? It just doesn’t seem like that should be possible, but it is, and it is the App Store model which has made that possible.

I will forever be overwhelmingly grateful for the tremendous opportunity being an Apple developer has afforded me.

Fresh New Bits

WWDC is like Christmas morning to an app developer. We get to unwrap all the “presents” the talented folks within Apple Engineering have been working on for the last few years.

I’ve had the great privilege of getting to know many of these engineers over the years, and it never ceases to be a thrill to hear the excitement in their voices as they discuss the newly announced features.

People

Additionally, WWDC is the best time of year when I get to spend time with the broader Apple developer community. While smaller gatherings and other conferences are wonderful, WWDC is the time when the most folks get together from the most places.

Many of my best friends I’ve met at WWDC over the years. Whatever is announced on Monday, it is a gathering of like-minded people who care so much about the things I’m passionate about.

Let’s Get Started

This year has been a tough one, I won’t sugar coat that. I’ve had to work through some really complicated feelings about my relationship with Apple and my work. There remain some fundamental challenges for the Apple developer community. I hope many of them will be addressed next week. Maybe they will, maybe they won’t.

But I also know some other things for sure. I love my job, I’m privileged to have the opportunity to do what I do, and I love the people in this community (within Apple and without). After taking a step back from the drama and developing some perspective, I’m reminded of these great things and now head to Cupertino with a refreshed sense of excitement and anticipation.

This is not naive, blind fanaticism; I remain profoundly aware of the challenges ahead of us. But I am choosing a thoughtful positivity, which is appropriately grateful for all the positives this week represents and the tremendous opportunities it will hold.

  1. This will be my 17th consecutive WWDC, I’ve been in the room for the Keynote every year since 2009 (Covid aside) 

David Smith