183: Compatibility Contrast
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.
00:00:06
◼
►
Under the Radar is never longer than 30 minutes, so let's get started.
00:00:09
◼
►
I'm having one of those amazingly productive few day spans.
00:00:14
◼
►
These don't come around often.
00:00:16
◼
►
Wait, we should stop recording.
00:00:18
◼
►
You just go back to working and we'll just pick this up later,
00:00:21
◼
►
whenever you get nonproductive again.
00:00:25
◼
►
Come back to the podcast when I'm lazy as heck.
00:00:28
◼
►
There you go.
00:00:30
◼
►
So I've been doing a quick bit of follow up.
00:00:32
◼
►
The last episode I discussed, or the one before that, whatever it was,
00:00:36
◼
►
discussed basically my decision to re-add iOS 12 support back to Overcast
00:00:42
◼
►
because I was basically getting kind of killed in the app store for not having it
00:00:46
◼
►
and adoption of 13 seemed slower than I expected.
00:00:50
◼
►
And I kind of decided, you know what, let me see what it would take
00:00:54
◼
►
to re-adopt iOS 12 and re-support it.
00:00:57
◼
►
And so I now have the results of that experiment.
00:01:00
◼
►
It's not in the store yet, but re-adopting iOS 12 took me about a half a day.
00:01:07
◼
►
That's not very long.
00:01:09
◼
►
No, and it was -- I kind of feel bad.
00:01:14
◼
►
Like, had I known it would be that easy,
00:01:17
◼
►
I probably wouldn't have dropped support for it in the first place.
00:01:21
◼
►
But it's just like the very first thing I do every summer, or at least that I have done,
00:01:24
◼
►
the very first thing I do is set the SDK to require the newest OS
00:01:28
◼
►
and see all the deprecations and everything, all the stuff I have to change,
00:01:32
◼
►
and then just start doing it, just start changing all the deprecated enums
00:01:36
◼
►
to their new values and start adopting all the new APIs
00:01:39
◼
►
and delete all the code that supported the old APIs and stuff like that.
00:01:42
◼
►
And when I was 13, there was a good deal of that this summer,
00:01:46
◼
►
but most of it that I actually adopted to date was trivial stuff.
00:01:51
◼
►
It was things like enum values that I can just change back.
00:01:55
◼
►
Most of them were like the type of activity spinners and stuff like that.
00:01:59
◼
►
And I had adopted the new background APIs,
00:02:02
◼
►
and I had adopted the theming API, or the system dark mode API,
00:02:07
◼
►
to kind of override my theme choice.
00:02:10
◼
►
But it turned out it took very little effort for me to just put all those enum values back
00:02:18
◼
►
because it didn't matter, the old ones are still supported, they're just deprecated,
00:02:21
◼
►
and when you build with 13 not as the requirement, you don't even get warned about it.
00:02:25
◼
►
So I just put all those enum values back.
00:02:29
◼
►
That took, what, 15 minutes maybe at most, just to make sure I did everything right.
00:02:33
◼
►
And then I re-added support for the old background API,
00:02:37
◼
►
which, by the way, works better than the new background API.
00:02:41
◼
►
The old background refresh, it turns out,
00:02:46
◼
►
so the old background refresh most of the time would work.
00:02:49
◼
►
The new iOS 13 background task system appears to not work at all for some people or sometimes,
00:02:57
◼
►
and I have a frequent bug in the current version where people say search doesn't work.
00:03:02
◼
►
And that's because I was doing search indexing only with background tasks
00:03:05
◼
►
because it would kill my app if I did that CPU-intensive job in the background.
00:03:09
◼
►
So in my dev version that I'm going to release shortly,
00:03:13
◼
►
it's just doing it whenever you enter a search box.
00:03:17
◼
►
Whenever you put the cursor in a search box, it quickly indexes things right then.
00:03:21
◼
►
If anything needs to be indexed, it hasn't been done by the background tasks
00:03:24
◼
►
that don't seem to execute sometimes anyway.
00:03:26
◼
►
So I'm kind of working around the need for anything that 13 actually did.
00:03:31
◼
►
And all those new APIs that I thought I would be using that are 13 and up only,
00:03:38
◼
►
so things like obviously SwiftUI is the big one,
00:03:41
◼
►
there's also a whole bunch of other stuff throughout the frameworks,
00:03:43
◼
►
especially there's Combine and a new Diffable data source
00:03:48
◼
►
and a new collection view layout system that for making standard table viewing,
00:03:54
◼
►
especially collection view stuff, there's a bunch of big advantages,
00:03:57
◼
►
even if you don't want to use SwiftUI.
00:03:59
◼
►
There's a bunch of big advantages to 13.
00:04:00
◼
►
So all this new stuff in the APIs that, yeah, it would be nice to be able to use that,
00:04:05
◼
►
but the fact is I haven't used that yet.
00:04:07
◼
►
And if I delay myself by another year, well, I've gotten this far.
00:04:14
◼
►
I've gotten into late January, and I've still had so much more that I want to do in the app
00:04:21
◼
►
or bugs I have to fix or features I want to add that don't require
00:04:25
◼
►
or even give me time for new API adoption that I figure if I made it this long,
00:04:31
◼
►
I can probably make it at least until June or July,
00:04:34
◼
►
and when I see what iOS 14 adds and then decide from there what my ongoing OS requirements might be.
00:04:40
◼
►
But until then, I have enough to keep me busy without diving into the 13 APIs.
00:04:45
◼
►
So therefore, re-implementing iOS 12, I even thought,
00:04:50
◼
►
now that I've kind of removed the manual toggling of theming,
00:04:55
◼
►
switching between dark and light mode, I now rely on the system for that.
00:04:59
◼
►
I thought, well, that's going to be hard to change in iOS 12.
00:05:02
◼
►
And it turns out I just added one table row above the theme picker that says,
00:05:08
◼
►
"Are you currently in light mode or dark mode?"
00:05:10
◼
►
And it shows only in iOS 12.
00:05:12
◼
►
And so it was really surprisingly easy.
00:05:17
◼
►
The only big work that I had to do was in my current build,
00:05:24
◼
►
I basically rewrote the audio engine and was using an Airplay 2 compatible engine,
00:05:28
◼
►
and that relies on bugs that were fixed in 13.1.
00:05:31
◼
►
That's a great phrase. Just to interrupt you for a moment, that's a great phrase.
00:05:35
◼
►
Relies on bugs.
00:05:37
◼
►
Right. It relies on them having been fixed.
00:05:42
◼
►
And they were fixed in 13.1.
00:05:44
◼
►
And so I was going to require 13.1 for this build,
00:05:46
◼
►
and then when I re-added 12, I thought, well, this entire audio engine has to be not used under iOS 12.
00:05:51
◼
►
But there were other reasons why I wanted to make a second audio engine
00:05:56
◼
►
that was based on just AV audio engine,
00:05:58
◼
►
that the Airplay 2 engine was not working as well as I wanted to when it was not running on Airplay,
00:06:02
◼
►
when it was just running on your phone, speaker, whatever.
00:06:05
◼
►
So I made a whole second audio engine that happens to be compatible with 12.
00:06:09
◼
►
But I was going to do that anyway before I released this.
00:06:12
◼
►
So the actual additional work required to support iOS 12 in this release was about a half a day of work,
00:06:19
◼
►
just mostly enum values and adding one row to a table to change the theme manually.
00:06:25
◼
►
And that's about it.
00:06:28
◼
►
Which I think does make me kind of think,
00:06:31
◼
►
because I'm pretty sure we'd recorded an episode in the summer where we were talking about the benefits
00:06:35
◼
►
and drawbacks of being aggressive with requiring iOS 13 and whether it was a good idea this year.
00:06:42
◼
►
And I think we both ended up that it was like this was a good year to do it, and we should probably be like...
00:06:47
◼
►
We sure did.
00:06:49
◼
►
So maybe you shouldn't be listening to advice from the Under the Radar podcast.
00:06:52
◼
►
Maybe we should add some kind of disclaimer that turns out that we are potentially sometimes horrifically wrong,
00:06:58
◼
►
and that's like half a day of work was all you needed to do to continue supporting 12
00:07:04
◼
►
and all the requisite benefits that come with that.
00:07:08
◼
►
I think the main differences here, which you talked about two episodes ago,
00:07:11
◼
►
whenever that was when I mentioned re-adding this,
00:07:13
◼
►
the main differences that I didn't foresee at least is that I really thought I'd be jumping into the new APIs
00:07:20
◼
►
way more than I have.
00:07:22
◼
►
And I also really thought that iOS 13 adoption would be way faster than it has been.
00:07:28
◼
►
So the combination of both of those factors, I think not going the way that I predicted,
00:07:34
◼
►
is why this had to require a change of mind.
00:07:38
◼
►
I had to change my mind on this.
00:07:40
◼
►
I had to look back and say, "Well, normally I do this, but turns out this time that was the wrong move,
00:07:44
◼
►
and I'm fixing it now, and I don't know how long I'll keep 12 compatibility,
00:07:49
◼
►
but it's still important to me today to do it, so I'm going to do it."
00:07:53
◼
►
And I think the thing that's crazy about that, I've been just keeping an eye on my stats,
00:07:57
◼
►
and my adoption has essentially leveled off now at about 80% adoption.
00:08:03
◼
►
And it has not moved at all in the last month or two,
00:08:08
◼
►
which is making me think that that's probably where it's going to be for a pretty long time,
00:08:13
◼
►
essentially until the incompatible devices age out and get replaced,
00:08:19
◼
►
so the 5S, the 6, and the 6 Plus.
00:08:22
◼
►
But that takes a while on iPhones.
00:08:24
◼
►
Yeah, that's going to take a long time.
00:08:26
◼
►
Or it's like somehow there's a new influx of devices that are running the newer OS.
00:08:33
◼
►
Either the old ones are going to have to go away,
00:08:35
◼
►
or they're going to have to get eclipsed by the new ones.
00:08:38
◼
►
But it's been very stable there,
00:08:41
◼
►
which makes me think even next year we may be in an awkward position
00:08:46
◼
►
where 12 may just be the one that lingers around for a while,
00:08:51
◼
►
and that's just where we're going to be living for a while, that 12 is required.
00:08:57
◼
►
And then if we want to adopt any of the new stuff,
00:08:59
◼
►
we're going to just have to do it in the--
00:09:03
◼
►
having the app behave differently between two different systems,
00:09:07
◼
►
which is complicated potentially and not necessarily great in a lot of ways,
00:09:10
◼
►
or there might be features that are only available on the new OSes.
00:09:14
◼
►
There's lots of ways we think problems,
00:09:16
◼
►
and I'm sure our future selves are going to have to deal with.
00:09:18
◼
►
But it definitely seems like 12 is going to be part of the conversation for a long time
00:09:23
◼
►
in a way that 11 just disappeared when 12 came out.
00:09:29
◼
►
Oh, no. Is iOS 12 our IE6?
00:09:32
◼
►
It might be.
00:09:33
◼
►
I think it might be.
00:09:36
◼
►
Yeah, because 20% of people still not running it is a lot.
00:09:39
◼
►
That's a lot of people, and that's a lot of the market.
00:09:43
◼
►
And as I keep--
00:09:45
◼
►
I'm literally hearing people every day saying,
00:09:47
◼
►
"I searched for over-caching the app store, and it's not there.
00:09:50
◼
►
What happened?"
00:09:51
◼
►
And the answer is always that they're running iOS 12,
00:09:54
◼
►
and it literally just doesn't even--
00:09:56
◼
►
your app doesn't even show up if it requires a higher OS,
00:09:59
◼
►
and that's terrible.
00:10:01
◼
►
So, yeah, so we got to work on that.
00:10:03
◼
►
But anyway, so I've been doing a whole lot of that--
00:10:07
◼
►
well, very little bit of that and a whole lot of other work on this new build.
00:10:12
◼
►
In terms of-- before we move on to where the other work is, though,
00:10:14
◼
►
I'm curious, when you're going through and doing that kind of re-adding it,
00:10:18
◼
►
how do you make sure that you're not re-breaking it in the process?
00:10:23
◼
►
Are you going through the commit that you did to drop support
00:10:28
◼
►
and kind of doing the--
00:10:30
◼
►
having it up in one window and Xcode in the other and kind of just doing the opposites?
00:10:34
◼
►
Because I would be worried that I would forget something,
00:10:37
◼
►
and there's some lingering bug or problem that--
00:10:42
◼
►
I'm reintroducing that I will only hit if I happen to go through a very particular code path,
00:10:48
◼
►
and then it all falls apart.
00:10:50
◼
►
No, I mean, really the advantage here was that I really adopted iOS 13 APIs very little.
00:10:57
◼
►
And so I didn't--
00:10:59
◼
►
the thing that actually dropped support for it, like the commit back then,
00:11:03
◼
►
was part of a larger series of commits,
00:11:05
◼
►
and there's been a lot of changes since then,
00:11:07
◼
►
so I didn't think it would be wise to try to go back to that and try to back it out somehow.
00:11:10
◼
►
So instead, I just set the deployment target back and ran it on iOS 12 device.
00:11:16
◼
►
And if you set the deployment target back and hit Build,
00:11:20
◼
►
you're going to get a ton of errors from all the new enum values and stuff.
00:11:24
◼
►
And then I basically went and for the very few APIs that I knew I adopted that are 13 only,
00:11:31
◼
►
mainly the background task API.
00:11:33
◼
►
I just did if available checks around that and made a separate code path
00:11:38
◼
►
for the old background refresh API to work again.
00:11:40
◼
►
And then I just ran it on an iOS 12 device, and I played around with it for a while.
00:11:44
◼
►
I tested a bunch of different parts of the app,
00:11:46
◼
►
because I still have an iOS 12--
00:11:48
◼
►
I actually ran it on an iPhone 5S, which you can't run 13.
00:11:51
◼
►
So ran it on that, and I couldn't find any problems.
00:11:55
◼
►
And then I released it to beta, and it's been in beta with 12 compatibility.
00:11:59
◼
►
And I do have a lot of test flight people on iOS 12.
00:12:02
◼
►
So it's been in beta testing now for a couple of weeks,
00:12:07
◼
►
and so far there's been no problems introduced--
00:12:10
◼
►
or no problems identified with iOS 12.
00:12:14
◼
►
Because I had just barely adopted those new APIs.
00:12:19
◼
►
And so it really didn't take very long at all to re-add the compatibility,
00:12:24
◼
►
which is a little shameful, like a little unfortunate.
00:12:28
◼
►
But definitely going all these months between iOS 13's release--
00:12:33
◼
►
or I guess the week after, whenever I did my update--
00:12:35
◼
►
between then and now, basically losing 20% of potential new customers or more,
00:12:41
◼
►
that's going to cost me long term, of course.
00:12:45
◼
►
That's the penalty for my error here.
00:12:48
◼
►
And certainly the longer we go without fixing it, the less it needs to be fixed.
00:12:53
◼
►
But I do think that, as you mentioned, I think we're going to hit a floor
00:12:58
◼
►
for how low iOS 12 is going to go reasonably for a while.
00:13:01
◼
►
It'll continue to trickle down slowly, but it's not going to be a rapid change.
00:13:05
◼
►
So I do still think, even though I've lost whatever it's been four or five months
00:13:10
◼
►
of those potential sales, it is still worth releasing this now
00:13:14
◼
►
and regaining the ability to have those sales going forward.
00:13:18
◼
►
- That makes sense.
00:13:19
◼
►
- Yeah, and in reality, it's just like, whatever the mistake was,
00:13:23
◼
►
once you've identified it, you just fix it.
00:13:25
◼
►
You can't worry about what you potentially could have lost or whatever.
00:13:29
◼
►
There's no productivity in that.
00:13:31
◼
►
You identified a mistake and you fixed it, and that's really all we can do.
00:13:36
◼
►
- Yeah, exactly.
00:13:38
◼
►
Because there's not a lot of value in regretting your old mistakes.
00:13:43
◼
►
Just do better going forward.
00:13:45
◼
►
Anyway, we are brought to you this week by Linode.
00:13:48
◼
►
Whether you are working on a personal project
00:13:50
◼
►
or managing your enterprise's entire infrastructure,
00:13:52
◼
►
Linode has the pricing, support, and scale
00:13:55
◼
►
that you need to take your project to the next level.
00:13:57
◼
►
They have now 11 data centers worldwide.
00:13:59
◼
►
They're always adding more.
00:14:00
◼
►
This includes their newest data center in Sydney, Australia.
00:14:03
◼
►
And they have enterprise-grade hardware,
00:14:05
◼
►
a new S3-compatible storage option, and their next generation network.
00:14:10
◼
►
So they deliver the performance you expect and at a surprisingly good price.
00:14:14
◼
►
You can get started today.
00:14:16
◼
►
Plans start at just $5 a month,
00:14:18
◼
►
and you can get started today with a $20 credit using our coupon code.
00:14:22
◼
►
And you can get all sorts of great stuff with this.
00:14:24
◼
►
They have, of course, those $5 a month plans.
00:14:26
◼
►
They give you one gig of RAM currently,
00:14:28
◼
►
and over time, as technology gets better, they always upgrade their plans.
00:14:32
◼
►
So right now, that's a gig of RAM.
00:14:34
◼
►
In the future, that may buy you even more, and they give you free upgrade paths.
00:14:37
◼
►
They also have all sorts of plans above and beyond that,
00:14:39
◼
►
depending on what your needs are,
00:14:41
◼
►
including specialties like dedicated CPU plans with cores reserved just for you,
00:14:45
◼
►
GPU compute plans suitable for AI, ML, and video processing,
00:14:49
◼
►
one-click installs of popular apps including WordPress, the LAMP stack,
00:14:53
◼
►
and even Minecraft servers, and so much more.
00:14:56
◼
►
So go to linode.com/radar,
00:14:59
◼
►
and use promo code RADAR2020 when creating a new Linode account.
00:15:04
◼
►
That'll get you $20 credit towards your next project.
00:15:06
◼
►
And they're hiring right now.
00:15:08
◼
►
So if that interests you, go to linode.com/careers.
00:15:11
◼
►
So once again, linode.com/radar to sign up.
00:15:14
◼
►
Use that promo code RADAR2020 for a $20 credit.
00:15:18
◼
►
Our thanks to Linode for their support of this show and all of Relay FM.
00:15:22
◼
►
So all this time that I've been avoiding the new APIs
00:15:27
◼
►
and doing all sorts of other work,
00:15:29
◼
►
I've been taking advantage of my current rush of productivity
00:15:33
◼
►
to cram in a whole bunch of small fixes.
00:15:37
◼
►
I fixed a weird bug this morning where upload files would fail if they had a comma in them,
00:15:42
◼
►
a bunch of weird little bugs and fixes that I've been doing,
00:15:45
◼
►
trying to cram into this as much as possible
00:15:47
◼
►
because I've had this productivity that I saved by not spending it all,
00:15:50
◼
►
making iOS 12 compatible,
00:15:53
◼
►
cramming in a few new features that are high demand, low effort features,
00:15:57
◼
►
like intro and outro skipping.
00:15:59
◼
►
So I've crammed all this stuff in.
00:16:02
◼
►
Meanwhile, you've been adopting a whole bunch of new APIs.
00:16:05
◼
►
You've kind of been doing the total opposite of this.
00:16:08
◼
►
- The opposite, yes.
00:16:09
◼
►
So I'm curious, in a study of contrast here,
00:16:13
◼
►
how have you, while I've been living in the old days,
00:16:18
◼
►
what have you been doing?
00:16:21
◼
►
- So a bit of context is probably helpful.
00:16:23
◼
►
So I've been really enjoying just working on the Apple Watch,
00:16:28
◼
►
and that has been my primary focus.
00:16:31
◼
►
I got my main, sort of like my bread and butter apps updated and stable,
00:16:35
◼
►
and in general, they all seem to be in a pretty good place right now, feature-wise.
00:16:40
◼
►
And then I decided I wanted my next project to be something a little bit ambitious,
00:16:46
◼
►
a little bit kind of like, see how far I could push the Apple Watch.
00:16:50
◼
►
And so that's what I've been doing, essentially.
00:16:53
◼
►
And it's a bit early to get into the exact details of what that's going to look like,
00:16:56
◼
►
but I mean, functionally, I'm trying to see how far you can push the complication system,
00:17:01
◼
►
the Watch apps, all kinds of fitness and workout modes.
00:17:06
◼
►
I'm trying to see just how crazy I can get there,
00:17:09
◼
►
and especially taking advantage of as much of the new stuff that we can do on the Watch with SwiftUI.
00:17:15
◼
►
So graphically and visually, there's lots of things that we can now do,
00:17:19
◼
►
and it's been an interesting process.
00:17:24
◼
►
Parts of it are just amazing,
00:17:26
◼
►
and it's been really fun to be able to make things like,
00:17:30
◼
►
I played around a little bit with making games on the Apple Watch using SwiftUI,
00:17:34
◼
►
and it surprisingly just kind of works great,
00:17:37
◼
►
and the animations are nice and smooth.
00:17:40
◼
►
And when SwiftUI works, it is just an absolute delight,
00:17:45
◼
►
and the code kind of feels like magic,
00:17:47
◼
►
like the way you combine and the way the data flow works.
00:17:51
◼
►
I both love it and I absolutely hate it,
00:17:55
◼
►
which is probably in many ways reflective of the way that I come from with view layout on UIKit,
00:18:02
◼
►
where I do all my layout with setting explicit frames.
00:18:07
◼
►
I very much like that kind of layout system,
00:18:10
◼
►
and I never liked auto layout.
00:18:12
◼
►
I never liked the magic where you set it up and it just kind of works.
00:18:17
◼
►
And SwiftUI's data flow system feels very similar to that in some ways,
00:18:21
◼
►
where you create these state objects,
00:18:25
◼
►
and any time they change, the changes just flow to where they need to go,
00:18:29
◼
►
and everything will stay in sync.
00:18:31
◼
►
And when it works, it's amazing.
00:18:33
◼
►
But if it doesn't work, or if there's performance issues or problems with it,
00:18:38
◼
►
it can be very frustrating.
00:18:41
◼
►
But I think the biggest thing that has been interesting working with this
00:18:45
◼
►
the last three or four weeks on this
00:18:49
◼
►
is the most difficult part of working on new APIs
00:18:53
◼
►
that are not particularly largely adopted.
00:18:57
◼
►
I don't get the impression that there's huge amounts of...
00:19:00
◼
►
There's lots of SwiftUI academic use, it seems.
00:19:06
◼
►
There's lots of really good resources and documentation things,
00:19:11
◼
►
lots of toy projects and things,
00:19:13
◼
►
but actually in use with lots of complications.
00:19:16
◼
►
You start running into all kinds of weird edge cases.
00:19:19
◼
►
The thing that is most challenging is when you find yourself in this place
00:19:24
◼
►
where it's like, "Do I not understand how this should work,
00:19:27
◼
►
and my code is broken?"
00:19:29
◼
►
Or is this new API, this new capability, just not working?
00:19:35
◼
►
And the difference between those two things is often...
00:19:41
◼
►
There's no way to specifically determine that.
00:19:44
◼
►
"Am I doing it wrong, or is it just not working?"
00:19:47
◼
►
I had a kind of hilarious one recently, I think I may have mentioned this to you,
00:19:50
◼
►
where I was doing a thing where in SwiftUI
00:19:54
◼
►
you can have your navigation hierarchy be based on a state.
00:20:01
◼
►
So you can say which of the detail views should be visible at any given time,
00:20:07
◼
►
and the way you do this is each row gets an identifier,
00:20:10
◼
►
and you say which of the identifiers is active.
00:20:12
◼
►
And I was using that, and it was working great,
00:20:15
◼
►
and then I added a few more rows to my table,
00:20:17
◼
►
and it stopped working for half of the rows,
00:20:20
◼
►
and it would work for some but not all of them.
00:20:22
◼
►
It turned out it would only work for a row that was visible on screen.
00:20:27
◼
►
Which, A, took forever for me to work out, because it worked fine,
00:20:32
◼
►
it worked fine, and then it just didn't.
00:20:34
◼
►
And then it's like, you're kind of playing this matching game of,
00:20:36
◼
►
"Why? If I try and set the value to this row, then it works,
00:20:40
◼
►
and if I switch to the other one, it just doesn't work."
00:20:42
◼
►
And so right now in my code I have this horrific workaround
00:20:45
◼
►
where I have a one-pixel-high row at the top of my thing
00:20:51
◼
►
that includes all the other rows in it,
00:20:53
◼
►
and I actually push to those rows and have them change the detail view
00:20:58
◼
►
rather than the rows that appear on the bottom of the screen.
00:21:00
◼
►
So that sort of works, but stuff like that is just so complicated to know,
00:21:06
◼
►
"Am I doing something wrong? Am I misusing this API?
00:21:09
◼
►
Or is it just a bug and it just doesn't work?"
00:21:12
◼
►
There's plenty of things still in WatchOS 6 that are just kind of buggy.
00:21:17
◼
►
You never know if it's just, "Is it me or is it you?"
00:21:22
◼
►
I don't know. But it's definitely been fun, though, I will say.
00:21:26
◼
►
And I think I'm enjoying working on something that has a bit of ambition behind it,
00:21:31
◼
►
that I feel like a lot of my projects previously have been interesting,
00:21:38
◼
►
and they've been challenging in their own ways.
00:21:42
◼
►
But what I've been enjoying about this project in particular
00:21:44
◼
►
is that I'm taking so many parts of the last ten years of work
00:21:49
◼
►
I've been doing on Apple platforms and kind of combining it all together.
00:21:52
◼
►
And so it's this really interesting kind of Voltron experience
00:21:56
◼
►
that is pulling all these parts together,
00:21:58
◼
►
all these different experiences I have,
00:22:00
◼
►
and then smooshing them all together in kind of an ambitious way.
00:22:03
◼
►
So that part's been fun.
00:22:04
◼
►
SwiftUI and its error messages continue to be just horrifically comical,
00:22:09
◼
►
though apparently I do believe, last I heard, the latest--
00:22:13
◼
►
I'm not on the Swift developer mailing list sort of things,
00:22:16
◼
►
but I remember hearing someone saying that the first version
00:22:20
◼
►
of the new Swift error message system is now out in beta.
00:22:25
◼
►
And so I look forward to hopefully that making my life much better,
00:22:28
◼
►
where the error messages maybe will actually point to the line of code
00:22:32
◼
►
that is actually the problem rather than just pointing to some random line
00:22:36
◼
►
and giving me strange messages.
00:22:38
◼
►
My favorite one recently was I was passing--
00:22:43
◼
►
at some point I'm passing a zero into a frame width or something,
00:22:49
◼
►
and then I make a change ten lines down,
00:22:52
◼
►
and the change had a bug in it. Fair enough. That was my fault.
00:22:57
◼
►
But the error message I get was ten lines up.
00:22:59
◼
►
It said the zero could not be converted to an int.
00:23:02
◼
►
And I didn't know what that means.
00:23:06
◼
►
I still don't really know what that means
00:23:08
◼
►
or what to make of that particular error message,
00:23:11
◼
►
but that's my life now.
00:23:14
◼
►
Yeah, this is--
00:23:16
◼
►
this couldn't be more different than the kind of thing I'm doing.
00:23:20
◼
►
But I see there are times--
00:23:24
◼
►
there are--my development kind of goes in various cycles or seasons,
00:23:29
◼
►
as we've talked about before.
00:23:31
◼
►
And there are times when I'm in an exploration or expansion
00:23:35
◼
►
or new construction phase,
00:23:37
◼
►
where using a whole bunch of new stuff like this
00:23:40
◼
►
is actually what I want to do and what I enjoy doing
00:23:43
◼
►
and oftentimes is the right move.
00:23:45
◼
►
And right now I'm not in one of those phases.
00:23:47
◼
►
Right now I'm in a refinement and small fixes kind of phase
00:23:52
◼
►
as I prepare to launch this big update.
00:23:55
◼
►
But I totally get the appeal of that.
00:23:58
◼
►
And there will be a time when I will join that,
00:24:02
◼
►
that exclusive club of Swift UI users.
00:24:05
◼
►
I don't think that time is soon for me.
00:24:08
◼
►
But next time I get into a new construction phase,
00:24:13
◼
►
that's probably what I'm going to want to do.
00:24:17
◼
►
And it's--I think the thing that's tricky, though,
00:24:19
◼
►
is there's part of me that sometimes is like,
00:24:21
◼
►
is this--I guess maybe the thing that I'm trying to be
00:24:24
◼
►
very thoughtful of is, am I using Swift UI
00:24:26
◼
►
or the related new technologies
00:24:28
◼
►
because they're the best tool for the problem
00:24:30
◼
►
or because they're the new tool?
00:24:32
◼
►
Because I feel like that's the biggest trap
00:24:34
◼
►
that I have to keep honest with myself about,
00:24:37
◼
►
is sometimes I've--like, some of my things
00:24:40
◼
►
I've just rolled back to using WatchKit in
00:24:43
◼
►
because WatchKit was better for whatever reason.
00:24:47
◼
►
And then a lot of times it's just because it's simpler
00:24:49
◼
►
or it's more performant.
00:24:51
◼
►
Like, WatchKit is very straightforward,
00:24:53
◼
►
or at least I know where all the rough edges are.
00:24:56
◼
►
Like, every single one of them I've hit, I'm sure.
00:24:58
◼
►
And so I know how to do that.
00:25:00
◼
►
And so sometimes I have to be like, look, like,
00:25:03
◼
►
Swift UI is cool and could make this, like, slightly shinier.
00:25:07
◼
►
But I need to be thoughtful about the fact that, like,
00:25:10
◼
►
it may not actually be the right tool for the job.
00:25:13
◼
►
And I think that's--I think the biggest advice
00:25:16
◼
►
I would give to anyone kind of--just to anyone
00:25:18
◼
►
when we're adopting these new things is,
00:25:20
◼
►
it's making sure that you're adopting it because
00:25:22
◼
►
it's better and appropriate for the job that needs to be done
00:25:26
◼
►
and is actually going to tangibly improve the application
00:25:29
◼
►
as a result versus just because it--
00:25:32
◼
►
adopting it because it's cool.
00:25:33
◼
►
Because more likely--because, like, inevitably
00:25:35
◼
►
it's going to come with drawbacks and problems
00:25:37
◼
►
and bugs and issues.
00:25:39
◼
►
And so those--all those negatives have to be
00:25:41
◼
►
sort of outweighed by the positives.
00:25:43
◼
►
Like, the new stuff that in UITableView,
00:25:46
◼
►
like, the DiffableDataSource stuff,
00:25:47
◼
►
it's really cool and can do some, you know,
00:25:49
◼
►
some cool, like--have some--gives you some--
00:25:53
◼
►
it gives you some great stuff for free,
00:25:55
◼
►
but it also, like, comes with some costs and some complexities,
00:25:58
◼
►
and you have to restructure, you know,
00:26:00
◼
►
how you're getting your data source
00:26:01
◼
►
and may have some complicated questions with memory
00:26:04
◼
►
and, you know, how many of your objects
00:26:07
◼
►
you actually have to have in memory at any one time.
00:26:09
◼
►
And so, like, I've looked into that,
00:26:11
◼
►
and I've adopted it, I think, in one place in my app,
00:26:14
◼
►
but several other spots, I'm just like,
00:26:16
◼
►
"I'm just going to do this the old-fashioned way,"
00:26:18
◼
►
and not worry so much about, you know,
00:26:21
◼
►
the fact that I'm missing out on the new hotness
00:26:23
◼
►
and instead just like, "No, this is, like--
00:26:26
◼
►
this just needs the boring solution
00:26:27
◼
►
rather than the new solution."
00:26:29
◼
►
- Yeah, I think kind of a theme to my arc
00:26:32
◼
►
through iOS 12 and into iOS 13,
00:26:34
◼
►
now back to iOS 12 compatibility,
00:26:36
◼
►
is kind of that I overestimated the gains I would get
00:26:41
◼
►
by doing that, and I underestimated the costs
00:26:44
◼
►
of just doing new stuff or only supporting new stuff.
00:26:48
◼
►
And in every OS release every year
00:26:51
◼
►
and for different markets, those are different.
00:26:54
◼
►
Like, I was applying my old wisdom
00:26:57
◼
►
that had always worked for me to date,
00:27:00
◼
►
which was just support the new thing,
00:27:02
◼
►
adopt everything immediately, that's better for most indies.
00:27:04
◼
►
But that wasn't better for me this time.
00:27:06
◼
►
And so it's important to, you know,
00:27:09
◼
►
keep an open mind about that, that, you know,
00:27:11
◼
►
what you've done in the past in either direction,
00:27:12
◼
►
either supporting old stuff forever
00:27:14
◼
►
or jumping on new stuff immediately
00:27:16
◼
►
or anything in between, whatever you've done in the past
00:27:19
◼
►
might not hold this time around or next time around
00:27:22
◼
►
because conditions are different.
00:27:24
◼
►
You know, OS releases are different,
00:27:25
◼
►
hardware support is different, like, you know,
00:27:27
◼
►
it changes every time.
00:27:29
◼
►
And the value of supporting only the new stuff also changes
00:27:34
◼
►
because in different years that'll be--
00:27:37
◼
►
it'll be harder or easier, you know,
00:27:39
◼
►
to maintain backwards compatibility.
00:27:41
◼
►
The new APIs will be more or less compelling
00:27:44
◼
►
and they'll be more or less specialized.
00:27:46
◼
►
Like, you know, the iOS 13 API for dark mode
00:27:50
◼
►
is pretty specialized, so there's one feature in iOS 13
00:27:53
◼
►
and if you adopt that API, it doesn't really make it
00:27:55
◼
►
any harder to support the old way of doing things.
00:27:58
◼
►
If you adopt SwiftUI, then it makes it almost impossible
00:28:01
◼
►
to keep compatibility because you basically have
00:28:03
◼
►
to write your entire UI twice or somehow implement
00:28:05
◼
►
SwiftUI yourself for iOS 12, which is a terrible idea.
00:28:09
◼
►
You shouldn't do that.
00:28:11
◼
►
And so, you know, every time you are faced with this choice,
00:28:15
◼
►
you should reevaluate based on the current conditions.
00:28:19
◼
►
Ask around, do some research, see if you can find
00:28:21
◼
►
good numbers on adoption, things like that.
00:28:23
◼
►
And really think, like, is it the right move
00:28:26
◼
►
to adopt the new shiny thing in this case
00:28:28
◼
►
at the expense of compatibility?
00:28:31
◼
►
And if you're building something brand new from scratch,
00:28:33
◼
►
it probably is.
00:28:35
◼
►
If you're pushing your app update forward, it might not be.
00:28:39
◼
►
- Yeah, and I think what's interesting too,
00:28:41
◼
►
what's awkward is that the only way to really know the cost
00:28:45
◼
►
is to actually try it to some degree.
00:28:47
◼
►
That is much as you kind of want to estimate it,
00:28:49
◼
►
but I think there is certainly a value in doing
00:28:53
◼
►
the kind of like quick explorations to get a sense of things.
00:28:57
◼
►
I think you can give yourself a lot more information
00:28:59
◼
►
and make better choices as a result.
00:29:01
◼
►
I think about how it ended up the try iOS 12 compatibility
00:29:04
◼
►
was half a day or so, and if like, towards the end
00:29:08
◼
►
of the summer, had just been like, huh, I wonder
00:29:10
◼
►
what it would take to add 12 support.
00:29:13
◼
►
And it'd be like, I'll give myself half a day to work on it
00:29:16
◼
►
and see how far I can get.
00:29:18
◼
►
And if you've just gotten to the end and you had it all
00:29:20
◼
►
in there, it's like, okay, maybe I'll just ship this then.
00:29:22
◼
►
- Yeah, exactly.
00:29:23
◼
►
- So it's good to, I think, be thoughtful and explore
00:29:26
◼
►
in that way, but understand that sometimes you are
00:29:28
◼
►
just gonna have to try it and then just be thoughtful
00:29:31
◼
►
about not getting stuck in a hole just because you've started
00:29:34
◼
►
doesn't mean you have to finish.
00:29:36
◼
►
Thanks for listening everybody, and we'll talk to you
00:29:38
◼
►
in two weeks.
00:29:40
◼
►
[BLANK_AUDIO]