262: Managing Change
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 usually not longer than 30 minutes, so let's get started.
00:00:09
◼
►
So this week we wanted to talk about managing some changes that we're doing that feel risky
00:00:17
◼
►
because they involve changing long established behaviors or UI characteristics or code even in our apps.
00:00:28
◼
►
apps and it can be tricky. When you're first starting out making something new, you have
00:00:33
◼
►
no users, you have no traffic, you have no data, and so you can kind of change whatever
00:00:39
◼
►
you want all the time. I remember back in the Overcast 1.0 beta, there was so much change
00:00:46
◼
►
during that beta period and huge changes to the way the app worked, to how it looked,
00:00:51
◼
►
to even what the features were, how the features worked, like massive changes during that period
00:00:56
◼
►
because there was no legacy, there was no data, the user base was like 50 people, it
00:01:02
◼
►
was a very relatively small thing.
00:01:06
◼
►
And so I was able to iterate quickly.
00:01:09
◼
►
As time has gone on, I mean that was eight years ago, I have been less and less able
00:01:14
◼
►
to make those big changes.
00:01:16
◼
►
And there's been lots of reasons for that.
00:01:18
◼
►
Part of it has been just my workload and my life, I've had less time to do really big
00:01:25
◼
►
coding blocks. A bigger part is just that the app has gotten really well established.
00:01:30
◼
►
You know, I'm very fortunate that the app has a lot of users, I manage a lot of volume
00:01:35
◼
►
of usage and of user data, and I have, you know, if anything I change, I hit a bunch
00:01:42
◼
►
of one-star reviews and a bunch of five-star reviews. And a bunch of people saying, "Why
00:01:47
◼
►
don't you just make it a setting?" So anyway.
00:01:50
◼
►
Why don't you just?
00:01:52
◼
►
That phrase, nothing that's ever followed,
00:01:54
◼
►
why don't you just, has ever actually been constructive,
00:01:58
◼
►
- Any comment that begins with why don't you just
00:02:00
◼
►
instantly says you don't understand the problem.
00:02:02
◼
►
- Yes, it is.
00:02:03
◼
►
Everything is more complicated than you imagine it to be.
00:02:05
◼
►
- Exactly, exactly.
00:02:07
◼
►
But anyways, so I've recently undertaken
00:02:09
◼
►
a few of these changes over the last couple of weeks,
00:02:12
◼
►
kind of unplanned, but that's kinda how I work,
00:02:14
◼
►
and you're tackling some big ones as well.
00:02:17
◼
►
So first, I wanna hear,
00:02:19
◼
►
What is the large change management
00:02:22
◼
►
that you're doing recently?
00:02:23
◼
►
- Yeah, so in this version five update of Podometer++
00:02:27
◼
►
that I've been working on for the last few months,
00:02:29
◼
►
which I think, hopefully, fingers crossed,
00:02:31
◼
►
I will be submitting early next week,
00:02:33
◼
►
which I am thrilled by.
00:02:35
◼
►
- It's essentially rebuilding the entire app
00:02:40
◼
►
from almost the ground up,
00:02:42
◼
►
from maybe the second floor up.
00:02:44
◼
►
I'm leaving some old Objective-C
00:02:48
◼
►
layer stuff, but everything else is a complete rebuild to essentially modernize the app,
00:02:54
◼
►
to add a bunch of new features, to do a lot of big, essentially put myself in a position
00:02:58
◼
►
to actually move the app forward rather than feeling like I'm trapped in the past, which
00:03:03
◼
►
is how I've been feeling for a long time.
00:03:06
◼
►
But it's like so much of this is this weird, this terrifying feeling of, so I have something
00:03:13
◼
►
in the App Store right now that works.
00:03:15
◼
►
It's like battle tested.
00:03:16
◼
►
It's proven.
00:03:17
◼
►
there for, you know, almost a decade now, in some form, and it is very stable. And I'm
00:03:23
◼
►
going to essentially rip it out and replace it, which I think is the right call in this
00:03:28
◼
►
situation. Like, I think I can't maintain an Objective C UI kit app going forward into
00:03:33
◼
►
the future. Like it is just at a certain point, I'm going to have to migrate it. And I may
00:03:37
◼
►
as well do that now that, you know, the APIs are mature, but most people are running the
00:03:42
◼
►
latest operating systems, all the good things that are like reasons it's a good idea. But
00:03:45
◼
►
it's like I'm fundamentally changing the thing that is so vital to my business. And
00:03:51
◼
►
so that change is just terrifying. I mean, I've gone through this a few times where
00:03:56
◼
►
I've made changes like this, and I think in the back of my mind I always have that
00:04:00
◼
►
feeling of "You don't want to kill the golden goose," like the nursery rhyme about
00:04:06
◼
►
that, where it's that sense of there's this thing that's working, and if I make
00:04:10
◼
►
a change, this thing could just go away. And that's really problematic that in theory, you hope that
00:04:17
◼
►
it's just like, "Oh, you get 25-star reviews, 21-star reviews, it all balances out, and it kind
00:04:24
◼
►
of moves forward as though nothing has changed." Or in the best case, maybe you get a different
00:04:31
◼
►
ratio of those, that it's like 25-star reviews and five one-star reviews. Most people like it,
00:04:36
◼
►
it, the few people don't like it, whatever. But no matter what, there's always that risk of it's like
00:04:41
◼
►
50 one-star reviews and no positive reviews. All the work has sort of gone poorly and terribly and
00:04:48
◼
►
everything falls apart and your professional life is over. That's the risk that's always in the
00:04:56
◼
►
back of my head when I'm going through these kind of big fundamental changes. And it never gets
00:05:01
◼
►
easier. Like, I've done this many times now. I've gone through many things, and it's much
00:05:06
◼
►
easier, I will say, back in the day when my apps had hundreds of users. It was much easier
00:05:11
◼
►
to manage than in a situation now where I think we're both in a position where our apps
00:05:15
◼
►
have large enough audiences that you make a change. Even if 1% of those people don't
00:05:20
◼
►
like it, that's a lot of people. That's a number of people who could both make your life
00:05:24
◼
►
difficult in terms of reviews in the App Store or all kinds of other places, or just in general,
00:05:30
◼
►
Like, it's an absolute number.
00:05:31
◼
►
It's a lot of people that might get really annoyed and disappointed.
00:05:35
◼
►
And I don't want to disappoint anybody.
00:05:37
◼
►
I like someone who likes my app now.
00:05:38
◼
►
I want them to keep liking my app.
00:05:40
◼
►
I don't want that to change.
00:05:42
◼
►
So it's a dangerous thing to do, and so I always feel really nervous and tricky about
00:05:46
◼
►
actually going and doing it.
00:05:48
◼
►
Yeah, that's exactly what I've been facing, even the numbers you threw out, like the 1
00:05:54
◼
►
So, one of the big risks that I took recently is, about a week ago, I ended support—and
00:06:04
◼
►
I said I was going to do it on Mastodon, like I said, ahead of time, but not everybody follows
00:06:08
◼
►
me on Mastodon, obviously.
00:06:09
◼
►
So I ended support for some really old versions of my sync API that runs on my servers.
00:06:16
◼
►
And this was in part—this was mostly because I'm in the middle of this giant migration
00:06:21
◼
►
that's another huge change that I'm managing
00:06:24
◼
►
and that I'm very stressed about.
00:06:26
◼
►
So basically, as I've talked about many times before,
00:06:28
◼
►
I'll be brief, because this is a brief show.
00:06:30
◼
►
I've been doing server migrations and server tweaks
00:06:33
◼
►
to basically scale the business better,
00:06:36
◼
►
to lighten the server load, to make sync faster
00:06:38
◼
►
and more reliable, and to lower my server costs,
00:06:41
◼
►
'cause my costs just keep going up and up
00:06:43
◼
►
and they're getting really crazy.
00:06:45
◼
►
So anyway, it's been very, very stressful,
00:06:48
◼
►
but I'm actually making pretty good progress
00:06:49
◼
►
of kind of moving everything into this new, a newly architected handful of classes and
00:06:57
◼
►
functions in the back end, where I'm consolidating all of the access to these two massive high
00:07:02
◼
►
traffic tables, the subscriptions and the episode progress tables basically, consolidating
00:07:08
◼
►
the access to those two tables all now through this one unified class that has the ability
00:07:14
◼
►
to read and write that in two different ways. One of them is the new way that I'm trying
00:07:18
◼
►
to migrate to where it's going to be way smaller, way easier to host, and give you more flexibility
00:07:23
◼
►
in how it's hosted in the future.
00:07:25
◼
►
Like, I could, you know, the new class has the ability to do things like instead of hosting
00:07:29
◼
►
it on local MySQL servers, I could host it like on a managed database service, you know,
00:07:34
◼
►
where then I don't have to deal with a lot of this stuff and scaling becomes easier,
00:07:38
◼
►
performance becomes better, cost might be better in certain ways, I don't have to deal
00:07:41
◼
►
with backups and replication and sync and everything else.
00:07:44
◼
►
So moving at all towards this new system.
00:07:46
◼
►
So this has involved rewriting and refactoring
00:07:49
◼
►
tons of the server code.
00:07:51
◼
►
Because it turns out, when you run a podcast app,
00:07:54
◼
►
Sync Servers, a lot of code involves reading and writing
00:07:57
◼
►
to the tables that deal with what podcasts you are subscribed
00:07:59
◼
►
to, what your settings are, and what your progress and status
00:08:03
◼
►
of every episode is.
00:08:06
◼
►
So anyway, massive changes here.
00:08:09
◼
►
And in the process of doing all of that, which, again, that
00:08:12
◼
►
alone has been terrifying.
00:08:15
◼
►
But also very, so far it's been very fulfilling
00:08:19
◼
►
in that by doing this I've been able to make some things
00:08:21
◼
►
more efficient already, even before I've started
00:08:23
◼
►
using the new table structure.
00:08:25
◼
►
I've been making a lot of things more efficient
00:08:27
◼
►
with the old table structure and everything.
00:08:29
◼
►
But as part of doing this, the way I've managed
00:08:33
◼
►
my API versioning over time is I basically just copy
00:08:38
◼
►
the controller, the API controller.
00:08:40
◼
►
I have like API one, API two, API three.
00:08:43
◼
►
Whenever I do a major API version change where the method by which the app syncs to the servers
00:08:48
◼
►
has to change in a big way, I just copy, I make a new API controller, and I make the
00:08:53
◼
►
whole protocol in that, and then I just have the old one around, just running untouched.
00:08:59
◼
►
Now as I'm making all these changes to the low-level data storage and how it's accessed
00:09:05
◼
►
and everything else, these are pretty large changes to the code, and so I had to make
00:09:11
◼
►
a difficult choice.
00:09:12
◼
►
either just keep the most modern API files up to date and refactor those to use the new
00:09:20
◼
►
code, or go back and refactor all of the old ones also. And I chose not to do that for
00:09:27
◼
►
a few reasons. The biggest of which is that the old ones are all... the ones I was hoping
00:09:35
◼
►
to not have to update were the ones that serve versions of iOS that the app hasn't worked
00:09:41
◼
►
on in about a year or more.
00:09:44
◼
►
And so this is basically everything before iOS 15.
00:09:47
◼
►
And when I looked at my usage, it actually is,
00:09:50
◼
►
it's not nothing, it's about 1%.
00:09:54
◼
►
It's kind of funny actually.
00:09:55
◼
►
I have about 0.7% on iOS 14,
00:09:59
◼
►
about 0.3% on iOS 12,
00:10:03
◼
►
and almost nobody on iOS 13.
00:10:06
◼
►
I have almost as many people on iOS 17 as I do on iOS 13.
00:10:11
◼
►
iOS 17 is in doubt yet.
00:10:14
◼
►
So, iOS 13, yes, it was a disaster.
00:10:18
◼
►
Apparently everyone else thought so as well.
00:10:20
◼
►
So it seems like the people who are holding onto iOS 14,
00:10:25
◼
►
'cause 15 and 14 run on the same devices,
00:10:27
◼
►
I think from what I've gathered is mostly jailbreaks,
00:10:30
◼
►
'cause jailbreaks I think are still on iOS 14 only.
00:10:33
◼
►
I don't really follow that world,
00:10:34
◼
►
but that's what I've been told.
00:10:35
◼
►
And also people who are just like,
00:10:39
◼
►
who are just kind of scared to update
00:10:40
◼
►
because they have maybe an older device
00:10:42
◼
►
and they don't want their device to slow down.
00:10:43
◼
►
And they've had bad experiences in the past with that.
00:10:45
◼
►
And so like, well, you know, I have,
00:10:47
◼
►
like, you know, somebody wrote me the day with an iPhone 11.
00:10:49
◼
►
And that, they considered too old to run iOS 15.
00:10:52
◼
►
They were holding it to 14.
00:10:54
◼
►
You know, that's what happens.
00:10:56
◼
►
Your user base, people develop these habits
00:10:58
◼
►
with bad experiences in the past
00:10:59
◼
►
and they refuse to update anyway.
00:11:01
◼
►
And iOS 12 makes some sense because the devices
00:11:04
◼
►
that are on 12 can't go past that.
00:11:05
◼
►
like they are not compatible with 13, 14, and 15.
00:11:08
◼
►
But all in total, this total is about 1% of my user base.
00:11:11
◼
►
And I made the decision to actually cut that off,
00:11:16
◼
►
because it was so much work on the server side.
00:11:20
◼
►
Basically, my workload during this migration
00:11:22
◼
►
would have approximately tripled.
00:11:25
◼
►
And furthermore, I no longer maintain old devices
00:11:29
◼
►
that can test those old API versions.
00:11:31
◼
►
Because after a while of my app not working on an OS,
00:11:35
◼
►
I decommissioned those test devices.
00:11:37
◼
►
So I don't even think I have a device that's
00:11:39
◼
►
running iOS 14 anymore.
00:11:41
◼
►
I have an old one that can run iOS 12.
00:11:43
◼
►
I can maybe test that, but the API that runs iOS 14,
00:11:46
◼
►
I can't even test that myself.
00:11:48
◼
►
And so I'm not going to rewrite this huge part of my API
00:11:51
◼
►
file for a very small percentage of the user base
00:11:54
◼
►
that I can't even test against.
00:11:55
◼
►
And then I have to maintain indefinitely into the future.
00:11:57
◼
►
So I decided-- it was a tough decision.
00:11:59
◼
►
The last time I did this, it was probably three or four years
00:12:02
◼
►
ago at least.
00:12:03
◼
►
But I did cut off support.
00:12:04
◼
►
And I've heard from those people.
00:12:06
◼
►
Because 1% of a big number is a big number.
00:12:09
◼
►
And so I have heard from them.
00:12:11
◼
►
And I knew I would.
00:12:13
◼
►
And I felt bad.
00:12:14
◼
►
And I've tried to explain to them as nicely as I could,
00:12:16
◼
►
here's the situation.
00:12:18
◼
►
And for the most part, most people were like, well, OK.
00:12:21
◼
►
Thanks anyway.
00:12:22
◼
►
A few people were really mad, but what can you do?
00:12:25
◼
►
And ultimately, this is what I had
00:12:27
◼
►
to do to make the app better.
00:12:30
◼
►
When I look at what I'm moving towards,
00:12:32
◼
►
the world I'm moving towards by doing all these things.
00:12:35
◼
►
Not only am I going to save server costs, which is something that I care about, but
00:12:38
◼
►
my users don't.
00:12:40
◼
►
But also, I'm making things less likely to break in the future, much more resilient.
00:12:46
◼
►
But the big thing that my users will actually care about is that there have been a number
00:12:50
◼
►
of really good features that I haven't been able to do because of the way my old sync
00:12:54
◼
►
system worked.
00:12:55
◼
►
And there have been a few really big annoying sync bugs that I haven't been able to fix
00:13:00
◼
►
because of the way the old system worked.
00:13:02
◼
►
And so, soon, once I'm on this new system,
00:13:06
◼
►
I will be able to do some really nice features
00:13:09
◼
►
that have been the number one requested features
00:13:11
◼
►
for a long time.
00:13:12
◼
►
I can finally start to do those,
00:13:14
◼
►
because the sync system will support them.
00:13:16
◼
►
And that's something that the old system could never do.
00:13:18
◼
►
So, this is, I feel like, the decision you have to make
00:13:22
◼
►
when you're managing these big changes
00:13:24
◼
►
and taking these big risks is like,
00:13:26
◼
►
yes, you are gonna upset some people.
00:13:28
◼
►
That's inevitable when you change anything
00:13:30
◼
►
that people are using. But you have to look at the bigger picture. Like, well, overall,
00:13:34
◼
►
am I going to please more people than I upset? Is this going to allow me to get new customers
00:13:40
◼
►
and retain my existing customers better? And unfortunately, those things often require
00:13:47
◼
►
losing some other people. And I wish it didn't have to, but that's the reality. You can't
00:13:52
◼
►
please everyone all the time.
00:13:54
◼
►
Yeah. And I think there's an element of being, as long as you're being thoughtful about it,
00:13:59
◼
►
don't just make change for change's sake and be pulling the rug out from other people
00:14:02
◼
►
just because. It's slightly easier. But if there's a good reason, I think that is
00:14:09
◼
►
an important thing that is very difficult to feel good about. But I think increasingly
00:14:14
◼
►
I'm in that mindset of understanding that those small single-digit percentage numbers
00:14:21
◼
►
of users, trying to cater to them is just going to ultimately make the product worse
00:14:29
◼
►
and is going to make the experience of the 98% of other people have a worse experience,
00:14:35
◼
►
rather than, you know, and that is way more important. That is such a disproportionately
00:14:41
◼
►
valuable thing. And there's no strategy that you can take that is going to eliminate issues
00:14:45
◼
►
with that kind of very long tail situation.
00:14:50
◼
►
I ran into this recently, this one,
00:14:54
◼
►
the stat just blew my mind where I was doing
00:14:55
◼
►
the dark sky APIs going away,
00:14:58
◼
►
and so I was doing some work with migrating away from it.
00:15:00
◼
►
And my dark sky API calls were higher
00:15:04
◼
►
after working through the migration stuff
00:15:07
◼
►
than I expected them to be.
00:15:10
◼
►
And I eventually worked this out,
00:15:11
◼
►
that there was a bug in the very first version
00:15:11
◼
►
version of Widgetsmith, the very first one on day one that was making way more Dark Sky
00:15:17
◼
►
calls than it actually should and was happening for everybody, whether or not you had a membership.
00:15:22
◼
►
So there's still 1% of my user base running that very first version of the app. And it's
00:15:27
◼
►
like they've never updated the app in two and a half years. And okay, weather for them
00:15:33
◼
►
is just going to stop working at some point because Dark Sky is going to go away. And
00:15:36
◼
►
It was just one of those thoughts of like, "Yeah, those people, I can't help them.
00:15:42
◼
►
There's nothing that I can do to that person who is in a situation where two and a half
00:15:46
◼
►
years later, they downloaded one version of the app and they have never updated it since.
00:15:51
◼
►
That's a choice they're making or a situation they're in, whatever the reason for that.
00:15:57
◼
►
That is not where I should put my effort.
00:15:58
◼
►
I should put my effort into the 98% of people who are running a version that I released
00:16:03
◼
►
in the last six months.
00:16:05
◼
►
That is a group, a cohort that I can work for,
00:16:09
◼
►
make their life better, make my life better,
00:16:13
◼
►
and put effort into in a way that is actually useful.
00:16:17
◼
►
- We are brought to you this episode by Indeed.
00:16:19
◼
►
When it comes to hiring, you need to trust your gut,
00:16:21
◼
►
but what if you could give your gut some help?
00:16:24
◼
►
When you want to find the top talent fast, you need Indeed.
00:16:27
◼
►
Indeed is the hiring platform.
00:16:29
◼
►
You can attract, interview, and hire all in one place.
00:16:33
◼
►
Don't spend hours on multiple job sites
00:16:35
◼
►
looking for candidates with the right skills
00:16:36
◼
►
when you can do it all with Indeed.
00:16:38
◼
►
Find top talent fast with Indeed's suite
00:16:40
◼
►
of powerful hiring tools like Indeed Instant Match,
00:16:43
◼
►
Assessments, and Virtual Interviews.
00:16:45
◼
►
And if you hate waiting, Indeed's US data
00:16:47
◼
►
shows over 80% of Indeed employers find quality candidates
00:16:51
◼
►
whose resume on Indeed matches their job description
00:16:53
◼
►
the moment they sponsor a job.
00:16:55
◼
►
Instant Match really is incredible.
00:16:57
◼
►
As soon as you sponsor a post,
00:17:00
◼
►
you'll get that short list of quality candidates.
00:17:02
◼
►
You can invite them to apply right away.
00:17:04
◼
►
Join more than 3 million businesses worldwide using Indeed to hire great talent fast.
00:17:10
◼
►
Indeed knows that when you're doing everything for your company, you can't afford to overspend
00:17:15
◼
►
Visit Indeed.com/undertheradar to start hiring now.
00:17:20
◼
►
That's Indeed spelled I-N-D-E-E-D dot com slash undertheradar.
00:17:26
◼
►
Indeed.com/undertheradar.
00:17:29
◼
►
Terms and conditions apply.
00:17:30
◼
►
Cost per application pricing not available for everyone.
00:17:33
◼
►
to hire, you need Indeed.
00:17:35
◼
►
Our thanks to Indeed for the support of this show
00:17:37
◼
►
and all of Relay FM.
00:17:39
◼
►
Yeah, so I was, you know, speaking of other changes
00:17:43
◼
►
that you can't please everybody,
00:17:45
◼
►
I also made a couple other changes recently in my UI.
00:17:48
◼
►
I issued a couple of app updates,
00:17:50
◼
►
trying to solve some long-standing problems
00:17:52
◼
►
and trying to give people a few little new features
00:17:54
◼
►
while I work on some bigger behind-the-scenes stuff.
00:17:56
◼
►
You know, you mentioned you're doing
00:17:57
◼
►
this big pedometer rewrite.
00:17:59
◼
►
You know, you kinda started from the second floor up.
00:18:02
◼
►
I'm trying to do the same thing with Overcast.
00:18:04
◼
►
And this is another reason why I am doing all the sync engine
00:18:07
◼
►
work, is that I'm modernizing the back end
00:18:12
◼
►
and adding all this support for new features,
00:18:14
◼
►
while at the same time rewriting the entire data layer
00:18:17
◼
►
in Overcast very slowly as part of my grand rewrite plans
00:18:21
◼
►
that hopefully getting everything to Swift UI
00:18:23
◼
►
and Swift and async stuff and Blackbird and everything else.
00:18:28
◼
►
And so I'm also rewriting the sync protocol
00:18:32
◼
►
that this new sync layer will sync to the servers with,
00:18:36
◼
►
trying to optimize, making things as lightweight as possible
00:18:39
◼
►
on the client.
00:18:39
◼
►
Because there are certain things right now,
00:18:41
◼
►
like if you're an Overcast user and you
00:18:43
◼
►
have a lot of podcast subscriptions,
00:18:46
◼
►
sync is a very heavy operation for you.
00:18:48
◼
►
Because every time it syncs, it collects
00:18:52
◼
►
all episodes of all podcasts you're subscribed to,
00:18:54
◼
►
and kind of sends all their e-tags to the server to say,
00:18:57
◼
►
hey, have any of these changed?
00:18:58
◼
►
And that's on every single sync request.
00:19:00
◼
►
And so as your collection grows, that's a very heavy operation.
00:19:04
◼
►
So that's one of the things I'm migrating away from,
00:19:07
◼
►
trying to make things scale better for both
00:19:09
◼
►
the client and the servers.
00:19:11
◼
►
But anyway, in the meantime, while I'm
00:19:13
◼
►
doing all that, which is going to show basically
00:19:15
◼
►
nothing to my customers for months and months and months,
00:19:18
◼
►
I'm trying to do small features in the app that
00:19:20
◼
►
will kind of give people just signs that I'm still alive
00:19:24
◼
►
and still working on this app while I do the bigger
00:19:26
◼
►
stuff behind the scenes.
00:19:27
◼
►
And so I added some highly requested menu options
00:19:31
◼
►
for playlist management and stuff.
00:19:33
◼
►
I also wanted to try to tackle some longstanding issues
00:19:38
◼
►
that people had with both the new interface
00:19:39
◼
►
and with the interface in general.
00:19:41
◼
►
And by the new interface, I mean the one I launched
00:19:43
◼
►
like two years ago.
00:19:44
◼
►
It's been a while.
00:19:45
◼
►
- Something like that, yeah.
00:19:46
◼
►
- Yeah, but anyway.
00:19:47
◼
►
So one of the issues with the new interface is that
00:19:52
◼
►
I changed for the first time in the app's history,
00:19:55
◼
►
I changed what was shown on the home screen,
00:19:58
◼
►
like what podcasts are shown there.
00:20:00
◼
►
And it used to be just a stack of like,
00:20:02
◼
►
quote, unplayed podcasts and then everything else.
00:20:06
◼
►
And I found as a user of the app,
00:20:08
◼
►
it was hard to find stuff.
00:20:10
◼
►
'Cause I would skim past one of the sections maybe
00:20:12
◼
►
and not realize that the podcast was in the other section,
00:20:15
◼
►
you know, whatever.
00:20:16
◼
►
And that was a common thing,
00:20:16
◼
►
people complained about it all the time.
00:20:17
◼
►
So in the quote, new interface,
00:20:20
◼
►
I changed it to be like these tabs.
00:20:22
◼
►
This was like, it was like unplayed, active,
00:20:25
◼
►
and archive.
00:20:26
◼
►
And these tabs, ever since I launched it,
00:20:30
◼
►
I've gotten a bunch of feedback on them,
00:20:32
◼
►
some of which likes them, most of which was like,
00:20:34
◼
►
can I just please get a list that just has
00:20:36
◼
►
all of the podcasts in it?
00:20:39
◼
►
And I eventually wanted that myself, too,
00:20:41
◼
►
because I was hitting the same problem with the new layout.
00:20:43
◼
►
I was like, well, if I don't know
00:20:45
◼
►
whether a podcast is unplayed or active or inactive,
00:20:49
◼
►
I don't know which one of these tabs to look for it in.
00:20:51
◼
►
And so I was often either using search
00:20:53
◼
►
to get around this limitation, or I would check all three lists and that feels terrible.
00:20:58
◼
►
And so I'm like, you know what, people want an all tab.
00:21:02
◼
►
So I just added an all tab and I got rid of the archive tab because it confused a lot
00:21:06
◼
►
of people and everything that was in the archive tab would now be in the all tab amongst everything
00:21:12
◼
►
So I thought, this is what people actually have been really asking for for the most part,
00:21:17
◼
►
let me try this.
00:21:19
◼
►
And I tested it with the beta group for a little while and everyone was fine with it
00:21:22
◼
►
for the most part, so I was like,
00:21:23
◼
►
"All right, that sounds good."
00:21:24
◼
►
And then, I also, you know, the concept of unplayed
00:21:28
◼
►
in Overcast has never made sense,
00:21:31
◼
►
because what unplayed has always meant in Overcast
00:21:35
◼
►
is not yet deleted, which is different from unplayed.
00:21:39
◼
►
You could have an episode that is played,
00:21:42
◼
►
you couldn't in 1.0, but fairly soon afterwards
00:21:46
◼
►
in the apps life cycle, I added the ability
00:21:48
◼
►
to have an episode that was played,
00:21:50
◼
►
but that you didn't delete yet.
00:21:51
◼
►
And so there were all these labels in the app said unplayed,
00:21:56
◼
►
but then you could literally have a played episode
00:21:58
◼
►
right below that header.
00:22:00
◼
►
And so it made no sense.
00:22:02
◼
►
And that's another thing I've heard about forever.
00:22:04
◼
►
And so I decided, you know what,
00:22:05
◼
►
let me address this issue finally too.
00:22:08
◼
►
Now I will actually change the logic
00:22:10
◼
►
so that played episodes won't show up
00:22:12
◼
►
in the unplayed sections.
00:22:14
◼
►
And I shipped that out as 2023.1.
00:22:17
◼
►
Everyone hated it.
00:22:21
◼
►
Well, if you're one of the people who didn't, I'm sorry.
00:22:23
◼
►
But in this case, you're like a 1%er,
00:22:25
◼
►
like the previous discussion.
00:22:26
◼
►
So it's like everyone else hated it.
00:22:29
◼
►
I heard from so many people, I can't find my episodes now,
00:22:32
◼
►
where did they go, you broke the way things work.
00:22:33
◼
►
And I realized the reality is,
00:22:37
◼
►
oh, and also everyone said they missed the archive section.
00:22:39
◼
►
That was fun too.
00:22:40
◼
►
But everyone loved the new all section,
00:22:41
◼
►
but they still missed archive, and I broke that.
00:22:43
◼
►
So I broke these two big things for people
00:22:45
◼
►
because they were used to it the other way.
00:22:46
◼
►
And I realized, okay, I was correct that something needed to change.
00:22:52
◼
►
I was hearing from people, something needs to change in these two areas.
00:22:55
◼
►
Unplayed doesn't make sense, and I can't find where podcasts are, and I want an alt-tab.
00:23:00
◼
►
So I fairly quickly issued a 2023.2 update that addressed those problems in two different
00:23:08
◼
►
So I realized the unplayed thing, people actually had gotten used to the way it worked, and
00:23:13
◼
►
I was used to the way it worked, and I couldn't find stuff after it was played either.
00:23:15
◼
►
And so I realized that it wasn't that the behavior was wrong,
00:23:20
◼
►
the terminology was just wrong.
00:23:22
◼
►
So I just changed the word unplayed to current,
00:23:25
◼
►
which there is no good single word that I can find
00:23:28
◼
►
that describes the status of episodes.
00:23:30
◼
►
Current is not the best,
00:23:31
◼
►
but I couldn't think of a better one.
00:23:33
◼
►
If I can in the future, I'll change it again.
00:23:35
◼
►
And so I just changed everything back,
00:23:37
◼
►
all right, it works the way,
00:23:38
◼
►
the behavior will go back to the way it was before.
00:23:41
◼
►
I was just changing the label
00:23:43
◼
►
so that the label now matches the behavior
00:23:45
◼
►
rather than changing the behavior to match the label.
00:23:48
◼
►
And that was the right move.
00:23:50
◼
►
Now everyone's fine, no one's mad,
00:23:51
◼
►
well now like two people are mad
00:23:53
◼
►
'cause they like the change I made,
00:23:54
◼
►
but everyone else was fine, okay.
00:23:57
◼
►
And then with the all versus archive
00:23:59
◼
►
versus unplayed slash current slash active,
00:24:02
◼
►
I realized what I want,
00:24:04
◼
►
and I think I should trust what I want
00:24:05
◼
►
because I made this app for myself for the most part,
00:24:08
◼
►
and so people who have come to this app
00:24:10
◼
►
usually are people who want things
00:24:12
◼
►
the way I want them for the most part
00:24:14
◼
►
because otherwise they wouldn't have stuck with my app.
00:24:17
◼
►
And what I wanted, I wanted the all list.
00:24:21
◼
►
I also wanted an archive list.
00:24:23
◼
►
And the old active list I never used.
00:24:25
◼
►
So I just changed that section
00:24:27
◼
►
to now just be current, all, and archived.
00:24:31
◼
►
That seems to be satisfying more people on the whole.
00:24:36
◼
►
And it's not perfect, and honestly,
00:24:38
◼
►
once I, when I do the big Swift UI rewrite,
00:24:41
◼
►
my plan is to actually make that customizable
00:24:43
◼
►
so that you can have whatever sections you want there.
00:24:45
◼
►
And I'll give you three or four or five different possibilities,
00:24:48
◼
►
and you can slot them in wherever you want.
00:24:50
◼
►
Because that's much, much easier to do in Swift UI
00:24:53
◼
►
than it is in my current massive UI table view or UI collection
00:24:57
◼
►
view hack thing.
00:25:01
◼
►
That's very difficult for me to do now,
00:25:03
◼
►
but that will be very easy for me to do in the future.
00:25:05
◼
►
And so my plan is this will all become customizable,
00:25:08
◼
►
among other things in the app.
00:25:10
◼
►
But in the meantime, I've settled on something
00:25:12
◼
►
that I think works better for more people in the old system.
00:25:15
◼
►
And these were all huge risks,
00:25:17
◼
►
that changing long-standing things in the app.
00:25:19
◼
►
But I'm happy that I got here,
00:25:22
◼
►
and I did have to anger some people and lose some people
00:25:25
◼
►
and get some one-star reviews along the way,
00:25:28
◼
►
as you do with any change,
00:25:29
◼
►
but overall, I think this is better for more people.
00:25:32
◼
►
- Yeah, and I think there's definitely some couple lessons
00:25:35
◼
►
in that story you just told,
00:25:38
◼
►
where it's that sense of, I think,
00:25:40
◼
►
It's important to realize that changes you're making are not typically irreversible. That
00:25:49
◼
►
if you make a change, like that fear that I was talking about at the beginning of the
00:25:52
◼
►
episode of this overwhelming sense of dread that I'm going to just destroy everything
00:25:56
◼
►
and it's all going to just go down in flames, it's possible, pretty unlikely. Most changes,
00:26:02
◼
►
if it turns out you got it the wrong way around, like which side was the 1%, if you got that
00:26:09
◼
►
It's like, you can undo it. It's fine. You can go in and undo what you change, just
00:26:14
◼
►
roll back, whatever that's going to look like for you. Usually that's possible. So
00:26:19
◼
►
don't be so precious with these changes and think that, "Oh no, if I do this, I can
00:26:25
◼
►
never go back." I mean, I ran into a funny one with pedometer recently where when you
00:26:29
◼
►
reach your goal in pedometer, there's confetti that comes down from the top of the screen.
00:26:33
◼
►
So it's been in there for a long time. People love it.
00:26:35
◼
►
I love it. It's delightful.
00:26:37
◼
►
loves it. I started getting beta feedback from people who were saying that the new confetti,
00:26:41
◼
►
which I wrote written in SwiftUI, wasn't as fun as the old confetti. And at first, the
00:26:49
◼
►
first person who said that, it's like, "Oh, whatever." And then it's like, I started getting
00:26:51
◼
►
many people who were in the beta who were saying this to me, and I was like, "Oh, no.
00:26:55
◼
►
I'm not going to mess with people's confetti. I'm going to undo this change." And so now
00:26:58
◼
►
it is just the old CA, like CA emitter view, UI kit confetti, just in a UI view representable
00:27:07
◼
►
inside of SwiftUI. It's like, "I am not messing with that." I don't want people
00:27:10
◼
►
to be like, "Oh, the new confetti's sad." It's like, "No, I do not want to be on
00:27:15
◼
►
the wrong side of that change." So I just undid it. It's fine.
00:27:18
◼
►
And I think there's a wisdom in that, of being flexible. Pushing your app forward,
00:27:23
◼
►
making sure that you find ways to make it better, and if it turns out you pushed slightly
00:27:28
◼
►
too far, it's like, "Ease back. Back it up, change it." Ideally, you find this
00:27:32
◼
►
out when you're doing some kind of beta test rather than, you know, when the 99% of people
00:27:38
◼
►
who are grumpy is 99% of a few hundred people, it's much easier to manage than if it's 99%
00:27:44
◼
►
of the entire user base. But still, when that happens, just ease up, back up, change it,
00:27:49
◼
►
and you'll be fine.
00:27:51
◼
►
Yeah. Yeah. For me, to undo my unread logic change, it was literally just going into my
00:28:00
◼
►
version control and just finding that one commit that had those changes and just undoing
00:28:05
◼
►
it and then changing all the labels to say current instead of un-rattling it was super
00:28:09
◼
►
You know, it's harder when you're doing a massive re-write or a huge re-design, that's
00:28:14
◼
►
way harder to roll back and in most cases you're better off not rolling it back and
00:28:19
◼
►
just kind of making tweaks to be more successful rather than undoing months of work.
00:28:25
◼
►
But the fast stuff you can undo pretty quickly and it's not that big of a deal and it's
00:28:29
◼
►
worth experimenting with.
00:28:30
◼
►
Yeah, and I think just or moreover is just being open to that is I think the most like what that looks like technically like is
00:28:36
◼
►
Gonna widely vary and like rolling back isn't necessarily the right thing always sometimes
00:28:40
◼
►
It's gonna be finding a new middle ground listening to what you know sometimes when people are upset about a change
00:28:46
◼
►
It isn't that it changed. It's that you're exposing
00:28:48
◼
►
Some assumption they were making about the app or some workflow that you were completely oblivious to
00:28:54
◼
►
That is now being surfaced because of a change you made and it's like listen is like step number one
00:29:00
◼
►
and all these things.
00:29:01
◼
►
It's like, listen, try and understand what it is,
00:29:03
◼
►
and then make the change.
00:29:04
◼
►
And continue to move the app better.
00:29:06
◼
►
Don't get anchored in the past,
00:29:07
◼
►
and instead just keep making it better,
00:29:09
◼
►
both for yourself and for your users.
00:29:11
◼
►
- Yeah, and don't just make everything a setting.
00:29:13
◼
►
- Yeah, that's right.
00:29:14
◼
►
- Thanks for listening, everybody,
00:29:15
◼
►
and we will talk to you in two weeks.