PodSearch

Under the Radar

246: Hard Forks

 

00:00:00 ◼   ► - Welcome to Under the Radar,

00:00:01 ◼   ► a show about independent iOS app development.

00:00:04 ◼   ► I'm Marco Arment.

00:00:05 ◼   ► - And I'm David Smith.

00:00:06 ◼   ► Under the Radar is usually not longer than 30 minutes,

00:00:08 ◼   ► so let's get started.

00:00:09 ◼   ► - With this episode, I've been facing a lot of

00:00:13 ◼   ► angst and stress about the giant weight

00:00:17 ◼   ► of my huge amount of legacy UI code in my app.

00:00:21 ◼   ► Because my app, it's eight years old now,

00:00:24 ◼   ► and over that time, we've had both Swift itself

00:00:29 ◼   ► and then later Swift UI come out,

00:00:32 ◼   ► in addition to just huge advances in UIKit under the hood.

00:00:36 ◼   ► And if I stay with UIKit, huge advances there

00:00:39 ◼   ► in the meantime.

00:00:40 ◼   ► And so I have all this huge mountain of legacy code

00:00:43 ◼   ► in my app that gives me a lot of stress

00:00:46 ◼   ► and makes it hard for me to make changes

00:00:49 ◼   ► and move forward and update the design and things like that.

00:00:51 ◼   ► And so I have thought for a while,

00:00:53 ◼   ► man, wouldn't it be nice to just start clean

00:00:57 ◼   ► and do a whole clean, fresh start

00:01:00 ◼   ► and rewrite the entire UI.

00:01:02 ◼   ► And that's usually a terrible idea

00:01:05 ◼   ► because it's akin to a large rewrite of your app.

00:01:09 ◼   ► And so usually I've talked myself out of that

00:01:12 ◼   ► because it just seems like this impossible mountain to climb.

00:01:16 ◼   ► And a few weeks ago, you mentioned

00:01:19 ◼   ► an interesting alternative.

00:01:22 ◼   ► That you said, why don't you just start building it

00:01:25 ◼   ► and make just this fork in the app code.

00:01:28 ◼   ► And either when you're ready or maybe only on the latest iOS

00:01:34 ◼   ► version or whatever it is, in certain test modes,

00:01:37 ◼   ► whatever it is, when you're ready,

00:01:38 ◼   ► just switch over to that UI conditionally

00:01:41 ◼   ► and still have all the old code there

00:01:43 ◼   ► in the app for when it's not running in that mode

00:01:45 ◼   ► or under those conditions.

00:01:47 ◼   ► And I thought, it's one of those things

00:01:48 ◼   ► like a programmer first hears that

00:01:50 ◼   ► and that's a terrible idea, maintenance, et cetera.

00:01:52 ◼   ► And then it starts infecting your brain a little bit.

00:01:54 ◼   ► And you've done this to me before.

00:01:56 ◼   ► It's one of those ruthlessly efficient and pragmatic things

00:02:01 ◼   ► that you introduced to my thought technologies.

00:02:04 ◼   ► I would originally think-- like when you first told me that you

00:02:07 ◼   ► stored your Git checkouts for your Macs in Dropbox,

00:02:10 ◼   ► I thought that was the craziest thing I'd ever heard.

00:02:12 ◼   ► And I'm like, wait a minute.

00:02:13 ◼   ► But then you can work on it on the laptop and the desktop.

00:02:16 ◼   ► You don't have to constantly be committing things just

00:02:18 ◼   ► to transfer to a different computer.

00:02:19 ◼   ► Interesting.

00:02:21 ◼   ► And so the idea of having an entirely separate UI branch

00:02:26 ◼   ► within my app, that sounds ridiculous.

00:02:29 ◼   ► And it sounds like a very impure thought to a programmer.

00:02:34 ◼   ► But the more I think about it, the more I think,

00:02:37 ◼   ► I actually might do that.

00:02:39 ◼   ► And I want to actually talk about it.

00:02:41 ◼   ► I want to actually get more input on that from you.

00:02:45 ◼   ► And let's elaborate on that and see, what does that look like?

00:02:48 ◼   ► Why would you do such a thing?

00:02:50 ◼   ► And are you doing such a thing in any recent stuff?

00:02:53 ◼   ► I'm glad it was an interesting thought to you.

00:02:56 ◼   ► And I think it is definitely an approach

00:02:58 ◼   ► that I've taken before.

00:02:59 ◼   ► And I think it is one of those things that is certainly not

00:03:02 ◼   ► the case for everything, that typically, I suppose,

00:03:04 ◼   ► the way that we evolve our apps is this kind of incremental--

00:03:09 ◼   ► replacing one bit-- it sort of becomes the ship of Theseus

00:03:12 ◼   ► or whatever, where it's just like you keep changing one

00:03:14 ◼   ► little bit at a time.

00:03:16 ◼   ► And eventually, you end up with something new.

00:03:18 ◼   ► But over the course of that progression, that change,

00:03:23 ◼   ► at no point was there this hard change

00:03:25 ◼   ► from one thing to the other.

00:03:26 ◼   ► And I think that approach has a lot of merit.

00:03:28 ◼   ► But it also means that you're always tied to the past.

00:03:32 ◼   ► You're always tied to your old way of doing things.

00:03:35 ◼   ► And you have to be balancing all of these things

00:03:38 ◼   ► while you're moving forward.

00:03:39 ◼   ► Because you're also-- it's one of my favorite gifts.

00:03:44 ◼   ► I think it's from Wallace and Gromit, where Gromit is

00:03:47 ◼   ► building the train track in front of his toy train

