00:00:09 ◼ ► All right, so tis the season of diving into the redesigned iOS SDK, trying to adopt our
00:00:18 ◼ ► apps to the redesign, and we get that nagging question, that mind virus, could I just require
00:00:32 ◼ ► Every year we have that feeling, that little itch of, ooh, maybe this would be a lot easier.
00:00:37 ◼ ► You know, after you write if available 26 times in a day, you're like, hmm, this is really
00:01:07 ◼ ► And when I look at my reasons that I want to require 26, it really basically boils down
00:01:35 ◼ ► Like, there is a, as a developer, there is a technical as well as reasonable, like, productivity
00:01:43 ◼ ► There's lots of reasons why holding on to support for old versions of iOS is very cumbersome.
00:01:49 ◼ ► And this is, I would say, doubly a problem I find in SwiftUI, that it makes the technical,
00:01:55 ◼ ► we'll talk about this later maybe, but the technical aspect of backwards compatibility in
00:02:02 ◼ ► Because the way that you do it with all the modifiers on views and things, like, you do
00:02:10 ◼ ► It makes it really awkward to have things that are, you know, if you want to change something
00:02:35 ◼ ► dynamics that are going to come into play with, should you support older versions or not?
00:02:41 ◼ ► There's how it affects you, how it affects your existing users, and what it does to your
00:02:47 ◼ ► And for every app, it's going to be a question of, how do you value, respectively, each of those
00:03:09 ◼ ► Like, this is one of those things where every year, beyond the big, shiny, like, glass effect
00:03:15 ◼ ► stuff coming in iOS 26, there's just refinements to SwiftUI, to Swift, to, you know, iOS.
00:03:24 ◼ ► And so very often, it's like, you were previously needing to do this really complicated, you know,
00:03:42 ◼ ► For your existing users, the story is actually relatively good in the sense of your existing
00:03:47 ◼ ► users who don't update or have yet to update will continue to get whatever the last compatible
00:03:56 ◼ ► So they don't lose anything necessarily in terms of what they lose is, you know, future
00:04:05 ◼ ► And this is awkward if you, you know, if there is a lingering bug that exists in your app that
00:04:10 ◼ ► exists, you know, that was you fixed subsequent to your iOS 28 or iOS 26 update in this case,
00:04:17 ◼ ► they would never get that bug fix that, you know, they are sort of locked into whatever that
00:04:35 ◼ ► You know, it isn't the situation where you should do a bunch of messy underground work in your
00:04:41 ◼ ► app, ship that, and then the next update that you submit right away is the one that dropped
00:04:48 ◼ ► Because, you know, you ideally will want a period of time where you do a bunch of bug fixes,
00:05:00 ◼ ► And if they get, you know, say they get a new phone or they get a new iPad or something,
00:05:19 ◼ ► And this is the, like, business side of things, where it's mostly a business question rather than a
00:05:24 ◼ ► technical or kind of philosophical question, is new users have to be on the platform that
00:05:31 ◼ ► have to be supported by your app in order to download the app in the first place from the app store.
00:05:57 ◼ ► You would immediately be cutting off any user, new user to your app, I mean, who didn't have that version.
00:06:08 ◼ ► Depends on how broad your audience is, how fast they are to adopt, how much you're trying to maximize
00:06:22 ◼ ► Because that's something that I'm looking at, not in my case, I'm not looking at it to drop iOS 18.
00:06:28 ◼ ► I'm just asking now the question of, can I drop iOS 15, which is currently the version that it supports.
00:06:48 ◼ ► And so if I dropped support for iOS 15, you know, ostensibly my downloads will go down by 2.2%.
00:06:54 ◼ ► And it's tricky because it's so difficult to get a new download that in doing something proactively
00:07:03 ◼ ► that reduces my, you know, downloads by 2.5% or whatever is hard to justify in some ways to me.
00:07:11 ◼ ► Because I'm, you know, it's like, I'm willing to do the work on the technical side to manage the backwards compatibility to get that gain.
00:07:18 ◼ ► But even on the other side, it's like, if I decided to look at iOS 18 and get a sense of how many users I would be dropping going forward.
00:07:32 ◼ ► And by sort of the end of the year, so by, because essentially what Apple does, they launch it in late September.
00:07:42 ◼ ► But typically, it's only available to people who go to the settings app, do general software update, and actually like look for the update and hit, I want to update now.
00:07:51 ◼ ► The big, like, automatic update version doesn't typically seem to go out until right around the third week of November.
00:08:03 ◼ ► Like, it seems like they are intentionally holding back the big, broad, goes-to-everyone update until late November, presumably once the new iPhones are out,
00:08:13 ◼ ► the bugs are sort of potentially dealt with and fixed, and it's a very stable, broad thing.
00:08:18 ◼ ► And slightly I have the conspiracy theory that they're having it go out right before Thanksgiving in case people need to have their, like, you know,
00:08:44 ◼ ► And by that point, like, for Widgetsmith, it was getting to about 70% of my downloads, you know, by, you know, sort of by the second week of December, 70% of my downloads were coming from iOS 18, which is pretty substantial.
00:09:04 ◼ ► So, in this case, if we project forward and say you had the same structure, you know, you're dropping maybe for a period of time maybe half of your downloads, you know, in September and October.
00:09:16 ◼ ► And then by November, December, you're getting up to about, you know, only losing about 30%.
00:09:21 ◼ ► And then, you know, over the course of the rest of the year, at this point, iOS 18 represents 91% of my downloads.
00:09:36 ◼ ► And it's – there is no one answer is, I think, something that is fundamental to all of this, that those three factors, your, you know, your enjoyment, your satisfaction, the technical debt, and all the things that come along with it, how it affects your existing users and how it affects your new acquisition of users, is just going to vary for everyone.
00:09:58 ◼ ► I tend to make my life more difficult in terms of the backwards compatibility thing because I am, you know, I am willing to do that work.
00:10:07 ◼ ► I've done it in enough times that I know how to do it in a way that doesn't drive me crazy.
00:10:10 ◼ ► And so, I will do that so that I can, you know, in this case, have 9% more downloads now, you know, versus if I went iOS 18 only last year or even if I went iOS 18 right now, it would reduce my downloads by 9%.
00:10:25 ◼ ► And, you know, I would be thrilled if I was able to do some simple, you know, some App Store optimization activity that boosted my downloads by 9%.
00:10:33 ◼ ► And so, I'm doing that activity and it just happens to be that it's, you know, supporting these older versions.
00:10:40 ◼ ► And so, that's the way the calculus works for me, you know, but for every app, it's going to be variable.
00:10:48 ◼ ► And I think it's the only other factor that's a little awkward is in some ways, you know, it's, it's, if you're, most of the benefit would come from only supporting the current version, you know, iOS, in this case, iOS 26.
00:11:01 ◼ ► Anytime you support anything behind that, very often, it's just as much work to support, you know, sort of N minus 3 or N minus 2 versions of things.
00:11:15 ◼ ► So, if you wanted to support iOS 18 and iOS 26, the difference between supporting that and iOS, you know, 26, 18, 17, 16, that difference is much smaller.
00:11:26 ◼ ► And so, it's a weird dynamic that either you should be sort of all in or probably very conservative.
00:11:32 ◼ ► There's not a lot of desire, I think, and a lot of, huge amount of benefit in this case to go back and forth.
00:11:37 ◼ ► Because if you have to do the work of supporting the pre-26 design as well as the post-26 design, you're kind of, you're doing that work anyway.
00:12:14 ◼ ► So, there's no more like 1 a.m. Slack threads or digging through endless logs trying to figure out what's going on.
00:12:27 ◼ ► Sear finds the true root cause 94% of the time, and can even generate merge-ready pull requests, plus optional tests to prevent regressions.
00:12:37 ◼ ► The bottom line is you ship faster, your team isn't drowning in bug alerts, and instead of grinding through logs, your developers get back to building the product.
00:12:50 ◼ ► This can help you retain people, improve quality, improve the user experience, improve performance.
00:12:58 ◼ ► The good news is new users get three months free of the team plan, which covers 150,000 errors.
00:13:15 ◼ ► That's Sentry, S-E-N-T-R-Y dot I-O, and use the code RADAR or just click the link in the show notes.
00:13:29 ◼ ► So, like, at first I was like, hmm, like, you know, you make a good argument at first for, like, why I probably should support 18.
00:13:54 ◼ ► And I've been doing it for a year, and I haven't dropped 17 because there really wasn't much of a reason to.
00:13:58 ◼ ► I have, you know, a few views in the app that have conditional, you know, things in them, but not much.
00:14:03 ◼ ► So, at first, as you were going through that, I was like, hmm, I should really support it.
00:14:10 ◼ ► But then, at the end, as you were talking about how, well, actually, you know, after a few months, it doesn't really matter.
00:14:25 ◼ ► So, here's some more reasons why I would love to just require 26 sometime, you know, by mid-fall.
00:14:48 ◼ ► But you will be competing with everyone else who did the same thing for that attention and for that editorial selection.
00:15:02 ◼ ► So, that's – I think the day one game might be better for apps that are supporting the old OSs still.
00:15:10 ◼ ► Whereas, if you can wait – if you can hold off until October or November to do your release at all that has the new OS, it mostly doesn't matter if you require it, like, for many types of apps.
00:15:23 ◼ ► Now, it also depends, you know, what phase of your app are you in, like, business-wise and lifecycle-wise.
00:15:45 ◼ ► But I'm not getting no new users, and I obviously want and need to keep a steady stream of people coming in because there are obviously a steady stream of people going out with every app.
00:15:54 ◼ ► So, you kind of need – you know, to maintain your user base, you have to keep having more coming in.
00:16:02 ◼ ► So, the percentage of new users that I have is way, way, way lower than the percentage of existing users that I have.
00:16:18 ◼ ► If you require only the newest OS, all this summer when – like, this summer, we have a lot of work to do to adopt this.
00:16:30 ◼ ► It helps a lot to have simpler testing in QA, and you have a lot simpler testing in QA when you're only supporting one family of OSs, not the previous ones.
00:16:41 ◼ ► And it also reduces the number of bugs that get shipped out to customers because you don't have to worry.
00:16:47 ◼ ► Oh, in my change for 26, I broke this one behavior, this one control on iOS 17, and I'm not going to necessarily know that if I don't do a very, very deep testing on the old OSs, which, let's be honest, we don't always do that.
00:17:08 ◼ ► And then finally, I worry that if I maintain compatibility with 18, I worry that that might hold back how aggressive of a design refresh I inherently do.
00:17:22 ◼ ► Like, it might hold me back from doing, like, a more pure iOS 26 redesign if I'm also trying to maintain the structure of the app.
00:17:39 ◼ ► And that is a pretty big hurdle for me to overcome with logic to say I should be responsible and maintain 18.
00:17:48 ◼ ► And I suppose maybe the next thing for me to say is the way that I do my iOS 26 or expect to do my iOS 26 updates may help you a little bit here.
00:17:59 ◼ ► So I learned this from watchOS, where watchOS is the version, you know, like what I do.
00:18:09 ◼ ► On watchOS, it's, like, immeasurably more complicated because you have the iPhone version that's different from the watch version.
00:18:15 ◼ ► And if the watch version is different, you know, like the watch app just disappears in that case from the person's watch.
00:18:21 ◼ ► They can't get the last compatible version because the version that they have is tied to their iPhone version, not the watch version.
00:18:28 ◼ ► So in there, what I've done in watchOS is I'm very conservative about dropping old versions of watchOS because the impact to the user is much more different.
00:18:39 ◼ ► You know, the second of my factors where existing users on watchOS, it's really difficult because they just lose the app.
00:18:48 ◼ ► And so I'm taking something from an existing user, which is, you know, often something I try and avoid.
00:18:58 ◼ ► So let me, like, explain my reasoning before you jump to conclusions as to whether this is a good idea,
00:19:03 ◼ ► is essentially for every major sort of time I'm redesigning or restructuring or doing compatibility work with the app,
00:19:26 ◼ ► And so you will have a lot of views that are like, you know, it's like workout view, you know, it's like underscore 18 or 10.
00:19:37 ◼ ► Like when we did the watchOS 10 redesign, I have a lot of views that just end in a 10 now.
00:19:42 ◼ ► And there's a new entry point to the app that, like, at the highest level of the app is basically like,
00:19:53 ◼ ► Oh, you know, if we're on a version that supports that, otherwise it runs the old version.
00:19:57 ◼ ► And in some ways, what I'm doing is replicating the behavior that Apple is doing with their, you know,
00:20:06 ◼ ► the last compatible version of the app system, where that code is very stable, doesn't change.
00:20:39 ◼ ► I tend to intentionally add a bunch of add available sort of modifiers to all of my new views
00:21:22 ◼ ► It is a little bit cumbersome in the sense of I have two versions of a lot of the view logic of my app.
00:21:50 ◼ ► So, like, on iOS 18, they're getting essentially the last compatible version of the app
00:22:17 ◼ ► Say there was some marketing reason, or even I wanted to add a message that was talking about,
00:22:24 ◼ ► but on a device that could support an update, there'd be this great feature if you were updated to it.
00:22:40 ◼ ► I find it so painful to have any code in SwiftUI that is designed to support two different versions of iOS.
00:23:35 ◼ ► And so that's the way that I do it, and that's what keeps me sane when I'm supporting older versions.
00:23:41 ◼ ► And that's, you know, I've spent the last few days properly getting into a redesign for Pedometer++.
00:23:57 ◼ ► But from a business perspective and from a marketing perspective and all those things, I haven't.
00:24:06 ◼ ► And there's probably people listening to this who are shouting at their podcast app right now,
00:24:23 ◼ ► It's, like, surprisingly, like, logical and clever and reasonable and something I would not have thought to do on my own,
00:24:36 ◼ ► Like, that, I feel like a lot, like, a lot of, like, you know, idiomatic development would be, like, what?
00:25:15 ◼ ► Like, if I can do that, you know, it gives me a day one releasable update that doesn't cut me off from anything.
00:25:33 ◼ ► But, like, you know, widgets, as you know, like, they've changed a lot over the last few iOS releases.
00:25:38 ◼ ► And trying to maintain a bunch of, if available, checks inside of a widget is ridiculously horrible.
00:25:54 ◼ ► But I think for the entire app, there is both, on one hand, there are, like, fewer views that will differ between the versions compared to a widget.
00:26:33 ◼ ► And one of them is that all of the advice, like, I always remember, like, when I was getting into web development and it was always, like, keep your code dry, right?
00:26:44 ◼ ► And I think the big reason for that sort of philosophy is if you expect to maintain and actively work on both parts of the app, then that is something that is a useful and, you know, like, desirable outcome.
00:27:03 ◼ ► So, if you can consolidate your logic into one location, that location will always benefit everyone else who depends on it.
00:27:10 ◼ ► Like, that is why, I think that is the motivation for the don't repeat yourself philosophy.
00:27:14 ◼ ► And, like, the reason it seems to have worked in the past for me to do this, take this approach is because I don't maintain the old version in many ways.
00:27:35 ◼ ► Like, one of them is stable and you get the benefit of, like, that iOS 18 code is never going to run on a machine running something other than iOS 18.
00:27:49 ◼ ► You know, that future compatibility issue is only ever happening on the new branch, not on the old one.
00:27:55 ◼ ► And then the other thing is in SwiftUI, like, it incentivizes you to make your UI out of lots of small atoms, you know, within the app.
00:28:06 ◼ ► So that you have lots of small little views that do one, that, you know, tend to do one thing or focus in on one particular, you know, idea.
00:28:13 ◼ ► And many of the smallest leafs in your view tree, you can share between the old version and the new version because they're not doing something complicated or, you know, nuanced or taking advantage of the new glass effect or all these kinds of things.
00:28:28 ◼ ► That they're, you know, they're the part that you can share comfortably between two views or between both sides.
00:28:34 ◼ ► And so you'll have this relatively big thing that is shared, but the big kind of like hierarchical, the navigation stack, the big kind of chunky views are the things that you're going to repeat.
00:28:44 ◼ ► And so duplicating them is much, it's much less daunting than duplicating the entire app in that way.
00:28:51 ◼ ► You're only typically having to duplicate, I find, these big structural views and then lots of the small detailed views you won't.
00:29:05 ◼ ► And if you know what you're getting into when you do this, it can have these big, you know, payoffs that you get these business benefits.
00:29:12 ◼ ► You still get the developer benefit of really your new iOS 26 work is just as though you've dropped support for iOS 18, but you haven't actually.
00:29:21 ◼ ► And so it's kind of like a best of both worlds, but, you know, your mileage may vary, I suppose, is just fair to say.