0:00:00Welcome back to Under the Radar, a show about independent iOS development.
0:00:04I'm Marco Arment.
0:00:05And I'm David Smith.
0:00:06Under the Radar is never longer than 30 minutes, so let's get started.
0:00:10So today I think we wanted to talk about probably one of the most common
0:00:15but yet challenging parts of being a developer, at least in my experience,
0:00:19and that deals with unexpected complexity.
0:00:23When you start off working on something and you have kind of an expectation
0:00:27of how complicated it's going to be to do, what it's going to look like, the effort involved,
0:00:30the time involved. And then you sit down, you open up Xcode, you start programming, and it turns out
0:00:36that it's a complete nightmare and it's going to be way more effort and way more work.
0:00:41And that experience happens so often that I think having a good process and mindset about dealing
0:00:48with it is one of the very important things of being able to ship software in a reasonable time
0:00:54and reasonable quality.
0:00:56And I think we both recently had an experience
0:00:57that kind of fell into that category,
0:01:00and so this episode I think will be more
0:01:03of a case study style in terms of talking
0:01:06through our experiences.
0:01:07And so I believe that is the experience that you had
0:01:11when you were working on the streaming engine
0:01:12for Overcast, am I right?
0:01:14- Oh yeah.
0:01:15I mean streaming as a feature,
0:01:17so Overcast is a podcast player,
0:01:19and the built-in Apple APIs for playing media using AVPlayer,
0:01:24most of that stuff supports streaming out of the box.
0:01:29You don't really have to do much to enable it.
0:01:32I mean, depending on how much you want your interface
0:01:35to behave, you don't necessarily have to do anything.
0:01:37So it's relatively easy to support streaming media
0:01:41just as well as you do locally played media
0:01:43if you're using AVPlayer.
0:01:45But one of Overcast's biggest selling features,
0:01:47and one of the things that makes it most compelling,
0:01:50both to me and to many of the users,
0:01:52is my custom audio engine with a feature called Smart Speed,
0:01:56where Smart Speed dynamically adjusts the playback.
0:02:00And the way it works is there's a processing function that
0:02:06needs to read in the audio samples
0:02:09in the middle of the processing stream
0:02:11and then output possibly a different number of them
0:02:15if it's speeding up the sound.
0:02:16So it might take in 500 samples,
0:02:20and then the middle of it might be silence
0:02:22as it detects silence, so it might compress that
0:02:25down to 300 samples.
0:02:26So you need the ability to inject into the processing stage
0:02:31a function that can read faster than it can output.
0:02:34And that is not possible with AVPlayer.
0:02:37There's no mechanism to do that that I have found at all.
0:02:41If anyone knows, I'm really curious,
0:02:42but I have looked many times,
0:02:44every time there's a new SDK I look,
0:02:46I've asked Apple engineers at WWDC and in labs and via email, and it really does seem
0:02:51like it is just not possible with AVPlayer.
0:02:54So the way I do this is I actually just wrote the, I basically wrote my own AVPlayer.
0:02:58It's not a small task, and I'm writing at the core audio and audio units levels, and
0:03:06custom decoding of everything.
0:03:08And when you go lower level to enable this, the easiest way to do it is something called
0:03:13called the ext, geez, ext audio file API.
0:03:17And that is, that only works for locally stored files,
0:03:22it does not work for streams.
0:03:26There's a separate API, the audio file stream API
0:03:28that is lower level than that.
0:03:30And that you can supply stream data to.
0:03:33You still have to manage the fetching of the stream yourself
0:03:36and you have to manage a lot yourself.
0:03:39So the job of streaming was to convert
0:03:42from that ext audio file API that only does local files
0:03:46to the lower level audio file stream API.
0:03:49And also then build out all the UI behind it,
0:03:52build out the network fetcher,
0:03:54the actual streamer that can stream things,
0:03:56and of course make it all performant
0:03:58and responsible of data usage and memory
0:04:01and responsible of the CPU
0:04:04and also handle a whole bunch of weird edge cases.
0:04:08And I knew it was gonna be a big job going in,
0:04:11but I didn't quite realize how big,
0:04:14how many of those edge cases they would be,
0:04:16how tricky some of them would be to solve.
0:04:18And the biggest thing,
0:04:19like when we're talking about unexpected complexity,
0:04:22the biggest thing for me is unexpected time that it takes.
0:04:26You know, this is why our business is historically so bad
0:04:29at estimating time and ship dates.
0:04:32And when you're independent,
0:04:33I don't think we're any better at it.
0:04:34You know, I think in many ways, it might be worse.
0:04:38Do you find that you are good at estimating time?
0:04:41I think the honest answer is that I've stopped estimating time, or even trying to.
0:04:48I have found that it doesn't actually help.
0:04:52I have this vague sense of like, sometimes I have, the only deadline I usually have is
0:04:56a new device is being shipped, or a new OS is being shipped.
0:05:00There's something specific that like, if I want to be there on day one of the iOS 9 launch,
0:05:05then I need to have my app ready by the beginning of September.
0:05:10Other than that, I try hard to not think too much about timelines because every time I've
0:05:16tried to do that, it never works.
0:05:19The most universal experience of software engineering is you think it's going to take
0:05:24two weeks, it ends up taking four weeks.
0:05:27And that's just the reality of like, you're all like, as you, I mean, I think it sounds
0:05:32a little bit like you have the same experience.
0:05:33Like you start off thinking, okay, maybe I can do this with these high level APIs.
0:05:38like, you know, these things Apple has put together, they're tried and true, whatever.
0:05:43And you start using it and it's like, okay, it does most of what I need, but it doesn't
0:05:47do this one critical thing. And you start being like, how critical is that? Well, it's
0:05:52probably pretty critical. And so you take your next step down, and then you take your
0:05:56next step down, and then before long, you're just like re-implementing all kinds of crazy
0:06:00stuff. And you have no way of knowing superficially what that's going to look, how many love
0:06:06stacks deep, how much rewriting and rebuilding of stuff you're going to need to end up doing
0:06:11to get what you're going to do.
0:06:12And so at the end I was just like, I don't know, I'll just sort of hope for the best.
0:06:15And like other than for iOS 9 things, for those I just tend to say like how much, like
0:06:20I'll just work until I can't, I run out of time and just try and structure what I'm working
0:06:26on such that I can like, you know, not be half finished, have like half the things fully
0:06:32finished rather than all the things half finished.
0:06:35But yeah, estimating time is a complete nightmare, I find.
0:06:38- Yeah, totally.
0:06:40And we're lucky that when we're working for ourselves
0:06:44on our own products for the most part,
0:06:46our time estimates aren't that important
0:06:47'cause for the most part,
0:06:49only the users are demanding things, if anybody.
0:06:52It's not like, when you're a consultant,
0:06:55the pressure is much stronger on you
0:06:56to meet the client's deadlines.
0:06:58Or when you're working for a company,
0:07:00when you're working directly on your employer's product,
0:07:05You have similar pressures from that.
0:07:07But when you're a consultant, you have a whole different aspect of it, which is that
0:07:11the client is often directly paying you for the time that you are taking.
0:07:15And that, of course, makes it even more complex.
0:07:17We are both lucky that we are not currently in that kind of role.
0:07:20But certainly, I would say from just anecdotal evidence, it seems like the vast majority
0:07:26of iOS developers are involved in some kind of contract work.
0:07:31That seems to be the biggest chunk of the iOS work that's out there.
0:07:36Time estimates are such a nightmare there.
0:07:39We're both lucky that we can't really talk much about it, because I haven't done it in
0:07:43forever, and even when I didn't, I didn't do very much of it.
0:07:46It's been a while since you've done consulting as well, right?
0:07:48Yeah.
0:07:49I mean, the last time I did regular consulting was probably four or five years ago, something
0:07:54like that.
0:07:55I started out as a consultant.
0:07:56That was what I was doing initially, but it's been a long time since that made up any kind
0:08:01kind of significant portion of my business.
0:08:03And I learned very quickly when I was doing consulting,
0:08:06though, to not commit to time estimates as much as I could,
0:08:11because you're always gonna run into that.
0:08:13There's always some kind of complexity
0:08:15that you're not expecting.
0:08:16And if you don't plan for it,
0:08:18if you don't look at a problem and say,
0:08:20it's like the old rule of whatever you think
0:08:22it's gonna take, multiply it by three.
0:08:24- Yeah, at least.
0:08:25- You're probably well off, but yeah, I try as best,
0:08:30Like the first rule, you definitely have that experience when you start off consulting where
0:08:33you start to say like, "Oh, it's going to take such, you know, oh, that'll only be like
0:08:36a week's worth of work."
0:08:38And you commit to the client to do that and then it never ends up being a week's worth
0:08:41of work.
0:08:42It's just, that's just the reality.
0:08:43I mean, even, and I mean, with streaming, I had so many problems with, I would, I started
0:08:49it, I think three or four times.
0:08:52And I would get down a certain path or try to try to approach it in a certain way and
0:08:57and realize that it was just never gonna work.
0:09:00I was never gonna be able to complete it
0:09:01in the way I was doing it, or it just was not working,
0:09:05or I had made too many mistakes,
0:09:07or I had made too many subtle bugs
0:09:09that I couldn't find at the very low levels.
0:09:11And so I would just scrap it and start over again.
0:09:13And when you're at a big time crunch,
0:09:17you don't usually have the opportunity to do that.
0:09:19And that can be a blessing and a curse.
0:09:21If you do that too much,
0:09:23then you're wasting a whole bunch of time,
0:09:25and it's never gonna be perfect.
0:09:27It's never going to be exactly the perfect design, exactly what you want.
0:09:30And so if you have too many opportunities to cancel it and start over again, you're
0:09:33just going to kill tons of time.
0:09:35But if you don't have any opportunities to do that, which is often the case when you're
0:09:38under time pressure from a client, say, I feel like it's hard to get good quality work
0:09:43because you really do learn a lot if you try to do something, then get a chance to throw
0:09:48it away and do it over again.
0:09:49Yeah.
0:09:50Because I think one thing that I was, my experience, like whenever I've encountered these kind
0:09:54of problems, where I'm trying to deal with something that ends up being much more complicated
0:09:59than I think. I start off with a mental model for the problem that is straightforward. For
0:10:04example, the thing that I most recently ran into this with is I did a data syncing and
0:10:08merging algorithm for Pedometer++. So it takes the steps from your watch and your phone and
0:10:15gives you a unified view of them in semi-real time. At first I was like, "Oh, the mental
0:10:20model for this is great. There's HealthKit, right? I can just use HealthKit. And you can't,
0:10:24because that's not how HealthKit works, because it's not available on the watch in the way
0:10:28that shows you phone data. So I very quickly discovered that my original mental model was
0:10:33completely wrong. And so then, what my process tends to be, I have this really straightforward
0:10:38mental model, it ends up not working, and then I end up going down these crazy paths
0:10:43of incredibly complicated solutions. All of these really brittle and not really going
0:10:50to work solutions, like all kinds of crazy algorithms and merging schemes and way of
0:10:53throwing data back and forth. And you get to the end, and the times I'm most satisfied
0:10:59with my work, though, are when I end up, after all of that, with a simple solution again
0:11:04that is informed by all of those crazy paths down the way. Like, you can learn the lesson
0:11:10and be like, "Okay, actually, I don't need to do all these crazy things. Now that I understand
0:11:15the problem fully from top to bottom.
0:11:17I can say, "Okay, I don't need to worry about the data in all these crazy ways.
0:11:22I can just make all these nice simplifying assumptions about how it is because I've
0:11:28tested and verified that those work.
0:11:30And then I can build a solution that's almost as simple as the one I started off with wanting
0:11:35to build and now that actually deals with all that complexity."
0:11:38And whenever I'm able to go through that process, it starts simple, it gets horrifically
0:11:42messy and then it gets simple again.
0:11:44I know I'm doing it right.
0:11:47If ever I end up having to stop in that middle state where it's still really messy, I know
0:11:52it's going to break.
0:11:53I know it's not going to work.
0:11:55It needs to be something that I could just describe to myself in just a few sentences
0:12:00or something's probably gone wrong.
0:12:04What kind of system did you end up with to address the watchOS2 or watchkit2 sync problem?
0:12:11Because as you are very well aware,
0:12:14and as some of our audience might be,
0:12:18with WatchKit 1 apps,
0:12:20we're actually fairly straightforward and simple to make
0:12:22because they couldn't do that much,
0:12:24and because they were running on the phone
0:12:27in the app sandbox, in the same sandbox as the iPhone app,
0:12:30so that you could have a shared container,
0:12:32and the iPhone app and the Watch app
0:12:35could literally be reading and writing from the same data.
0:12:38And that's how I structured the Overcast Watch app,
0:12:40which is I just move the database file, the SQLite file,
0:12:44into the app container, and then the communication
0:12:49between the watch app and the phone app
0:12:51is limited only to basically commands and status updates.
0:12:55And all the data, the watch app reads the data
0:12:58right off the database, and the phone just tells the watch
0:13:02when it has changed, and the watch reads it.
0:13:04So it's actually very, quite simple in that way,
0:13:08'cause there is no sync issue.
0:13:10If the watch can't reach the phone at the given moment,
0:13:13you just can't use the Overcast app,
0:13:15'cause it's just, all it is is a remote control
0:13:17for the phone, so it's great.
0:13:19With watchOS 2, that shared data container
0:13:23no longer quite exists the same way, or at all, really.
0:13:26- It doesn't exist at all, yeah.
0:13:27- Right, so with watchOS 2, it is like,
0:13:30you are running two separate apps,
0:13:32and you need to figure out how they're going
0:13:34to communicate with each other,
0:13:35and there's methods to do the basics,
0:13:38but there is no automatic magical syncing that happens.
0:13:41So you have to deal with how these things
0:13:43synchronize their data yourself.
0:13:46That's one of the reasons why I haven't made
0:13:48an overcast watchOS 2 app.
0:13:51Why I just keep having the OS 1 app.
0:13:54First of all because it works well enough.
0:13:57WatchOS 2 improved watch kit reliability quite a bit
0:14:00and so the app works well enough for the most part.
0:14:03But also that it would be a major undertaking
0:14:06as you discovered, you know, it's a major undertaking
0:14:09to all of a sudden tackle these two,
0:14:11to all of a sudden take something
0:14:12that used to be a dumb remote and make it a full app
0:14:16with its own local storage
0:14:17and the problem of syncing both ways.
0:14:20And so, you know, if you take the phone away
0:14:23and you have the watch off by itself somewhere
0:14:24playing podcasts somehow,
0:14:26which is its own separate bag of hurt
0:14:28of like, you know, how capable that is right now
0:14:30in watchOS 2.0, but if you somehow do that,
0:14:34then you have to, when upon reconnection to the phone,
0:14:38you have to sync up that data again
0:14:39and resolve possible conflicts.
0:14:41And it's a very, it's a much larger problem
0:14:45than it seems upon first glance.
0:14:47Because while the APIs and everything are all very similar
0:14:50to what they were in Watch Scale 1,
0:14:53the data model is totally different.
0:14:55And that's where most of the complexity I think would lie.
0:14:58And I haven't yet decided that that's worth the investment.
0:15:01Apps for the Apple Watch are a whole separate topic,
0:15:04but I have found generally that I'm very scared
0:15:08to tackle that.
0:15:09This is one of the few times where I've spotted
0:15:10that complexity ahead of time,
0:15:13and possibly wisely, I don't know,
0:15:16but possibly wisely I'm avoiding it.
0:15:18- Yeah, 'cause I think what I've ended up having to do
0:15:21in WatchOS 2 is essentially you have to build
0:15:25two completely independent, can-run-on-their-own apps.
0:15:31Like the watch app has to be able to run entirely on its own without being able to phone home
0:15:35to the phone.
0:15:36And the phone app obviously needs to be able to run without the watch, which isn't that
0:15:40much of a stretch because that's what it does if you don't own a watch.
0:15:44And then you have to do these funny things because the communication between the two
0:15:49is not reliable, both in terms of sometimes the watch is just physically not close enough
0:15:56to the phone in order to communicate.
0:15:59And also, sometimes, just the APIs and things, I think it's because they're trying to do
0:16:04so much about power management and sometimes certain types of messages only go through
0:16:10if it's a good thing from an energy perspective to be able to do.
0:16:14Like the radios are all turned up and fired up, so hey, let's go ahead and send it right
0:16:17away.
0:16:18If they're not, maybe we'll wait and see if we are going to fire up the radio anyway for
0:16:22the next, in the next second.
0:16:24If not, then maybe we'll do it.
0:16:25And so you have to build the system that
0:16:30makes no assumptions about being able to talk to the other part,
0:16:34but still gives your user a consistent experience
0:16:37across both.
0:16:38And that's where, like for this project that I was working on,
0:16:41became the really crazy thing.
0:16:42Because a pedometer, in some ways, is very simple.
0:16:45Like both devices have a motion processor on it
0:16:49that tells you how many steps they took
0:16:51in a particular time period.
0:16:52Like that's all they do, and that's
0:16:54most of what the app is doing.
0:16:56And so I could run completely independently in terms of,
0:16:59if I could just showed you the watch's steps on the watch app
0:17:03and just showed you the phone steps on the phone app,
0:17:05it'd be trivial.
0:17:06But what I want to be able to do is obviously
0:17:08merge those together and say, which
0:17:09one is a better representation of what you're doing?
0:17:13And that is where all the crazy complexity comes in.
0:17:16Because I had a couple of things that I was like,
0:17:19so many of conflict resolution strategies
0:17:21don't really work in this scenario.
0:17:23because I can't just do simple things like who updated most recently or things because
0:17:28if I can ever, for example, make someone's step count go down, I guess I could, but conceptually
0:17:34I've always had that be like a rule for the app that if I ever, even if it was like slightly
0:17:38in error, if I ever showed you a step count, like for example, you hit your goal, right?
0:17:42Like you got 10,000 steps, confetti comes down from the screen, hooray, you did it.
0:17:46I don't want you to then like sync up with your watch and say like, oh, actually now
0:17:49we think that you did 9,000 steps.
0:17:51Like, that would be terrible, right?
0:17:53You have to withdraw somebody's confetti.
0:17:55Yeah, like, I'm sorry, your confetti now goes back up to the top of the screen and...
0:17:58Animated in reverse.
0:17:59I think that'd be awful, right?
0:18:02Play like a sad trombone.
0:18:03Yeah, and so you have to, like, a lot of my syncing stuff is about saying, like, what's
0:18:07the biggest number of steps that you've shown the user for the particular time period that
0:18:12we're looking at?
0:18:13And syncing that up so that if I ever needed to show, sort of add extra steps, I know what
0:18:20I need to add. And also I need to do that, but it's not just as simple as who's shown
0:18:26more because the nature of these devices is which one of them is going to be showing you
0:18:31a better view of the user's activity probably at any one time. When I'm walking and pushing
0:18:36my daughter in a stroller, my phone in my pocket is going to be a better idea of how
0:18:40many steps I am because my wrist is actually not moving. It's attached to a stroller pushing
0:18:44it along. But when my phone is in a backpack, or my wife runs into this a lot, her phone
0:18:51will be in her purse, but her watch is on her wrist, so then her watch is the better
0:18:55indicator of steps. So it's like having to work out a scheme that is in real time
0:19:00dynamically working out which one, based on the information we have, which we may or may
0:19:04not have all the time, looking at the two data streams and merging them together. That's
0:19:12that's the minimum threshold for having this thing work,
0:19:16is you have to have built a system that can do all that.
0:19:19And that was the complexity for me that just became like,
0:19:21wow, this is a whole bigger thing
0:19:23than I ever imagined it would be.
0:19:25- Yeah, and that's like one of the things
0:19:29that makes these unexpected complexities
0:19:32so frustrating or so powerful,
0:19:34is that, again, they're unexpected.
0:19:38You have no idea when in a project
0:19:41you're going to hit something like this
0:19:42until you hit it.
0:19:43And so like, you know, the more experience you get
0:19:47as a developer or just as a person who lives in life,
0:19:52the more experience you get,
0:19:53it becomes a little bit more likely
0:19:55that you'll spot them ahead of time
0:19:57and be able to possibly either avoid them
0:19:59or at least like budget for them.
0:20:01But there's still always like stuff that you hit
0:20:04that's unexpected and it can totally throw a project off.
0:20:07So like, you know, one thing that I do to manage this
0:20:11is if I can tell something's going to be a big hairy mess,
0:20:15a lot of times I'll just cut the feature.
0:20:17I'll just avoid it.
0:20:19I'll say, "Sorry, that's not worth doing."
0:20:21With Overcast, I knew streaming was gonna be a big deal,
0:20:24so for version 1.0, I just didn't include it.
0:20:27I couldn't ship it in time.
0:20:30I estimated that it would be a better idea
0:20:32to ship the app without streaming
0:20:34than to wait another six months to a year to add streaming.
0:20:39That turned out to be correct.
0:20:41And in the case of my watch app now,
0:20:43where I have the watchOS 1 app,
0:20:45the watchOS 2 app would be a ton of work
0:20:48and would be different and might not be better.
0:20:51It might just be different.
0:20:53I've calculated so far that at the moment
0:20:56it isn't worth investing the time in that.
0:20:57And it might never be, I don't know.
0:20:59But certainly right now it isn't worth
0:21:01investing the time in that,
0:21:02when I could instead be doing something
0:21:04with the same amount of time,
0:21:05I could instead be doing something like the Apple TV app
0:21:08or a major new feature, or even a brand new app
0:21:13if I wanted to.
0:21:14You have to really decide what's worth sinking
0:21:17all this time into, and sometimes it isn't
0:21:20the big hairy problem in front of you.
0:21:21Sometimes that problem is best off just staying unsolved.
0:21:26That feature might be better off staying unimplemented,
0:21:29or that app might be better off not being made,
0:21:32and you might be better off spending that time
0:21:34in other ways, because you can do a lot
0:21:37of low-hanging fruit in other parts of your app
0:21:40or as other apps in the same amount of time
0:21:42that you could tackle one big hairy problem in one app,
0:21:45and it might not be worth it.
0:21:46Our sponsor this week is Need.
0:21:48Go to neededition.com.
0:21:50Need is a curated retailer and lifestyle publication
0:21:53for the modern gentleman.
0:21:54Each week, Need launches new collections
0:21:56of exclusive clothing, literature, furniture, and more.
0:22:00Now earlier this month,
0:22:01coinciding with the company's second birthday,
0:22:03Need launched an all-new site expanding its availability
0:22:05into 43 countries in Europe, South America, Asia, and the Middle East. Shipping is flat
0:22:11rate for all international orders and free for all orders to the US, Canada, and Mexico,
0:22:16and all returns are free no matter where you are all over the world.
0:22:20This month, Neve has launched three collections, including their Holiday Gift Guide, featuring
0:22:24dozens of gift ideas for the holidays, many of which are under $40. Neve is designed to
0:22:29be simple, straightforward, and uncomplicated. They include prepaid return labels with all
0:22:34They offer 24/7 support and there aren't any subscriptions or stylists or other gimmicks
0:22:39to deal with.
0:22:40It's just a straightforward retailer.
0:22:42Simply come along to NeedEdition.com, peruse the latest collections and shop.
0:22:46Or don't, your choice.
0:22:48For listeners of this show, use coupon code radar for 20% off.
0:22:52That is coupon code radar at NeedEdition.com for 20% off anything.
0:22:56Thank you so much to our friends at Need for sponsoring Under the Radar.
0:23:00Getting back to one thing that you just said that I think is probably a good place to be
0:23:05winding down this discussion is, I think the thing that I've learned most, like this
0:23:09is the battle-hardened wisdom of dealing with complexity, is making sure that I'm solving
0:23:18the problem for the right reason.
0:23:21I think most of us who get into software engineering, or whatever you want to call what we do, we
0:23:26We like solving problems, and the problems that we like solving most are the most difficult,
0:23:31interesting, tricky problems. Like, that is, I think I'm in my element the most, I'm the
0:23:37most engaged, I'm the most excited about what I'm doing when I'm solving a really interesting
0:23:41problem. Like, if I'm just writing boilerplate code, that's not nearly as exciting and something
0:23:47I want to really, like, wrap my arms around and get, you know, sort of get up in the morning
0:23:50to dive into. And so the thing that I, though, then always have to keep in the back of my
0:23:54my mind when I find a problem like this, when I'm working along on a task and I find that
0:23:58there's this big unexpected bump in complexity. Like you were just saying, sometimes you're
0:24:02just worth not doing it. The thing I know I've had to teach myself some discipline with
0:24:07is that when I see a problem like that, when I seize an opportunity to really go crazy
0:24:11spelunking, dive deep down into some crazy low APIs and build this crazy cool clever
0:24:17system, make sure that I'm not just doing it because it would be intellectually fun
0:24:23and interesting. Sometimes there's a place for that, but I've definitely caught myself
0:24:28sometimes just building things because I think it would be fun and it wouldn't actually make
0:24:32my customers happier. It wouldn't actually make my products better. It would just be
0:24:37fun for me to do. I end up just going down these crazy rabbit holes and doing all these
0:24:41things and often the reality is it isn't actually as fun as I thought it was going
0:24:46to be. It's fun for the first few hours, first few days, and then you're just like
0:24:51It's like you're in this point where,
0:24:53like I always want to avoid where,
0:24:54it's like I started working on my car
0:24:56and I've taken it completely apart.
0:24:57And then I come to discover
0:25:00the fun part was taking it apart.
0:25:02The fun part is not putting it back together.
0:25:05And now I don't have a car anymore.
0:25:06That's the part where I have to catch myself
0:25:09and be like, am I really doing this for the right reason?
0:25:11Is this complexity worth the effort?
0:25:14And having that kind of taking a step back from your work
0:25:18is a sort of a habit and a discipline
0:25:20I've found has been very helpful in me making sure that I'm staying on track.
0:25:23And especially being like a one-man shop, like there's no one, I don't have a supervisor
0:25:27being like, "Huh, yeah, yeah, we're just going to cut that feature."
0:25:30That's too much.
0:25:31It has to be something that I have the ability to not just get totally sucked down these
0:25:36rabbit holes and say like, "Yes, of course, I need to do this thing because it's really
0:25:40interesting and really hard."
0:25:42Like, I need to be able to say like, "Will my customers notice if I do this?"
0:25:47And if they won't, like am I just doing this for myself?
0:25:50And if I am, like that's kinda sometimes fun,
0:25:55but that's really not a way that you're gonna be able
0:25:57to reliably ship quality products.
0:25:59You're just gonna end up with a lot of kind of like
0:26:01crazy half-built things that probably will end up
0:26:04making your app more complicated and harder to use
0:26:07for your customers in the end.
0:26:08- Yeah, that's a fantastic way to look at it.
0:26:11And we all face that dilemma because I mean look,
0:26:14we're all geeks, we all like interesting things,
0:26:17We all like keeping our brains interested
0:26:18and trying new things and approaching problems in new ways
0:26:21or doing things in better ways
0:26:22than what we did in the past.
0:26:24It's not that you should never do that,
0:26:25but that there's a balance to be struck
0:26:27and that doing that has significant time costs
0:26:31that may not be worth it.
0:26:32And doing a major rewrite of something that already works
0:26:36might also introduce brand new bugs,
0:26:37in fact, it almost certainly would,
0:26:39brand new bugs that you didn't have before
0:26:42then you'd have to go fixing that.
0:26:44And so it's just a balance.
0:26:45You need to keep yourself happy and learning
0:26:48and intellectually satisfied.
0:26:50But you also need to ship products
0:26:52and it's important to find that balance.
0:26:55And that's something that I think mostly just comes
0:26:57with experience and wisdom over time.
0:27:00It's not that you can never have fun,
0:27:02but that you should know when to have fun
0:27:05and when it's no longer fun and you need to get back to work.
0:27:09- Yeah, and I think the best lesson I've had about that
0:27:12is it's trying to have customer-focused development
0:27:15that way. It's like the time to do that, the time to solve interesting problems, is to
0:27:19find features or find apps or find ideas that solving a difficult problem will make a customer's
0:27:27life better. And like the intersection of those two things, like a really interesting
0:27:31technical problem and a real honest need or pain point in someone's life, like that's
0:27:37where really interesting and fun work happens. And if you can't sort of honestly say that
0:27:43that it's both interesting to build
0:27:45and useful for a customer,
0:27:47then you're probably not in a place
0:27:49that it's actually worth building.
0:27:51- All right, thanks a lot for listening, everybody.
0:27:53Please tell your friends about the show,
0:27:55help us spread the word,
0:27:56recommend us on Overcast,
0:27:58and we'll see you next week.