00:03:50 ◼   ► as he's riding it.

00:03:51 ◼   ► And he's just constantly building just that little bit

00:03:53 ◼   ► in front of him as he goes.

00:03:55 ◼   ► And that approach means that you always

00:03:57 ◼   ► have to have that sense of urgency,

00:03:59 ◼   ► that you're in this weird incremental process,

00:04:01 ◼   ► that you're building things.

00:04:02 ◼   ► But you're building things that are alive and in active use.

00:04:04 ◼   ► And so if anything goes wrong, bad things will happen.

00:04:07 ◼   ► And so instead, taking the approach of saying,

00:04:09 ◼   ► you know what, I'm going to completely start from zero,

00:04:13 ◼   ► essentially.

00:04:14 ◼   ► And it's not zero insofar as-- well, it's zero code.

00:04:17 ◼   ► It's not zero in terms of experience,

00:04:19 ◼   ► in terms of expectation.

00:04:20 ◼   ► You know how the app should work.

00:04:21 ◼   ► You know what it should do.

00:04:22 ◼   ► You have something to compare it to.

00:04:24 ◼   ► And free yourself from trying to have

00:04:27 ◼   ► this be an incremental thing and instead do a complete rewrite.

00:04:29 ◼   ► And for me, the first place I had this big version of this

00:04:33 ◼   ► was back when SwiftUI was introduced to watchOS.

00:04:37 ◼   ► So previous to SwiftUI's introduction to watchOS,

00:04:40 ◼   ► we had WatchKit, which was awful and really rough to use

00:04:43 ◼   ► and not fun at all.

00:04:45 ◼   ► And didn't allow a lot of cool, interesting, and fluid UIs

00:04:49 ◼   ► that you might want to build.

00:04:50 ◼   ► But then out comes SwiftUI, but it requires watchOS 6.

00:04:55 ◼   ► And so I felt in this really awkward place,

00:04:57 ◼   ► because I didn't want to feel like--

00:04:59 ◼   ► I couldn't require watchOS 6 right off the bat.

00:05:02 ◼   ► Because if I did, especially with the watch,

00:05:04 ◼   ► it creates this really weird experience

00:05:06 ◼   ► where the app just gets uninstalled from the watch

00:05:08 ◼   ► and weird things start happening.

00:05:10 ◼   ► And so I needed to keep my deployment target sort

00:05:13 ◼   ► of generous.

00:05:15 ◼   ► But I still wanted to use SwiftUI.

00:05:16 ◼   ► And so what I ended up doing with that app

00:05:18 ◼   ► is I just left the WatchKit version of the app

00:05:22 ◼   ► entirely as it was.

00:05:23 ◼   ► Like it's frozen in carbonite.

00:05:24 ◼   ► It is just right there.

00:05:26 ◼   ► And then on the Swift, then just have built out the SwiftUI app

00:05:32 ◼   ► that I'd always wanted to build that I thought was great.

00:05:34 ◼   ► And I went and built that.

00:05:36 ◼   ► And then in essentially the app delegate,

00:05:38 ◼   ► when the app is being run, which entry point the app got

00:05:41 ◼   ► was just based on, are you running watchOS 6?

00:05:44 ◼   ► Great.

00:05:44 ◼   ► You get this one.

00:05:45 ◼   ► If you're watching watchOS 5 or before,

00:05:47 ◼   ► you get the old version.

00:05:49 ◼   ► And when I did this, in some ways,

00:05:51 ◼   ► it was forced, because I wanted to use SwiftUI so soon,

00:05:54 ◼   ► to go down this road.

00:05:55 ◼   ► And I was curious to see what the result would be.

00:05:59 ◼   ► Because inevitably, what I was doing

00:06:00 ◼   ► was I was creating a situation where there were going to be

00:06:03 ◼   ► people who would see in the screenshot some

00:06:06 ◼   ► of the stuff that was there for the SwiftUI version in the app

00:06:09 ◼   ► store.

00:06:10 ◼   ► Or maybe a friend of theirs or a spouse, whatever.

00:06:14 ◼   ► They see someone else who has the app, and they--

00:06:16 ◼   ► why doesn't my app look like that?

00:06:18 ◼   ► And I was bracing for that to be an annoyance and a customer

00:06:22 ◼   ► service issue and creating confusion.

00:06:23 ◼   ► And I think in reality, it just happens much less often.

00:06:27 ◼   ► Because for most people, their experience of--

00:06:31 ◼   ► very often, people are more likely to be upset by just

00:06:35 ◼   ► any change than they are by the app just staying

00:06:39 ◼   ► the same as it was before.

00:06:41 ◼   ► And if anyone is running the old version,

00:06:43 ◼   ► they're getting exactly the same experience

00:06:45 ◼   ► that they're used to that's been there forever.

00:06:47 ◼   ► And then the new people, hopefully their experience

00:06:49 ◼   ► is positive.

00:06:49 ◼   ► And I got a little bit of people who were confused as to,

00:06:52 ◼   ► why don't I get this cool graph or the nice animations

00:06:56 ◼   ► or any of the features that were in there?

00:06:58 ◼   ► But by and large, that didn't happen.

00:07:00 ◼   ► And I really liked it.

00:07:01 ◼   ► It was a really pleasant way to develop,

00:07:04 ◼   ► because I was building the app--

00:07:07 ◼   ► when we're first writing an app, I

00:07:08 ◼   ► feel like one of the hardest things

00:07:10 ◼   ► is we don't know what the app is ultimately

00:07:12 ◼   ► going to look like, what it's ultimately going to do,

