203: Modernizing Overcast
00:00:00
◼
►
Welcome to Under the Radar, a show about independent iOS app development.
00:00:04
◼
►
I'm Marco Arment.
00:00:05
◼
►
And I'm David Smith. Under the Radar is never longer than 30 minutes, so let's get started.
00:00:09
◼
►
So I am riding a lot of Swift finally.
00:00:13
◼
►
I know, it only took what, six years, five years?
00:00:17
◼
►
Many years, I don't know.
00:00:19
◼
►
Probably, like, early on it was fine to wait.
00:00:22
◼
►
I think it's probably been at least two years too late that I've jumped in at this point.
00:00:26
◼
►
There was a window when it was like, you know, I think it's appropriate to be cautious about this new technology.
00:00:32
◼
►
Like, especially in those early years where code compatibility was not something that was required.
00:00:37
◼
►
I mean, the ABI wasn't even stable for a while.
00:00:41
◼
►
But I feel like we're well past that at this point.
00:00:45
◼
►
Yeah, like, I very much am happy I wasn't a Swift beta tester, basically.
00:00:49
◼
►
Because that requires you to be a certain level of enthusiast and language nerd that I am not.
00:00:54
◼
►
And with a certain level of patience that I don't have.
00:00:57
◼
►
And so I've waited until it is very, very stable and not changing very much anymore.
00:01:04
◼
►
And that's when I jumped in. And I feel good about that.
00:01:07
◼
►
And one of the reasons why I did that is because I decided this past few weeks,
00:01:16
◼
►
the HomePod mini was announced and with it a whole bunch of updates to what HomePods can do.
00:01:23
◼
►
The HomePod mini is a very attractive price.
00:01:26
◼
►
And while nobody has them yet, I have a feeling it's probably going to succeed as a general device.
00:01:31
◼
►
And they're probably going to sell a good number of them.
00:01:33
◼
►
And so I was curious to really make sure that Overcast can be good on the HomePod.
00:01:41
◼
►
And I already did AirPlay 2 last year.
00:01:45
◼
►
And it was a massive job and in retrospect possibly not worth it.
00:01:49
◼
►
But it was a big deal and I eventually got there and it was fine.
00:01:53
◼
►
But I didn't have good Siri intent support.
00:01:57
◼
►
Or I don't know what to call this. Is it intense?
00:02:00
◼
►
It used to be a one-time called Shortcuts, then Siri Shortcuts, then Intents, and now just Siri integration?
00:02:08
◼
►
It sort of makes me think of NSUserActivity.
00:02:12
◼
►
It's one of these things where there's technological aspects to it that are different.
00:02:18
◼
►
Like you use Intents to configure your widgets, which has nothing to do with Siri at all.
00:02:24
◼
►
But I think the thing you're talking about is being able to say, "Excuse me, lady in the dome."
00:02:32
◼
►
I don't know. "In the snowball. Excuse me, snowball. Would you play the latest episode of ATP in Overcast?"
00:02:39
◼
►
That's what you're after, right?
00:02:41
◼
►
The ability to ask the snowball to play something.
00:02:45
◼
►
I think that's Siri Shortcuts, I think.
00:02:49
◼
►
Yeah, or it at least uses Intents and it uses the Play Media intent and everything.
00:02:53
◼
►
So anyway, Overcast has supported Intents since they came out for, I believe it was iOS 12.
00:02:58
◼
►
It was either 11 or 12. I forgot one of those.
00:03:01
◼
►
And when I wrote that first version of it, this is when Shortcuts launched and with the API and everything,
00:03:07
◼
►
it was pretty rough to work with. It was a very clunky workflow.
00:03:11
◼
►
You had this giant, weird, plist, GUI configurator in Overcast to configure your Intents.
00:03:17
◼
►
And then what you had to do to get parameters and stuff was always a big pile of hacks
00:03:23
◼
►
because it didn't actually support native parameterization.
00:03:25
◼
►
And what you could do as a media app for play or pause, you had to do so much stuff manually and hacky.
00:03:31
◼
►
And it was buggy and it didn't work well and the API was kind of miserable to work with.
00:03:36
◼
►
On top of that, I was working with it from Objective-C, which you can do,
00:03:42
◼
►
but it would frequently cause problems in Xcode because all those Intents from that weird plist thing
00:03:48
◼
►
get automatically generated into classes that get magically imported into your project.
00:03:52
◼
►
And that doesn't work a lot of times with Objective-C.
00:03:55
◼
►
It'll break the build in weird ways that you'll have to clean the build folder and hope it builds the second time.
00:03:59
◼
►
I mean, all those weird bugs that we had.
00:04:01
◼
►
And so this was a big pile of hacks. And then when iOS 13 came out last year,
00:04:06
◼
►
they added with the 13 SDK a whole bunch of improvements to this.
00:04:10
◼
►
They added media Intents that could actually take parameters,
00:04:13
◼
►
you could actually specify what your library of content was to the Siri API.
00:04:18
◼
►
So you could say, "Here's the list of titles of playlists in my app. Here's the list of titles of podcasts.
00:04:23
◼
►
My app, by the way, is a podcast app instead of a music app."
00:04:26
◼
►
And you could specify all this stuff.
00:04:28
◼
►
I had this old iOS 12 system that I hated that was a big pain in the butt to build.
00:04:33
◼
►
And you were still doing all this stuff through the Intents extension.
00:04:38
◼
►
And so in order to make this work, you had to have this data shuffling between the extension and the main app,
00:04:44
◼
►
as you do with any extension.
00:04:46
◼
►
And that's one thing when it's simple things like, "Tell the app this command."
00:04:51
◼
►
It's a whole other thing when you have to expose your entire library of content through it
00:04:55
◼
►
and have it navigate and perform searches and everything.
00:04:57
◼
►
It just becomes very complicated.
00:04:59
◼
►
So I kind of punted on that.
00:05:01
◼
►
I had seen that not a lot of people were using the Intents I had built for iOS 11 or 12.
00:05:07
◼
►
And so I thought last year when 13 came out, this isn't worth adopting yet.
00:05:11
◼
►
I'll put this on the back burner.
00:05:13
◼
►
I have more important things to do that more people are using right now.
00:05:16
◼
►
So I kind of put it on hold.
00:05:19
◼
►
So now iOS 14 comes out.
00:05:23
◼
►
14 SDK introduces a major new improvement to this,
00:05:27
◼
►
which is that you can now get rid of the extension and perform whatever Intents you want right in your app.
00:05:34
◼
►
It'll just background launch your app.
00:05:36
◼
►
That's amazing.
00:05:37
◼
►
Yes! That's a huge improvement because that needs way less code.
00:05:42
◼
►
But in order to do this, you have to adopt the new "scene" -- "new" in quotes -- "scene" APIs.
00:05:50
◼
►
The new "new" last year.
00:05:52
◼
►
Was it even that recent?
00:05:54
◼
►
I think it was new last year. I'm pretty sure.
00:05:56
◼
►
Anyway, so you have to adopt the "scene" APIs.
00:05:59
◼
►
So much of your app delegate stuff moves into the new "scene" delegate.
00:06:04
◼
►
By the way, there can be multiple "scene" delegates.
00:06:06
◼
►
You better account for that and things like that.
00:06:08
◼
►
And so I took this opportunity with my six-year-old app.
00:06:12
◼
►
So you can imagine the app delegate of a six-year-old app.
00:06:16
◼
►
It's large, is my guess.
00:06:19
◼
►
Especially because it's Objective-C, so it's all one file, too.
00:06:22
◼
►
Well, actually, no. I had actually split it up.
00:06:25
◼
►
I had two category files that extended it.
00:06:27
◼
►
I had one for notifications and one for intent handling.
00:06:30
◼
►
So I had split off some functionality, but not most.
00:06:33
◼
►
Most of it was one big file.
00:06:35
◼
►
And the other thing motivating this was
00:06:39
◼
►
I decided over the summer, you know what, this whole widget thing,
00:06:43
◼
►
I don't know if it's going to be a big deal.
00:06:45
◼
►
I don't think a lot of people are going to use widgets.
00:06:47
◼
►
No, no one's going to use widgets.
00:06:49
◼
►
It's a passing fad.
00:06:51
◼
►
Yeah, well, like iMessage apps.
00:06:53
◼
►
I thought, like, Apple launches all sorts of--
00:06:55
◼
►
TV OS, like, Apple launches all sorts of stuff that
00:06:57
◼
►
we think might be a big deal, and then it comes out and no one uses it.
00:07:00
◼
►
And I'm like, OK, well, I guess, you know, oh, well, if we skipped it, great.
00:07:04
◼
►
And if we didn't skip it, well, there goes a bunch of wasted effort, right?
00:07:07
◼
►
So I decided, let me hold off on widgets.
00:07:10
◼
►
I was using them myself during the beta period.
00:07:13
◼
►
I was trying them out.
00:07:14
◼
►
And I wasn't finding them incredibly useful because they were so big.
00:07:17
◼
►
I didn't have space for them on my home screen and stuff.
00:07:20
◼
►
So I thought, you know what, this will probably pass.
00:07:22
◼
►
And, well, you, more than anybody, knows that didn't really happen.
00:07:26
◼
►
And it turns out they're a big deal.
00:07:28
◼
►
And I am having competitive pressure from my users.
00:07:33
◼
►
And I'm actually getting one-star reviews, like, meaningfully now
00:07:38
◼
►
because I don't have a widget yet.
00:07:40
◼
►
That's harsh.
00:07:41
◼
►
Tell me about it.
00:07:43
◼
►
And so I decided, like, OK, I should probably actually do this.
00:07:47
◼
►
Like, enough of my customers are wanting this.
00:07:49
◼
►
I need to do this.
00:07:50
◼
►
Well, widgets, as you said, also use the intent API.
00:07:55
◼
►
And also, you know, our modern extensions that need some of this stuff.
00:08:00
◼
►
I need to learn Swift UI.
00:08:02
◼
►
I need to learn more Swift and everything.
00:08:04
◼
►
So I thought, this is a great time to rewrite my app delegate,
00:08:10
◼
►
to use the new scene API so I can get the Siri support with the background app stuff.
00:08:16
◼
►
So I can also use all the new stuff with the HomePod integration.
00:08:19
◼
►
So I can also use better Siri integration.
00:08:22
◼
►
And, by the way, this would also make widgets easier.
00:08:25
◼
►
And, by the way, if I separate all these things,
00:08:27
◼
►
I can also make my watch app better for boring reasons
00:08:30
◼
►
that won't fit in a 30-minute podcast.
00:08:32
◼
►
So, and my watch app is basically on fire right now.
00:08:35
◼
►
Like, it's a terrible mess.
00:08:36
◼
►
Like, the syncing of episodes for offline playback on the watch
00:08:41
◼
►
is completely broken for a lot of people.
00:08:44
◼
►
Not everybody, but for a lot of people.
00:08:45
◼
►
And I have to fix that.
00:08:47
◼
►
And so there's all sorts of things that have piled up.
00:08:51
◼
►
So I've decided to tackle one of the stupidest things you can do as a programmer,
00:08:56
◼
►
a big rewrite.
00:08:58
◼
►
But I focused it so it wasn't totally killing my business.
00:09:01
◼
►
I focused it only on the app delegate, the now new scene delegate,
00:09:06
◼
►
moving a whole bunch of the data and sync engine stuff
00:09:10
◼
►
into a new thing called the session that is cross-compiling with watchOS.
00:09:17
◼
►
So I can have the exact same data and sync layer between watchOS and iOS
00:09:21
◼
►
and whatever else OS comes later.
00:09:24
◼
►
So, you know, and it's so much work.
00:09:27
◼
►
Just pulling out calls from the model layer that went to the app delegate for some reason.
00:09:32
◼
►
Or all this weird little spaghetti that you tell yourself you're never going to do,
00:09:36
◼
►
but in practice you end up doing.
00:09:38
◼
►
I mean, that's--
00:09:39
◼
►
And in-- it sounds like you're being down on yourself.
00:09:41
◼
►
Like, that's the-- it is often just-- that's the path of least resistance,
00:09:46
◼
►
the obvious thing.
00:09:47
◼
►
And if you go too crazy separating things out from the start,
00:09:52
◼
►
you end up building all this infrastructure that you may not ever actually need.
00:09:56
◼
►
Like, you build the thing so that it's generic and can be used anywhere,
00:09:59
◼
►
but it's actually only used in one place.
00:10:01
◼
►
And so don't be too hard on yourself in terms of, like, doing that.
00:10:04
◼
►
But yes, the process of unraveling that when it does come time
00:10:07
◼
►
is certainly not straightforward.
00:10:10
◼
►
And I also decided while I'm rewriting my six-year-old app delegate
00:10:14
◼
►
and breaking up all this code, I should do the new one in Swift.
00:10:18
◼
►
And so I've been finally, for the first time ever,
00:10:22
◼
►
plowing ahead with Swift at full speed.
00:10:25
◼
►
Not just using it piecemeal here and there,
00:10:28
◼
►
but, like, all the new code I'm writing is Swift now.
00:10:32
◼
►
And that's something I've never been able to say.
00:10:34
◼
►
Because you'd previously used it in your Today View.
00:10:36
◼
►
Am I remembering this right?
00:10:38
◼
►
There was some part of your app that you used it before, but--
00:10:42
◼
►
Yeah, like, I used it in a couple of extensions here and there.
00:10:44
◼
►
A couple of the classes in the main app were Swift before,
00:10:47
◼
►
but not many because it's a giant Objective-C app.
00:10:50
◼
►
And it just made pragmatic sense most of the time
00:10:54
◼
►
when I was working with other Objective-C code
00:10:56
◼
►
to just write new stuff in Objective-C when it came up.
00:10:58
◼
►
But now I decided I'm going to do this from the ground up.
00:11:01
◼
►
And I'm not going to rewrite stuff for no reason if it works
00:11:04
◼
►
and if there's no motivating SDK or competitive reason to update it.
00:11:09
◼
►
But now I'm saying everything I'm doing that's new,
00:11:11
◼
►
that's updated for good reasons or that is new code,
00:11:14
◼
►
that's all Swift now.
00:11:16
◼
►
And that's something that's brand new for me.
00:11:17
◼
►
And so I took this entire--
00:11:19
◼
►
the last two weeks since we last talked,
00:11:21
◼
►
I have been doing tons of work just refactoring and restructuring
00:11:26
◼
►
and rewriting a lot of that low-level code in the app.
00:11:29
◼
►
And I finally-- I have it now.
00:11:31
◼
►
It's running on my phone.
00:11:32
◼
►
It seems to be fine.
00:11:34
◼
►
I'm not brave enough to put it in beta yet.
00:11:36
◼
►
I want to do more testing.
00:11:38
◼
►
But it seems okay.
00:11:41
◼
►
And it just-- and so much of the app has been touched by this.
00:11:44
◼
►
Like, just-- but in ways that a user would never know.
00:11:47
◼
►
Like, just would never see.
00:11:49
◼
►
All this is to say I have reached a point now
00:11:52
◼
►
where I have the app and scene delegate all rewritten.
00:11:55
◼
►
It's all Swift.
00:11:56
◼
►
I have the Siri intent support, whatever it's called.
00:11:58
◼
►
I have the-- all that stuff going great.
00:12:01
◼
►
So you can say, like, hey, thing, play--
00:12:04
◼
►
you know, play-- and you can name any podcast,
00:12:06
◼
►
whether you subscribe to it or not,
00:12:08
◼
►
and you can say play that in Overcast
00:12:10
◼
►
and it will play it no matter what.
00:12:12
◼
►
That's great.
00:12:13
◼
►
If you don't have it, it'll add it.
00:12:14
◼
►
It'll perform a web search if it has to.
00:12:16
◼
►
Like, all that stuff is all done.
00:12:18
◼
►
You can ask for your playlist by name, of course.
00:12:21
◼
►
I can say, hey, thing, play my lunch playlist.
00:12:23
◼
►
And that was-- that was quite something.
00:12:25
◼
►
That's great.
00:12:26
◼
►
So, like, I'm making great progress there.
00:12:29
◼
►
And at the same time, I have my entire session layer now
00:12:33
◼
►
running on the watch for the first time.
00:12:35
◼
►
Not on the real watch, in the simulator only so far,
00:12:37
◼
►
but I have, like, you know, just--
00:12:39
◼
►
I was able to run it, and I--
00:12:41
◼
►
like, to the point where, like, you run the app,
00:12:43
◼
►
I could finally get it to compile,
00:12:45
◼
►
which is most of the work.
00:12:48
◼
►
And so now I have the data layer running on the watch.
00:12:51
◼
►
Now, it doesn't actually do anything in the UI yet
00:12:54
◼
►
because the UI and the data layer
00:12:56
◼
►
are not talking to each other yet.
00:12:58
◼
►
So here, this is where I bring the question of the episode
00:13:04
◼
►
But first, we are sponsored this week--
00:13:07
◼
►
see the transition there-- by Pingdom from SolarWinds.
00:13:12
◼
►
Now, if you have a website or a web service
00:13:14
◼
►
or anything that runs on the web,
00:13:16
◼
►
and you have something important,
00:13:18
◼
►
like a shopping cart if you're a store site,
00:13:20
◼
►
registration forms if you're a service,
00:13:22
◼
►
contact pages, or if you just have a web API
00:13:25
◼
►
that you need to monitor,
00:13:27
◼
►
if you answered yes to any of that, you need Pingdom.
00:13:30
◼
►
Nobody wants their critical website transactions
00:13:33
◼
►
or their web service backend to fail
00:13:35
◼
►
because that means not only a bad experience for users,
00:13:38
◼
►
but it also could mean lost business for you.
00:13:41
◼
►
So you can set up monitoring with Pingdom.
00:13:44
◼
►
And this can be very simple monitoring
00:13:46
◼
►
from just check if this web page is up
00:13:48
◼
►
and make sure it includes this phrase.
00:13:50
◼
►
So you can design certain things around that
00:13:52
◼
►
or you can tell when a page changes.
00:13:54
◼
►
But you can also do transaction monitoring.
00:13:56
◼
►
This can alert you when things like cart checkouts
00:13:58
◼
►
and forms and login pages fail
00:14:01
◼
►
before they affect your customers and your business.
00:14:04
◼
►
You will know from Pingdom the moment any of them fail
00:14:07
◼
►
in whatever way you want to be notified.
00:14:09
◼
►
They have customizable notifications.
00:14:11
◼
►
You can customize how you're alerted,
00:14:13
◼
►
who is alerted, how bad it is,
00:14:15
◼
►
like how severe the outage has to be.
00:14:17
◼
►
It is great. I've personally been a Pingdom customer
00:14:20
◼
►
for, oh geez, eight to ten years.
00:14:23
◼
►
I used it since the beginning of Overcast for sure.
00:14:26
◼
►
I used it in this paper before that.
00:14:27
◼
►
I even used it on marker.org.
00:14:29
◼
►
And Pingdom is a great monitoring service.
00:14:32
◼
►
I can say that honestly. It's fantastic.
00:14:34
◼
►
So if you want to see, you want to monitor your stuff,
00:14:36
◼
►
go to Pingdom.com/RelayFM right now
00:14:40
◼
►
for a 14-day free trial with no credit card required.
00:14:44
◼
►
When you sign up, use code RADAR at checkout
00:14:47
◼
►
to get a huge 30% off your first invoice.
00:14:50
◼
►
So RADAR at checkout to get 30% off your first invoice
00:14:54
◼
►
Thanks to Pingdom from SolarWinds
00:14:56
◼
►
for their support of this show and RelayFM.
00:14:59
◼
►
So the question of the hour, half hour,
00:15:02
◼
►
is I have now gotten to the point where I have
00:15:06
◼
►
all this restructuring in my main app.
00:15:08
◼
►
I have the huge data layer transition running on my watch app.
00:15:12
◼
►
But my watch app, which admittedly is not that big,
00:15:15
◼
►
it's maybe a few hundred lines of code,
00:15:17
◼
►
is an entirely Objective-C app,
00:15:21
◼
►
although I just rewrote the app,
00:15:23
◼
►
the extension delegate in Swift as part of this move.
00:15:26
◼
►
So it's a mostly Objective-C app.
00:15:28
◼
►
The entire UI layer is Objective-C.
00:15:30
◼
►
And it's all based on this old transfer system
00:15:34
◼
►
with the phone that I'm abandoning.
00:15:36
◼
►
And I have this new data layer below it all.
00:15:39
◼
►
So I have a lot of work ahead of me
00:15:41
◼
►
to either adapt the UI code to the new data layer code
00:15:46
◼
►
or rewrite the entire UI code in Swift
00:15:50
◼
►
and possibly also in Swift UI.
00:15:53
◼
►
So what do you think I should do about the UI code
00:15:56
◼
►
in my watch app?
00:16:00
◼
►
Well, first thing, great job on all the progress thus far.
00:16:04
◼
►
That is no small thing.
00:16:06
◼
►
And especially I know from many experiences
00:16:10
◼
►
that first feeling when it all kind of seems to work
00:16:13
◼
►
and you're almost a little concerned that it seems to work.
00:16:16
◼
►
It's this eerie feeling of like, "Huh, nothing's broken.
00:16:20
◼
►
Everything's running. Seems fine."
00:16:23
◼
►
Yeah, it makes you suspicious of like,
00:16:25
◼
►
"I had to have broken something.
00:16:27
◼
►
If it isn't something obvious, how am I ever going to find it?"
00:16:29
◼
►
It's like, I almost feel it's better
00:16:31
◼
►
when it's just obviously broken,
00:16:32
◼
►
because then it's like, it's clear.
00:16:34
◼
►
There's not this lurking fear of a subtle bug out there
00:16:37
◼
►
just waiting to pounce on you.
00:16:39
◼
►
Yeah, it's like, "There's going to be some feature
00:16:41
◼
►
I never use that I broke somehow.
00:16:43
◼
►
I'm never going to know it,
00:16:44
◼
►
and the beta testers won't find it."
00:16:46
◼
►
And the thing is, the nice thing is
00:16:48
◼
►
you have a large enough beta audience, I think,
00:16:50
◼
►
that it's unlikely that it's going to...
00:16:54
◼
►
No big issue should likely survive
00:16:57
◼
►
the amount of beta testing that I think you're able to
00:16:59
◼
►
sort of leverage on something like this,
00:17:01
◼
►
especially with the breadth of that.
00:17:03
◼
►
So hopefully that'll be fine.
00:17:04
◼
►
You'd be surprised.
00:17:05
◼
►
I mean, I'm sure things get through,
00:17:07
◼
►
but there's always hope.
00:17:09
◼
►
But in terms of the watch, I think
00:17:11
◼
►
the things that come to mind is like,
00:17:14
◼
►
the first question is,
00:17:16
◼
►
"What version of watchOS do you expect to require going forward?"
00:17:20
◼
►
Oh, I forgot to mention that.
00:17:21
◼
►
So I looked at my stats, and I said recently that
00:17:25
◼
►
I wanted to keep compatibility with 12 and 13
00:17:28
◼
►
because it was just pragmatic to do so.
00:17:31
◼
►
And I was looking at my stats,
00:17:32
◼
►
and I decided as part of this big move,
00:17:34
◼
►
it made a lot of things easier
00:17:36
◼
►
not to go to 14,
00:17:37
◼
►
because that's too aggressive for me right now,
00:17:38
◼
►
but I went to 13 and watchOS 6.
00:17:42
◼
►
Because that made a lot of...
00:17:44
◼
►
watchOS 6 was an even easier decision.
00:17:47
◼
►
iOS 13, according to my stats,
00:17:49
◼
►
I'm only losing from the 12 people.
00:17:51
◼
►
I'm losing like 3.5% now.
00:17:54
◼
►
The adoption of 14 has been very high,
00:17:56
◼
►
and now that it's new iPhone season,
00:17:58
◼
►
I expect that to go even higher.
00:18:00
◼
►
So, and this release of the app
00:18:02
◼
►
is probably at least a month or two out.
00:18:04
◼
►
Just because it's so much work,
00:18:06
◼
►
I'm trying to do a lot at once,
00:18:07
◼
►
so it's probably about a month out,
00:18:08
◼
►
if I had to guess.
00:18:09
◼
►
But, so, you know, I went with 13
00:18:12
◼
►
because I was only losing like 3.5% of people
00:18:16
◼
►
by ending 12 compatibility.
00:18:18
◼
►
And watchOS 6, I'm losing like
00:18:21
◼
►
less than 1% of people that were on watchOS 5 still.
00:18:24
◼
►
So the watchOS 6 requirement
00:18:26
◼
►
was actually a no-brainer.
00:18:27
◼
►
And that actually helps a lot with,
00:18:29
◼
►
with what I can do with the audio layer as well there.
00:18:33
◼
►
So that's why I moved to that.
00:18:35
◼
►
- Yeah, 'cause I think if you can require watchOS 6,
00:18:39
◼
►
it feels like a good time
00:18:43
◼
►
to adopt SwiftUI on the watch.
00:18:47
◼
►
- Ooh, I was hoping you'd say that.
00:18:49
◼
►
I'm a little scared.
00:18:50
◼
►
- Sure, 'cause...
00:18:51
◼
►
- 'Cause I have to rewrite a lot of my UI code anyway.
00:18:54
◼
►
But, I gotta, I mean, it's been a while
00:18:57
◼
►
since I used all of the parts of the overcast watchUI.
00:19:01
◼
►
But from what I remember, it's like,
00:19:03
◼
►
we're talking about like three or four screens, maybe?
00:19:06
◼
►
- It's a very small app, like UI-wise,
00:19:09
◼
►
and it's not very good.
00:19:10
◼
►
I'm willing to entertain changes.
00:19:13
◼
►
'Cause I feel like it's,
00:19:15
◼
►
you're gonna have to, if you're gonna
00:19:18
◼
►
like need to essentially build hooks
00:19:20
◼
►
from your new common data layer,
00:19:22
◼
►
into a UI framework.
00:19:24
◼
►
Like that work is gonna have to happen no matter what,
00:19:28
◼
►
because your existing UI and the new data layer
00:19:32
◼
►
aren't compatible with each other anyway.
00:19:34
◼
►
So, it's like if you have to do that effort,
00:19:36
◼
►
like doing it with SwiftUI, I think is gonna be
00:19:39
◼
►
a great place to, like that work is not gonna be
00:19:43
◼
►
for nothing, because that work is going to ultimately
00:19:46
◼
►
allow you to, when you get to working on your widgets,
00:19:49
◼
►
they're gonna have to do exactly the same integration.
00:19:51
◼
►
There may come a point where you need to do SwiftUI work
00:19:54
◼
►
with your main app, and that work is not gonna be
00:19:56
◼
►
wasted there, and so it feels like it's a good thing
00:19:58
◼
►
in terms of, and this is something that,
00:20:00
◼
►
it's relatively straightforward, it's just a bit kind of,
00:20:03
◼
►
you just have to have a different mindset within SwiftUI
00:20:06
◼
►
where you're just taking your data layer
00:20:08
◼
►
and making it so that it's all sort of this
00:20:10
◼
►
combined observable object stuff,
00:20:13
◼
►
is the primary aspect of what you're gonna have to do.
00:20:16
◼
►
Whereas SwiftUI is very, you know,
00:20:19
◼
►
your data layer sort of just tells the UI something's changed
00:20:23
◼
►
and then the UI will come and pull the new data out
00:20:27
◼
►
of the data model and so on, and so you just have to
00:20:30
◼
►
kind of build that in, it's just a slightly different format
00:20:32
◼
►
than what you would typically do where, you know,
00:20:35
◼
►
the data layer is a bit more, like, I don't know,
00:20:39
◼
►
it's imperative rather than declarative programming,
00:20:42
◼
►
but whatever, you're gonna have to do that work
00:20:44
◼
►
no matter what, and I think having now built
00:20:48
◼
►
a tremendous, I've built a lot of watch apps,
00:20:50
◼
►
and what is possible and what is easy
00:20:55
◼
►
in SwiftUI on watchOS makes it so that,
00:21:00
◼
►
like, I don't ever want to touch a watch kit
00:21:03
◼
►
sort of watch app again, because there's so many things
00:21:06
◼
►
that are just, you run into this place where
00:21:09
◼
►
you want to do something, you have an idea,
00:21:11
◼
►
you have a vision for how you want to build it,
00:21:13
◼
►
and with watch kit you will hit this point
00:21:16
◼
►
where suddenly it's just impossible.
00:21:19
◼
►
It isn't like, oh, it's difficult, or, oh,
00:21:21
◼
►
it's, like, challenging to do, it's like, no,
00:21:23
◼
►
it's just, that's not possible, that's not the way
00:21:25
◼
►
watch kit works, and that gets really frustrating,
00:21:28
◼
►
and it could be, like, simple things like,
00:21:30
◼
►
say you wanted to reorder a playlist on your watch,
00:21:35
◼
►
so you have, like, a list of shows, a list of episodes,
00:21:38
◼
►
and you wanted to move them around.
00:21:40
◼
►
In SwiftUI, super straightforward on the watch.
00:21:43
◼
►
In watch kit, impossible.
00:21:46
◼
►
Like, the only way you can do it is, like,
00:21:48
◼
►
you'd have to, like, put arrows, like, up arrow,
00:21:50
◼
►
down arrow on each row or something,
00:21:52
◼
►
and you, like, tap the arrow, and then it, like,
00:21:54
◼
►
would swap with the one above it or something,
00:21:56
◼
►
whereas in SwiftUI you just give, add, like,
00:21:58
◼
►
add a modifier to a list, and then it just, like,
00:22:02
◼
►
you get automatic, like, free drag and drop,
00:22:04
◼
►
and it's, like, things like that are just so much better
00:22:07
◼
►
that I think at this point, spending any amount of time
00:22:10
◼
►
on watch kit, unless it was essentially done,
00:22:14
◼
►
and it was, like, oh, it'll be, like, half a day of work,
00:22:17
◼
►
and then the watch app's updated,
00:22:19
◼
►
and I can start using it, like, great, go ahead and do it,
00:22:22
◼
►
but if it's gonna be any amount of work,
00:22:24
◼
►
then I feel like that's the place to do it,
00:22:26
◼
►
and I think it's also, the watch, and I think this is also
00:22:29
◼
►
from my experience where I built, so I built,
00:22:32
◼
►
with WatchSmith, I built, the iOS app was in UI kit,
00:22:36
◼
►
but the watch app was in SwiftUI,
00:22:38
◼
►
and I learned SwiftUI essentially building that watch app,
00:22:41
◼
►
and then I came to build Widgetsmith,
00:22:43
◼
►
Widgetsmith is entirely written in SwiftUI,
00:22:45
◼
►
so I built the, I essentially re-implemented
00:22:48
◼
►
the Y kit interface that I had built for WatchSmith
00:22:52
◼
►
in SwiftUI for Widgetsmith,
00:22:54
◼
►
and I did that because it just, once I've kind of
00:22:59
◼
►
flipped that switch in my brain, it became so much more fluid
00:23:02
◼
►
and so much more productive for me to sort of just stay
00:23:06
◼
►
in the SwiftUI mindset, and so I think I can say
00:23:09
◼
►
that a watch is a great place to learn SwiftUI
00:23:12
◼
►
because the screens are so much smaller,
00:23:15
◼
►
the interactivity is so much simpler,
00:23:18
◼
►
and it's like a very constrained problem,
00:23:21
◼
►
and it also gives you just more capability,
00:23:24
◼
►
and so in general, that's sort of the direction
00:23:26
◼
►
that I think would be worth doing,
00:23:28
◼
►
and I think it's also, like, in the context
00:23:30
◼
►
of this broader kind of rewrite of what you're doing,
00:23:32
◼
►
like, going, that is clearly, like, there is no work
00:23:36
◼
►
getting done on WatchKit anymore, I'm sure.
00:23:39
◼
►
Like, that is a sort of, if you run into any bugs,
00:23:41
◼
►
if you run into any issues, if weird things start happening,
00:23:44
◼
►
like, that is not a place that you're going to get a lot of,
00:23:46
◼
►
you know, expect that in WatchOS, you know, 7.2.6,
00:23:50
◼
►
they're going to be fixing this weird, esoteric WatchKit bug.
00:23:53
◼
►
Like, that's not going to happen in SwiftUI bugs.
00:23:55
◼
►
Very, there's lots of bugs being fixed there.
00:23:58
◼
►
It seems much more reliable, so, like, my instinct
00:24:01
◼
►
is that's your best bet.
00:24:03
◼
►
It's just sort of, just keep this train rolling,
00:24:06
◼
►
and just keep, you know, just, like, you've torn up
00:24:09
◼
►
and rebuilt a bunch of stuff, it's like, just keep going,
00:24:12
◼
►
and, you know, rebuild and just sort of make your Watch app
00:24:16
◼
►
what it could actually really be, with, like, a real UI
00:24:19
◼
►
that isn't WatchKit, which is not a real UI.
00:24:22
◼
►
- Yeah, agreed.
00:24:24
◼
►
And I'm going to be the first person to be, you know,
00:24:27
◼
►
dancing on the grave of WatchKit when I finally destroy it,
00:24:30
◼
►
but, like, I did hesitate, because I'm like, you know,
00:24:33
◼
►
the main problem with my Watch app, you know,
00:24:35
◼
►
the UI is not great, but the main problem with the Watch app
00:24:38
◼
►
is not the UI, and so pragmatically, I was thinking,
00:24:41
◼
►
I should probably just fix the data layer and the transfer layer
00:24:45
◼
►
as much as possible, and then I can just easily adopt
00:24:48
◼
►
the UI to it, but when I look at, like, you know,
00:24:51
◼
►
what that actually is, and I think you're right,
00:24:53
◼
►
that, like, you know, my use case here is probably going to be
00:24:55
◼
►
a pretty straightforward SwiftUI app.
00:24:58
◼
►
I think it does make more sense, you know, because I have to do
00:25:01
◼
►
a lot of work anyway to adapt the UI in some form.
00:25:06
◼
►
If I'm going to do a lot of work, I might as well do a lot of work
00:25:09
◼
►
that has a bigger payoff than just adopting my old UI,
00:25:12
◼
►
which isn't that great, you know.
00:25:14
◼
►
- And the biggest payoff, I think, is, like,
00:25:17
◼
►
personal development-wise, like, I think it is a,
00:25:20
◼
►
you will be in a much better place, because clearly SwiftUI
00:25:23
◼
►
is the direction that Apple is heading.
00:25:25
◼
►
It is clearly the platform that they're putting the most
00:25:28
◼
►
energy and effort behind internally for the cross-platform,
00:25:32
◼
►
like, all of their, you know, the directions they're heading
00:25:36
◼
►
seem to be SwiftUI-driven, and so it's going to be a much
00:25:41
◼
►
better place to get comfortable in a relatively constrained
00:25:45
◼
►
problem before you kind of, you don't end up in the same
00:25:48
◼
►
situation with Swift, right, where it's like,
00:25:50
◼
►
there was definitely, SwiftUI was not the right time
00:25:53
◼
►
to use it to adopt SwiftUI last year.
00:25:55
◼
►
As someone who did adopt it last year,
00:25:57
◼
►
I can tell you that definitively.
00:25:59
◼
►
It was definitely too early, it did not work well,
00:26:02
◼
►
there was a lot of weird debugging and Xcode issues.
00:26:05
◼
►
I would say now, though, it feels like it's sort of
00:26:08
◼
►
crossing over that point, and, like, if you,
00:26:11
◼
►
if this was, it's like, if you didn't need to do a UI rewrite,
00:26:15
◼
►
I may not necessarily, like, it wouldn't be as required,
00:26:19
◼
►
but I think if you're having to do anything in there,
00:26:21
◼
►
it's past that point where it's painful,
00:26:24
◼
►
now it's just a new tool that, you know, sometimes has some
00:26:27
◼
►
weird edge cases, and there's a few things we,
00:26:29
◼
►
you know, I wish it did differently, but overall it seems to
00:26:31
◼
►
work much more reliably, and the tooling for it is so much
00:26:35
◼
►
better, and even just getting experience using the new SwiftUI,
00:26:39
◼
►
like, interactive development thing, where you can, you know,
00:26:42
◼
►
have a live updating example of your app while you're making it,
00:26:46
◼
►
like, getting used to that development, I found, is very,
00:26:49
◼
►
very potent in terms of, from a speed of sort of prototyping
00:26:53
◼
►
and development perspective, so I think, I'm going to recommend
00:26:58
◼
►
that you give it a try at least, and I think the reality too is
00:27:01
◼
►
give it a try, and it's like, if it, if like, after a day or two,
00:27:04
◼
►
you're like, this is, this is a terrible idea, then that's fine,
00:27:07
◼
►
like, you can go back to it, watch it, it's going to be waiting
00:27:09
◼
►
for you there, but I think it's worth giving it a try at this point,
00:27:12
◼
►
especially in the context of all the other work you're doing.
00:27:15
◼
►
So one more question, and that is, should I, you know, SwiftUI,
00:27:20
◼
►
it's 1.0, it's WatchOS 6. Should I wait until I can require
00:27:25
◼
►
WatchOS 7 before shipping this update? Like, is the SwiftUI
00:27:30
◼
►
difference between 6 and 7 big? Because, like, one thing I really
00:27:35
◼
►
don't want to do is have to test a lot on WatchOS 6, and have to
00:27:38
◼
►
support, like, you know, ancient SwiftUI 1.0-isms, I know ancient
00:27:41
◼
►
from last year, and, because right now I'm already at 75% WatchOS 7.
00:27:46
◼
►
So I think the biggest things that you would have to watch out for,
00:27:51
◼
►
you would have to deal with anyway, because the biggest things that
00:27:55
◼
►
are kind of WatchOS 6 to WatchOS 7 differences are the removal of
00:28:00
◼
►
Force Touch, and the context menu system in WatchOS, and so
00:28:06
◼
►
whatever you do, you're going to have to make sure you're not
00:28:09
◼
►
using that anywhere, because in order for it to work on WatchOS 7,
00:28:12
◼
►
you have to get rid of it. And that's, even if you stay on WatchKit,
00:28:16
◼
►
or 6 or 7, doesn't really matter. And then the other thing is the
00:28:20
◼
►
way that the complication system works is very different in 7,
00:28:25
◼
►
but the old system, I think, still can work, and I don't think your
00:28:29
◼
►
complications are going to be complicated enough that it would
00:28:32
◼
►
actually matter.
00:28:33
◼
►
- No, I literally don't do anything. I just have a launch complication.
00:28:35
◼
►
It's my app icon, that's it.
00:28:37
◼
►
- Yeah, so then I don't think it would actually be that difficult,
00:28:40
◼
►
because the changes in SwiftUI itself, most of them are sort of
00:28:45
◼
►
backwards compatible in a way that they were Swift language changes,
00:28:49
◼
►
rather than being OS changes. And so there's some changes to
00:28:54
◼
►
when you have to call self, and when you have to, like some of the
00:28:57
◼
►
language semantics, but I believe all of those kind of work fine
00:29:01
◼
►
on the old version. They just, because the API didn't change,
00:29:05
◼
►
it's just some of the Swift language stuff changed. So I think you'd be fine
00:29:08
◼
►
with requiring, you don't need to wait for 7, if you can, that's awesome,
00:29:12
◼
►
but if you don't, I think you'd be fine with 6 and 7 working together.
00:29:15
◼
►
- Oh, great. Well, thank you very much, this actually helps a lot.
00:29:19
◼
►
- There you go.
00:29:20
◼
►
- Now you've given me a lot of work for the next two weeks, but...
00:29:22
◼
►
- Hey, you know, that's what I'm here for. Keep you busy.
00:29:25
◼
►
- Yep. Alright, thank you everybody for listening, and we'll talk to you in two weeks.
00:29:31
◼
►
[BLANK_AUDIO]