00:07:15 ◼   ► how to structure it, how to build it.

00:07:17 ◼   ► And that is just inherent to the initial creation,

00:07:21 ◼   ► that we build an app, and then it's

00:07:23 ◼   ► going to go through iteration and refinement

00:07:25 ◼   ► and get feedback from people and interact

00:07:28 ◼   ► with the real world in a way that informs us

00:07:32 ◼   ► on how the app should actually work in practice.

00:07:34 ◼   ► And so rewriting it-- in this case,

00:07:37 ◼   ► when I was rewriting the Pedometer++ WatchKit app,

00:07:42 ◼   ► the second app was actually what people wanted,

00:07:44 ◼   ► was actually what people used, was much better,

00:07:47 ◼   ► was much more performant, did all the things right.

00:07:50 ◼   ► And I was glad to be able to do this hard fork approach.

00:07:55 ◼   ► And having had that experience, I've

00:07:58 ◼   ► opened myself to this in a lot more contexts.

00:08:01 ◼   ► And I think in general, it's a way to deal with iOS versioning

00:08:05 ◼   ► is probably the main place to do this.

00:08:06 ◼   ► Like in your case, I think taking the approach of saying,

00:08:10 ◼   ► well, even though you don't strictly need to, say,

00:08:12 ◼   ► I'm going to remake the main UI in Overcast in SwiftUI,

00:08:19 ◼   ► but I'm going to target iOS 16's version of SwiftUI

00:08:24 ◼   ► and only do that.

00:08:26 ◼   ► And while technically you could go, I think, all the way back

00:08:28 ◼   ► to iOS 13, I think, with SwiftUI,

00:08:32 ◼   ► if you go back farther-- the farther you go back,

00:08:35 ◼   ► the more complicated it is to deal with compatibility,

00:08:37 ◼   ► with issues, with SwiftUI rendering differently

00:08:39 ◼   ► in two different ways.

00:08:40 ◼   ► If you go with the latest and greatest,

00:08:42 ◼   ► like once the sort of initial builds and beta stuff gets out

00:08:45 ◼   ► of the way, you'll be on a much more stable, much more smooth

00:08:48 ◼   ► ground going forward.

00:08:49 ◼   ► And then at some point, yeah, you just turn that on.

00:08:52 ◼   ► And depending on how different you make the app,

00:08:54 ◼   ► many people may not even notice.

00:08:56 ◼   ► But either way, you're in this really nice, clean place

00:08:59 ◼   ► that you have this beautiful, clean bit of code that's

00:09:01 ◼   ► all Swift, it's all modern, uses all the latest and greatest.

00:09:05 ◼   ► And then over time, the old version just kind of falls away.

00:09:08 ◼   ► And if you're gaining it based on iOS version,

00:09:10 ◼   ► eventually you'll stop supporting iOS 15.

00:09:13 ◼   ► And when you do that, the old version

00:09:14 ◼   ► just disappears from the app and will never be used again.

00:09:17 ◼   ► That fork will die, and you're just

00:09:19 ◼   ► sort of living on the new fork.

00:09:20 ◼   ► And yeah, it's a little crazy.

00:09:22 ◼   ► It's a little wild.

00:09:23 ◼   ► I understand why some people would think that it's

00:09:26 ◼   ► a bit of a weird way to go.

00:09:27 ◼   ► But I got to say, I really liked it.

00:09:30 ◼   ► And it's worked well for me in the past.

00:09:32 ◼   ► And it's like, I'm going to keep using this pattern, I think,

00:09:34 ◼   ► going forward for other projects that I'm working on this summer.

00:09:37 ◼   ► Yeah, that's really-- it's a very, very interesting way

00:09:41 ◼   ► to look at things.

00:09:43 ◼   ► I mean, it's a very pragmatic way,

00:09:45 ◼   ► as you are so good at introducing to my thoughts.

00:09:50 ◼   ► I want to do something like this in theory.

00:09:53 ◼   ► In practice, I'm not sure I will be able to go through with it.

00:09:57 ◼   ► I mean, so when I did the same transition on watchOS

00:10:01 ◼   ► that you were just talking about, when Swift UI came out

00:10:03 ◼   ► and replaced the god-awful watch kit, I was very--

00:10:07 ◼   ► I was reluctant to do that at first.

00:10:09 ◼   ► And I talked to you about it.

00:10:10 ◼   ► And you basically told me, just right from scratch,

00:10:13 ◼   ► write it fresh, see how long it takes.

00:10:14 ◼   ► And it ended up taking not that long.

00:10:16 ◼   ► And I didn't regret that decision at all.

00:10:18 ◼   ► It was great.

00:10:19 ◼   ► The outcome was great.

00:10:20 ◼   ► That has been like a thorn in my mind ever since then.

00:10:26 ◼   ► Because when I think about doing it on the iOS app, which

00:10:30 ◼   ► is a much larger task, because there's so much more UI there,

00:10:34 ◼   ► and it's more complicated.

00:10:35 ◼   ► But when I think about doing it there,

00:10:37 ◼   ► my first thought is, no, I shouldn't do that,

00:10:40 ◼   ► because it won't work out.

00:10:41 ◼   ► It'll take forever.

00:10:42 ◼   ► I'll regret it.

00:10:43 ◼   ► And then that damn watch app, I realized,

00:10:46 ◼   ► but it worked really well there.

00:10:50 ◼   ► And that keeps being this exception in my mind.

00:10:55 ◼   ► But look over here.

00:10:56 ◼   ► It worked.

00:10:57 ◼   ► And you didn't regret it.

00:10:58 ◼   ► And it was great.

00:10:59 ◼   ► So that's what has kept this kind of spark burning in my mind,

00:11:03 ◼   ► like maybe I should actually do this.

00:11:05 ◼   ► It's tough, because SwiftUI, it still

00:11:09 ◼   ► feels like you're using beta 1 of the framework.

00:11:13 ◼   ► And right now, using the iOS 16 stuff,

00:11:14 ◼   ► it actually is very much still early beta in certain ways.

00:11:17 ◼   ► And there's still some frustrating bugs.

00:11:19 ◼   ► But SwiftUI in general still feels very beta to me.

00:11:22 ◼   ► So it's hard for me to get very far with SwiftUI on iOS.

00:11:28 ◼   ► On watchOS, it's easy, because it's simple.

00:11:31 ◼   ► The needs of navigation and viewed complexity and stuff

00:11:34 ◼   ► on watchOS are so much lower than on iOS,

00:11:37 ◼   ► because it's such a simpler platform.

00:11:39 ◼   ► But on iOS, there are certain expectations

00:11:42 ◼   ► of how things should work, how things should behave,

00:11:44 ◼   ► how things should look, the kind of customization people expect.

00:11:47 ◼   ► And that's just really hard in certain ways with SwiftUI.

00:11:51 ◼   ► You hit a lot more walls.

00:11:52 ◼   ► You hit them more frequently, and you hit them harder.

00:11:54 ◼   ► And so I feel like while the transition on watchOS

00:11:58 ◼   ► was relatively smooth, the transition on iOS

00:12:02 ◼   ► probably is less so.

00:12:03 ◼   ► And at the same time, if I'm going

00:12:05 ◼   ► to do a big rewrite like this-- because again,

00:12:08 ◼   ► I have two problems.

00:12:09 ◼   ► Well, three, really.

00:12:10 ◼   ► I'm using old versions of UIKit, and there

00:12:12 ◼   ► are newer things in UIKit that can make things simpler.

00:12:15 ◼   ► I'm using still mostly Objective-C,

00:12:17 ◼   ► and I want to make most of that, or all of it, Swift.

00:12:20 ◼   ► And I'm not using SwiftUI, and that's clearly

00:12:23 ◼   ► what Apple is pushing as the way we should be doing things.

00:12:26 ◼   ► So I need to move to SwiftUI.

00:12:27 ◼   ► So ideally, if I'm going to do this big rewrite, given

00:12:31 ◼   ► how long it takes me to adopt new things,

00:12:33 ◼   ► this is the kind of thing I want to do it once

00:12:36 ◼   ► for a very long time.

00:12:37 ◼   ► I don't want to just jump to Swift with UIKit

00:12:41 ◼   ► if I can go right to SwiftUI.

00:12:44 ◼   ► And then that, I think, will buy me more time

00:12:47 ◼   ► with this new platform down the road.

00:12:48 ◼   ► And I'll be able to do certain things faster and more

00:12:51 ◼   ► efficiently.

00:12:52 ◼   ► It's just the matter of when I hit those walls,

00:12:54 ◼   ► and how many walls do I hit.

00:12:55 ◼   ► And I mean, so far, I'm hitting a lot of them.

00:12:57 ◼   ► But part of that's because I don't know it as well.

00:13:00 ◼   ► SwiftUI is more complicated.

00:13:02 ◼   ► I also have to deal with the fact

00:13:03 ◼   ► that SwiftUI has to access state and changes in certain ways.

00:13:10 ◼   ► And my underlying model layers are still mostly Objective-C.

00:13:13 ◼   ► I have some Swift in there, some Swift shims on top of it

00:13:16 ◼   ► to make SwiftUI possible.

00:13:18 ◼   ► But most of that is still not Swift.

00:13:21 ◼   ► And so-- and certainly not SwiftUI,

00:13:24 ◼   ► not like the combined publishable kind of models

00:13:28 ◼   ► that SwiftUI works on.

00:13:29 ◼   ► So if I'm going to go on SwiftUI,

00:13:31 ◼   ► I also have to do a whole bunch of that lower level changing

00:13:35 ◼   ► and bringing things up to date at the lower levels,

00:13:38 ◼   ► and simplifying certain things, rewriting certain things,

00:13:41 ◼   ► or putting shims on top of them.

00:13:42 ◼   ► So there's a lot more work to do for me to do this.

00:13:45 ◼   ► And so the risk is much greater.

00:13:48 ◼   ► But yet, I still feel like I probably should do it anyway,

00:13:51 ◼   ► because I still feel all this weight of this old code.

00:13:55 ◼   ► And it holds me back.

00:13:57 ◼   ► And it makes me-- I get this brain freeze.

00:14:00 ◼   ► It's hard for me to even work on my app

00:14:02 ◼   ► right now, because I'm blocked by so many of these things.

00:14:07 ◼   ► And if I can just unfreeze my brain and plow through,

00:14:12 ◼   ► I feel like I need something to do that.

00:14:14 ◼   ► And maybe this giant modernization project is that.

00:14:18 ◼   ► But I don't know.

00:14:19 ◼   ► That seems like a tall order.

00:14:21 ◼   ► We are brought to you this episode by Sourcegraph.

00:14:24 ◼   ► So you've hired a brilliant developer.

00:14:26 ◼   ► That's great.

00:14:27 ◼   ► Now you have to get them onboarded.

00:14:28 ◼   ► If your company is growing, onboarding new developers

00:14:30 ◼   ► is a common occurrence.

00:14:31 ◼   ► But it's a big undertaking each time.

00:14:33 ◼   ► One of the biggest challenges is to getting new hires up

00:14:36 ◼   ► to speed with their team's project.

00:14:38 ◼   ► This can be tricky if the code bases your developers are

00:14:40 ◼   ► working in are already very large.

00:14:42 ◼   ► So thankfully, Sourcegraph makes it easy to move quickly,

00:14:45 ◼   ► even in those big code bases.

00:14:47 ◼   ► Developers know that knowledge is most useful

00:14:49 ◼   ► when it's findable.

00:14:51 ◼   ► Centralization is helpful.

00:14:52 ◼   ► But given the fact that most companies store knowledge

00:14:54 ◼   ► in at least two different locations,

00:14:56 ◼   ► how do you make knowledge accessible to those who need it?

00:14:58 ◼   ► As a code intelligence platform, Sourcegraph

00:15:01 ◼   ► gives developers what they need to drive their own learning

00:15:03 ◼   ► over time and in different situations.

00:15:06 ◼   ► Teams without Sourcegraph need to rely on asking colleagues

00:15:09 ◼   ► or reviewing documentation that may be out of date, which

00:15:11 ◼   ► is cumbersome and time consuming.

00:15:13 ◼   ► But with Sourcegraph, every developer

00:15:15 ◼   ► can search across millions of repositories

00:15:17 ◼   ► to find specific code, saving time for themselves

00:15:19 ◼   ► and everyone else.

00:15:21 ◼   ► So when questions do come up, you

00:15:22 ◼   ► know it's the big stuff that's worthy of the extra time.

00:15:25 ◼   ► Sourcegraph was created to make developers' lives easier.

00:15:28 ◼   ► And today, they work with leading companies

00:15:30 ◼   ► across every industry, including three out of five

00:15:32 ◼   ► of the top tech companies, plus PayPal, Uber, Plaid, GE, Reddit,

00:15:36 ◼   ► and Atlassian.

00:15:38 ◼   ► Visit about.sourcegraph.com to learn more.

00:15:41 ◼   ► That's about.sourcegraph.com to find out

00:15:45 ◼   ► why some of the biggest tech companies in the world

00:15:47 ◼   ► use Sourcegraph and to see what it can do for yours.

00:15:49 ◼   ► Or to click the link in the show notes

00:15:51 ◼   ► to let them know that you heard about them from us.

00:15:53 ◼   ► Our thanks to Sourcegraph for their support of this show

00:15:56 ◼   ► and Relay FM.

00:15:57 ◼   ► So I think that there's two things that really come to mind

00:16:00 ◼   ► as you unpack the resistances or the issues

00:16:03 ◼   ► that you feel like you're coming up against.

00:16:05 ◼   ► And it's like, I think the first one is there's the reality

00:16:09 ◼   ► that if we never changed our apps at all,

00:16:13 ◼   ► like if you just left the version that you have right now

00:16:15 ◼   ► in the App Store, the amount of time

00:16:18 ◼   ► that it would be that that would just work fine and be great

00:16:23 ◼   ► for most of your users is surprisingly long.

00:16:28 ◼   ► It's something that, barring potentially like weird--

00:16:31 ◼   ► there's a new screen size such that the app gets letterboxed

00:16:36 ◼   ► if it isn't rebuilt or something like that,

00:16:38 ◼   ► which is relatively easy to fix.

00:16:41 ◼   ► It's a weird thing to think that that really old code could just

00:16:44 ◼   ► exist for a long time.

00:16:46 ◼   ► And I think accepting that, accepting that that old code

00:16:49 ◼   ► isn't necessarily bad or needs to be changed or modernized

00:16:53 ◼   ► and kept current is freeing in this way.

00:16:56 ◼   ► That I think viewing it that you have this ability

00:16:59 ◼   ► to draw a boundary around where the new stuff is going to go

00:17:02 ◼   ► and the old stuff is just working like it always has been

00:17:05 ◼   ► and always will be, and that this new version is

00:17:08 ◼   ► different and distinct from it.

00:17:09 ◼   ► And I think for me, it would be the freedom

00:17:12 ◼   ► of being able to say, the old version is fine.

00:17:14 ◼   ► And if that's-- well, in theory, you think,

00:17:17 ◼   ► oh, I don't want to have to maintain

00:17:18 ◼   ► both versions of my app.

00:17:20 ◼   ► Now it's like, now I have two things to manage.

00:17:23 ◼   ► That's technically true.

00:17:25 ◼   ► But in practice, in reality, I think

00:17:28 ◼   ► isn't actually what happens in practice.

00:17:30 ◼   ► That more often than not, the old stuff is mostly fine.

00:17:33 ◼   ► And it won't actually cause problems or issues for you.

00:17:36 ◼   ► Because that's just the reality.

00:17:38 ◼   ► One of the best things about being an independent developer

00:17:42 ◼   ► is when I go on vacation, and I'll go away

00:17:44 ◼   ► for a couple of-- go away for two weeks, come back,

00:17:47 ◼   ► and everything's still the same as it was.

00:17:49 ◼   ► Everything's still working.

00:17:50 ◼   ► It's not like servers.

00:17:51 ◼   ► It's not like something where you have this--

00:17:53 ◼   ► there's this sense of this active energy has

00:17:55 ◼   ► to be poured into the system in order

00:17:57 ◼   ► to keep it going, that an app that

00:17:59 ◼   ► is in a good, stable place that isn't full of bugs

00:18:03 ◼   ► or something like that, once it reaches this equilibrium point,

00:18:07 ◼   ► it can sit there for a very long time.

00:18:10 ◼   ► And I think the other thing that really just popped

00:18:13 ◼   ► into my head was the thought that something like SwiftUI

00:18:16 ◼   ► and something like a rewrite is also an opportunity

00:18:20 ◼   ► to change the way that you are approaching things

00:18:26 ◼   ► and to not just modernize your code,

00:18:29 ◼   ► but also to modernize your thinking, your structure,

00:18:33 ◼   ► the way that you're building things.

00:18:35 ◼   ► And I can say from my own experience,

00:18:37 ◼   ► having built a lot of apps now in SwiftUI--

00:18:40 ◼   ► and WidgetSmith is essentially entirely SwiftUI,

00:18:43 ◼   ► with a few UI kit hooks here and there

00:18:45 ◼   ► where I have to go into a low-level thing

00:18:48 ◼   ► to hook into a system something or things like that.

00:18:50 ◼   ► But the main structure of the app, everything like that,

00:18:52 ◼   ► is SwiftUI, is when I first started building in SwiftUI,

00:18:59 ◼   ► I was building a UI kit app in SwiftUI.

00:19:02 ◼   ► And as a result, I hit lots of walls

00:19:07 ◼   ► and felt like I was constantly bumping into the edges,

00:19:10 ◼   ► that I kept saying, oh, this is how I would do it,

00:19:12 ◼   ► or this is how I would structure my code,

00:19:14 ◼   ► or this is what it would look like in UI kit.

00:19:17 ◼   ► How do I do that in SwiftUI?

00:19:20 ◼   ► And in a weird way, the image that comes into my mind

00:19:26 ◼   ► is to think of water flowing down a hill, where

00:19:30 ◼   ► when the water flows down a hill,

00:19:32 ◼   ► it will encounter resistance.

00:19:33 ◼   ► It'll smash into a rock or run into a bank or something.

00:19:38 ◼   ► And all it does is it just gently turns and follows

00:19:42 ◼   ► to the side and will just keep finding the easy path until it

00:19:46 ◼   ► gets all the way to the bottom.

00:19:48 ◼   ► And I think once I-- it was a bit zen to say,

00:19:51 ◼   ► but once my SwiftUI development became

00:19:54 ◼   ► flowing like water down a hill, everything got a lot easier.

00:19:58 ◼   ► Where if I start doing counter-resistance,

00:20:00 ◼   ► I think to my-- rather than like, ooh, this is SwiftUI

00:20:02 ◼   ► being annoying and getting in my way, I sort of think, huh,

00:20:06 ◼   ► am I doing this the way that I should?

00:20:09 ◼   ► Is this a symptom of me not using SwiftUI in the way

00:20:12 ◼   ► it is best used?

00:20:14 ◼   ► And most often, that was the case.

00:20:16 ◼   ► How could I change it to flow with SwiftUI in the way

00:20:19 ◼   ► that it's expecting and get back into its path?

00:20:21 ◼   ► And as soon as-- very few times in the development

00:20:25 ◼   ► of Widgetsmith, which is a very complicated, large app

00:20:28 ◼   ► with all kinds of features and a very wide user base,

00:20:31 ◼   ► there was a solution that was more SwiftUI-ish and got me

00:20:35 ◼   ► to where I wanted to go.

00:20:36 ◼   ► And sometimes that means that feature doesn't quite

00:20:38 ◼   ► look the way that it could on UIKit

00:20:40 ◼   ► or the way that I may have initially imagined it to look.

00:20:45 ◼   ► But I can get to a place that is reasonable, that is workable,

00:20:49 ◼   ► that very often is very clean from a code perspective

00:20:52 ◼   ► and ends up being really good.

00:20:54 ◼   ► Like, I'm a huge fan of SwiftUI.

00:20:56 ◼   ► And now when I go back and have to do some work in UIKit,

00:20:59 ◼   ► I just like, I don't even know what I'm doing.

00:21:00 ◼   ► I feel like I'm coding with oven mitts on.

00:21:02 ◼   ► And so that transition is difficult and not something

00:21:06 ◼   ► that is right away.

00:21:07 ◼   ► But it was certainly something that I found that--

00:21:10 ◼   ► and especially having the freedom to be all SwiftUI

00:21:12 ◼   ► rather than cobbling something together where you're like,

00:21:15 ◼   ► oh, I'm going to replace just this TableView cell in SwiftUI,

00:21:18 ◼   ► or I'm just going to sort of start shimming things in here

00:21:20 ◼   ► and there, made it really hard to get full SwiftUI

00:21:24 ◼   ► and get all of the benefits and all of the velocity

00:21:27 ◼   ► that that enables.

00:21:30 ◼   ► And if you-- and so without that velocity, then what's the point?

00:21:34 ◼   ► Just stick with what you have and just hope

00:21:38 ◼   ► that that lasts for long enough that you can--

00:21:42 ◼   ► at some point, you will stop needing to maintain Overcast,

00:21:45 ◼   ► whatever that is, in 10 years, 15 years,

00:21:47 ◼   ► and just ride it into the ground.

00:21:49 ◼   ► But otherwise, to modernize it, you really

00:21:52 ◼   ► have to just sort of embrace that future in that way.

00:21:55 ◼   ► Yeah, that's a good way to look at it.

00:21:57 ◼   ► I mean, you mentioned all the shimming and everything

00:21:59 ◼   ► if you try to do a piecemeal approach.

00:22:01 ◼   ► And I've been running into that all the time.

00:22:03 ◼   ► I mean, when I was doing my first phase

00:22:08 ◼   ► of my big redesign over the last six months

00:22:11 ◼   ► or whatever it was-- oh, more than that.

00:22:12 ◼   ► Geez, almost a year.

00:22:14 ◼   ► When I was doing that, I made the decision--

00:22:16 ◼   ► I talked about it on the show-- that things that were already

00:22:19 ◼   ► Objective-C-- like if I was working within a view

00:22:21 ◼   ► controller, if that view controller was already

00:22:23 ◼   ► Objective-C, I wasn't going to rewrite it in Swift.

00:22:26 ◼   ► I did a lot of that work in Objective-C.

00:22:27 ◼   ► And that actually held me back a lot,

00:22:30 ◼   ► and it made certain things harder, as many of the APIs

00:22:33 ◼   ► are decreasingly designed for Objective-C.

00:22:36 ◼   ► And I actually-- I think that was the wrong decision

00:22:40 ◼   ► in retrospect.

00:22:41 ◼   ► While it brought the design forward,

00:22:43 ◼   ► it didn't bring any of the code forward.

00:22:45 ◼   ► And it didn't decrease my technical debt in this way.

00:22:49 ◼   ► It actually increased it, if anything.

00:22:51 ◼   ► And it made certain parts of the iteration process,

00:22:53 ◼   ► which is most of what design is, most of its iteration.

00:22:56 ◼   ► It doesn't take me six months to write a few theme changes

00:22:59 ◼   ► to a view controller.

00:23:00 ◼   ► It takes me six months to try all the different things I

00:23:02 ◼   ► have in mind and see what works.

00:23:03 ◼   ► If I was going to do more of this design work, which

00:23:06 ◼   ► is what I'm trying to tackle now,

00:23:07 ◼   ► with the Now Playing screen and the podcast screen,

00:23:09 ◼   ► I am not going to make that same choice that way.

00:23:11 ◼   ► Now, I want to rewrite those screens completely.

00:23:15 ◼   ► And another major thing-- my app has not yet

00:23:18 ◼   ► used the new Swift async stuff yet.

00:23:20 ◼   ► And I actually just had to add that to this CloudKit code,

00:23:24 ◼   ► because they deprecated some of the old CloudKit methods

00:23:27 ◼   ► already.

00:23:28 ◼   ► And so I had to start using that.

00:23:29 ◼   ► And that's another thing, where if your app is not

00:23:31 ◼   ► made with all the async stuff in mind,

00:23:33 ◼   ► that's another huge migration that, over time,

00:23:36 ◼   ► needs to happen.

00:23:37 ◼   ► My current thinking is that leaving things that were

00:23:41 ◼   ► already the old way-- Objective-C, UI Kit--

00:23:44 ◼   ► leaving things that way, if they already were, was a mistake.

00:23:48 ◼   ► I now regret that.

00:23:49 ◼   ► And I now think that I want to do any future work

00:23:54 ◼   ► in this clean start kind of way.

00:23:57 ◼   ► And that's going to take a long time.

00:23:59 ◼   ► But I think you're right, though,

00:24:00 ◼   ► that the app overall, the UI and everything, is very stable.

00:24:04 ◼   ► And I don't really need to rush to do something quickly

00:24:08 ◼   ► right now.

00:24:10 ◼   ► I should probably be taking the time to do it right

00:24:13 ◼   ► and to pay down this technical debt in a way that

00:24:16 ◼   ► will allow me to work better in the future,

00:24:20 ◼   ► even if that means basically a rewrite of most of the UI.

00:24:24 ◼   ► And I think, too, the end result of that

00:24:26 ◼   ► is that it is a wonderful thing in the current environment

00:24:31 ◼   ► as an iOS developer to be an expert at Swift and SwiftUI.

00:24:36 ◼   ► That is the skill set that, going forward,

00:24:40 ◼   ► is going to be clearly-- that's where the energy is going

00:24:44 ◼   ► from Apple's perspective.

00:24:45 ◼   ► That's where, as a community, things are going.

00:24:47 ◼   ► And the quicker you can get yourself

00:24:51 ◼   ► into that place, where you can code in SwiftUI just as well

00:24:55 ◼   ► as you used to be able-- as you could in UI Kit--

00:24:57 ◼   ► it's setting yourself up for opportunity and success

00:25:00 ◼   ► in the future.

00:25:01 ◼   ► And I worry that if you take the approach of doing it

00:25:05 ◼   ► more piecemeal and trying to carry around the old code

00:25:08 ◼   ► and doing it as you go, is you're never

00:25:11 ◼   ► going to be able to be free of the past,

00:25:14 ◼   ► such that you're going to be able to really embrace

00:25:16 ◼   ► the future and to be able to really build things in the way

00:25:20 ◼   ► that, at some point, you're going to have

00:25:23 ◼   ► an idea for another app, inevitably.

00:25:25 ◼   ► I mean, that's just-- if you're anything like me,

00:25:27 ◼   ► and I think you've built a couple things over the years.

00:25:30 ◼   ► So those ideas will come.

00:25:32 ◼   ► And SwiftUI is great for rapid prototyping,

00:25:35 ◼   ► for quickly exploring ideas, or even

00:25:37 ◼   ► if you have an idea for a new feature in Overcast.

00:25:41 ◼   ► And it's like, you decide you're going to add a stats area

00:25:44 ◼   ► to show people their listening history over time, say.

00:25:47 ◼   ► And you want to use Swift charts for this,

00:25:50 ◼   ► or whatever that might be.

00:25:52 ◼   ► The farther the app is in that direction

00:25:55 ◼   ► to accept those new ideas, I think,

00:25:57 ◼   ► will just allow you to be in this fresh space.

00:26:01 ◼   ► And I think that's why I was initially thinking of nudging

00:26:06 ◼   ► you in this direction and encouraging you to avoid--

00:26:10 ◼   ► feeling the weight of--

00:26:12 ◼   ► carrying around all this technical debt

00:26:14 ◼   ► and having it feel like weight, rather than just saying,

00:26:16 ◼   ► you know what?

00:26:17 ◼   ► The code is fine.

00:26:18 ◼   ► It works great.

00:26:19 ◼   ► I'm going to partition it here.

00:26:20 ◼   ► I'm going to start this new thing.

00:26:22 ◼   ► I know you know exactly what you're building in terms of it's

00:26:24 ◼   ► not an exploration, so you're not

00:26:26 ◼   ► going to waste a lot of time there.

00:26:27 ◼   ► And I would be very surprised if you just sort of sat down

00:26:30 ◼   ► and worked diligently on it, that if you weren't able to

00:26:32 ◼   ► build the vast majority of Overcast,

00:26:35 ◼   ► again, much more quickly, in a matter of a few weeks,

00:26:38 ◼   ► that you could have a basically working, rebuilt version of it.

00:26:42 ◼   ► And then obviously, the actual refinement of that

00:26:45 ◼   ► and filling it out will take some extra time.

00:26:47 ◼   ► But at least spending that initial time to say,

00:26:49 ◼   ► I'm going to rebuild the now playing screen in SwiftUI,

00:26:53 ◼   ► and seeing how long that takes, and seeing

00:26:55 ◼   ► what that looks like as a clean rewrite, I think

00:26:57 ◼   ► would be a really instructive time, and certainly something

00:27:00 ◼   ► that would be well spent to see where that goes.

00:27:03 ◼   ► And if it does work, then great.

00:27:05 ◼   ► And it's just like, the now playing screen,

00:27:06 ◼   ► if you're on, whatever, an iOS 16,

00:27:08 ◼   ► is just different than the old one.

00:27:09 ◼   ► And that's fine.

00:27:10 ◼   ► And that works great.

00:27:11 ◼   ► And I don't think anyone would notice, or if they did,

00:27:14 ◼   ► it would hopefully be noticing it in a positive sense.

00:27:17 ◼   ► It's funny you mention that, because that's literally

00:27:19 ◼   ► what I tried to do over the last few days,

00:27:21 ◼   ► was the now playing screen.

00:27:23 ◼   ► And that was my first thought.

00:27:25 ◼   ► Oh, let me do this in SwiftUI.

00:27:26 ◼   ► However, I ran into a wall immediately,

00:27:29 ◼   ► which is that the now playing screen, the same view

00:27:32 ◼   ► controller is operating both when

00:27:35 ◼   ► it is minimized to the toolbar and when it is fully expanded.

00:27:38 ◼   ► It's the same view controller.

00:27:39 ◼   ► It's the same views that shrink down and join

00:27:42 ◼   ► their new positions down below.

00:27:45 ◼   ► And it's an interactive transition.

00:27:47 ◼   ► And so I could not for the life of me

00:27:50 ◼   ► figure out how to do that without everything else being

00:27:53 ◼   ► SwiftUI around it.

00:27:55 ◼   ► That's when I started getting into, oh, let me try SwiftUI

00:27:56 ◼   ► navigation stuff.

00:27:57 ◼   ► It's new in iOS 16.

00:27:59 ◼   ► And I just slammed into so many walls doing that,

00:28:03 ◼   ► and what seemed like bugs and limitations.

00:28:06 ◼   ► And I just couldn't break through.

00:28:09 ◼   ► I couldn't make it happen.

00:28:10 ◼   ► And so I just gave up.

00:28:12 ◼   ► And I was just going to go for a dog walk

00:28:14 ◼   ► and have dinner with my family and think about what

00:28:16 ◼   ► I'm doing with my life.

00:28:19 ◼   ► But maybe it didn't have to be that way.

00:28:21 ◼   ► I mean, I don't know.

00:28:22 ◼   ► I'm sure there's a way to do this piecemeal.

00:28:24 ◼   ► But I think it's going to be much easier

00:28:26 ◼   ► to do it all at once.

00:28:27 ◼   ► Yeah, exactly.

00:28:29 ◼   ► And I think you're going to encounter

00:28:30 ◼   ► so many of those things get easier when it's all one

00:28:33 ◼   ► or it's all the other.

00:28:34 ◼   ► And if you're only dropping down to UI Kit

00:28:37 ◼   ► when you absolutely have to, I think

00:28:39 ◼   ► we'll go a long way to making this work.

00:28:42 ◼   ► And the reality is if in the end you decide you don't like it

00:28:45 ◼   ► and you go down this road for a couple of weeks

00:28:49 ◼   ► and you decide, you know what, this isn't for me,

00:28:52 ◼   ► then you've gotten several weeks of experience

00:28:55 ◼   ► doing SwiftUI work, which is making you a better SwiftUI

00:28:57 ◼   ► developer, which is definitely helpful.

00:28:59 ◼   ► And you're no worse off.

00:29:00 ◼   ► You can go back and sort of think about it

00:29:02 ◼   ► and take a different approach later.

00:29:03 ◼   ► Because the nice thing about a hard fork

00:29:05 ◼   ► is you're not breaking the old version in the process.

00:29:08 ◼   ► You're just completely clean and separate.

00:29:09 ◼   ► And it's a nice, straightforward path forward as a result.

00:29:13 ◼   ► Yeah.

00:29:14 ◼   ► Thanks for listening, everybody.

00:29:16 ◼   ► And we'll talk to you in two weeks.

00:29:17 ◼   ► Bye.