PodSearch

Under the Radar

70: The Hacks We Ship

 

00:00:00 ◼   ► Welcome to Under the Radar, a show about independent iOS app development.

00:00:03 ◼   ► 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:10 ◼   ► So today we are going to be talking about hacks.

00:00:15 ◼   ► About the hacks that we ship, the hacks that we probably shouldn't ship, and in general

00:00:21 ◼   ► kind of what they are.

00:00:22 ◼   ► I mean, I think it's a term that is often thrown around in development, and sometimes

00:00:26 ◼   ► in a pejorative way, and sometimes in a praising way.

00:00:32 ◼   ► Which is always kind of interesting when you have a word that can be both something that's

00:00:35 ◼   ► really good and awesome, and something that is awful and terrible and no good.

00:00:41 ◼   ► And so I think it's kind of a fun topic to just kind of unpack and talk through maybe

00:00:46 ◼   ► some of the good hacks, the things that are really cool and clever, the things that are

00:00:51 ◼   ► kind of in the middle ground where it's like, "Ehh, it's starting to get a little questionable."

00:00:56 ◼   ► And then some of the hacks that we probably should never ship.

00:00:58 ◼   ► But sometimes we do.

00:01:00 ◼   ► Yeah.

00:01:01 ◼   ► Oh yeah, so that is I think the tricky thing.

00:01:03 ◼   ► If you're not aware of which bucket it had particular hack falls into, you may start

00:01:10 ◼   ► to really fall into these traps a little bit more easily.

00:01:14 ◼   ► So when I think of a hack, I was trying to think of a good operative definition to kind

00:01:21 ◼   ► of separate it from just regular development.

00:01:23 ◼   ► And I think when I think of a hack, I think of something that is either a shortcut, like

00:01:29 ◼   ► either just like I'm finding a way to solve a problem that is kind of skipping over a

00:01:36 ◼   ► bunch of usually required steps, or it's kind of like an oblique solution to the problem.

00:01:44 ◼   ► So rather than like solving the problem in the way that you would expect to, or like

00:01:49 ◼   ► the natural solution, you find a way to have a solution that works.

00:01:54 ◼   ► And often a hack will kind of solve 99% of the problem, but not the 100% of the problem,

00:02:00 ◼   ► but you're okay with that because it does it in such a clever and clean way.

00:02:05 ◼   ► But it's typically about rather than doing the, I don't know if you can call it like

00:02:10 ◼   ► the academically correct solution to a problem.

00:02:13 ◼   ► Like the hack is the finding a way to do it by abusing some kind of one of the system

00:02:20 ◼   ► APIs or working around a system API in a weird way.

00:02:24 ◼   ► But in some way or other, you're kind of going around things in a non-traditional approach.

00:02:30 ◼   ► And ultimately I find that your ability to do these kinds of solutions can be really

00:02:36 ◼   ► powerful.

00:02:37 ◼   ► Like it's a funny thing to say, but I think I'm pretty good at finding these.

00:02:40 ◼   ► I don't really know exactly what part of my mentality.

00:02:43 ◼   ► I think it's just the profound laziness that I tend to have in life.

00:02:46 ◼   ► It's the best kind of programmer.

00:02:48 ◼   ► Yeah.

00:02:49 ◼   ► It makes me look for these.

00:02:50 ◼   ► Like it makes me look for like, huh, is there a way that I could, you know, if I'm looking

00:02:55 ◼   ► at this, this big complicated feature, I'm like, is there a way that rather than actually

00:03:00 ◼   ► solving it, I can kind of solve it?

00:03:03 ◼   ► Here's a bunch of work in front of me that I don't want to do.

00:03:06 ◼   ► Is there a way I can not do it?

00:03:08 ◼   ► Yep.

00:03:09 ◼   ► That's basically it.

00:03:10 ◼   ► And often there is.

00:03:11 ◼   ► Like when you start looking at these big scary problems, you often find these really novel

00:03:17 ◼   ► solutions that aren't as maybe academically or professionally as good or as clever, but

00:03:27 ◼   ► like get the job done.

00:03:29 ◼   ► And if it gets the job done, it gets the job done.

00:03:31 ◼   ► And so I'm always on the lookout for these.

00:03:33 ◼   ► And I think in general, it's a great tool for getting things up and going.

00:03:37 ◼   ► And especially, you know, like the Nap Store is a pretty dynamic environment where being

00:03:41 ◼   ► able to do things more quickly than your competitors is an advantage.

00:03:47 ◼   ► Like it is definitely an advantage to be able to do things more quickly.

00:03:50 ◼   ► And you know, the ability to find these shortcuts and find these oblique solutions to problems,

00:03:55 ◼   ► I think is a great, it's one little like tool in the toolbox to help us, you know, sort

00:04:00 ◼   ► of stay ahead.

00:04:01 ◼   ► Yeah.

00:04:02 ◼   ► And I, the thing about finding a good hack is it's just so incredibly satisfying.

00:04:10 ◼   ► Like I love, like, and it's, you know, it's a kind of thing where like it's satisfying

00:04:16 ◼   ► both as a lazy person of like I just avoided a whole bunch of work.

00:04:21 ◼   ► But also just like as like an intellectual, you know, or a programmer, it's like you

00:04:26 ◼   ► get satisfaction out of cleverness, out of clever solutions.

00:04:30 ◼   ► And I just, I get so much joy out of it.

00:04:33 ◼   ► Like one of the favorite things I discovered recently was, do you remember, did you see

00:04:37 ◼   ► this back like in like, I think it was the Quake source code.

00:04:41 ◼   ► There was a method to do a fast inverse square root.

00:04:45 ◼   ► And this is something that games have to do a lot while rendering textures and stuff.

00:04:49 ◼   ► And you know, if you, and like square roots operations are complex mathematically, but

00:04:54 ◼   ► there was a way that, here it was, here I just found it.

00:04:58 ◼   ► It's in Quake 3 arena in the code.

00:05:01 ◼   ► And you know, like John Carmack is famous for being like an incredible programmer with

00:05:04 ◼   ► this kind of stuff.

00:05:06 ◼   ► And he probably wrote this or adapted this from whatever.

00:05:08 ◼   ► And like you totally bypass doing an actual reverse square root operation or inverse square

00:05:14 ◼   ► root operation by just like a bit of like bit shifting and quick math that's really

00:05:18 ◼   ► fast to do on processors.

00:05:19 ◼   ► And it includes this weirdo constant.

00:05:22 ◼   ► You like bit shift by this one weird constant, you know, like five F three seven something.

00:05:26 ◼   ► And in the source code, he actually wrote what the F like next to it, like what is this

00:05:31 ◼   ► number?

00:05:32 ◼   ► But it works and it generates like an approximation of the value that you need.

00:05:38 ◼   ► And it's something like 99% accurate, which is like good enough for a game purpose in

00:05:43 ◼   ► way less time on the processor than doing like the actual mathematically correct operation.

00:05:47 ◼   ► That's like, that is an amazing, amazing hack.

00:05:51 ◼   ► And that like, like the day that that was discovered by somebody must have felt amazing.

00:05:56 ◼   ► Like and like, so you know, like whenever I have like, you know, a day, like usually

00:06:00 ◼   ► I don't have a day like that where I discover a new way to do math.

00:06:03 ◼   ► But you know, I do often find like time savers or shortcuts or, or the ability, as you said,

00:06:10 ◼   ► really like the ability to like to, to do something that I wasn't supposed to be able

00:06:14 ◼   ► to do.

00:06:15 ◼   ► Like styling a certain element a certain way in the app or, or you know, a certain UI behavior

00:06:21 ◼   ► or a certain animation getting quite right.

00:06:25 ◼   ► And really like the best apps are filled with glorious, awful hacks because you know, usually

00:06:30 ◼   ► to do, to do whatever is considered making an app great at any given time almost always

00:06:37 ◼   ► involves some degree of like clever or horrendous hacks because oftentimes you're, you're

00:06:43 ◼   ► thinking around, you know, UI framework limitations or abilities of the platform that are, are

00:06:50 ◼   ► possible but really hard or you know, kind of edge cases that you don't usually need

00:06:54 ◼   ► to do.

00:06:56 ◼   ► And if you do glorious hacks effectively, you can set your app ahead.

00:07:02 ◼   ► You can make an app that people, that, that, that people take notice of, that, that does

00:07:06 ◼   ► something noteworthy or newsworthy.

00:07:08 ◼   ► And that can help you.

00:07:09 ◼   ► Not to mention the fact that as an independent, it can save you a bunch of time if you learn

00:07:12 ◼   ► how to hack well.

00:07:14 ◼   ► But you know, I think it's a question of like deciding when to try to find a glorious hack

00:07:19 ◼   ► to something and when to just say no thanks.

00:07:23 ◼   ► And that's, that's trickier than, than some of the hacks themselves.

00:07:26 ◼   ► Yeah.

00:07:27 ◼   ► Though I do think it's like, I think what you just hit on there is I think the, the,

00:07:31 ◼   ► the best kind of hack, like the one that I think is so, it's like the thing, you know,

00:07:35 ◼   ► the thing that I love is when you are able to use a hack to do something that shouldn't

00:07:40 ◼   ► be possible.

00:07:41 ◼   ► Right.

00:07:42 ◼   ► Like given whatever kind of what you're defining as possible, but like you come up with a way

00:07:46 ◼   ► to do something like, you know, in that example, it's like doing this math operation really,

00:07:50 ◼   ► you know, efficiently, like that shouldn't be possible.

00:07:53 ◼   ► Like it's, it's, you should only be able to do the math the way the math is, but like,

00:07:56 ◼   ► it's just somehow you're able to do it.

00:07:58 ◼   ► And from a developer, an app perspective, it's like, if you can do this thing that shouldn't

00:08:02 ◼   ► be, that shouldn't really be possible, but you find a way to do it, then you're necessarily

00:08:08 ◼   ► like putting yourself at an advantage towards your competitors because from their perspective,

00:08:12 ◼   ► it still is impossible.

00:08:13 ◼   ► Like it still is ridiculously computationally intensive or just, you know, a lot of times

00:08:18 ◼   ► you'll run into these things in, you know, there's just, you find a way to hack with

00:08:22 ◼   ► the frameworks that Apple gives us in a way that gets you, allows you to do something.

00:08:27 ◼   ► And like the one that I am still probably to this day, the most proud of was in parameter

00:08:32 ◼   ► plus plus, which, you know, it's a step counter.

00:08:34 ◼   ► And so I'm added a feature where it could show you your step count on the, as the badge

00:08:42 ◼   ► for the application itself.

00:08:44 ◼   ► I mean that alone is a hack, right?

00:08:45 ◼   ► The idea of using the, of using like the red alert badge as to represent a value that's

00:08:52 ◼   ► like in the thousands as a step count instead of like a message chat or something, that

00:08:56 ◼   ► is itself a glorious hack.

00:08:58 ◼   ► Yeah.

00:08:59 ◼   ► Nope.

00:09:00 ◼   ► That is the, that's not even the cool hack.

00:09:01 ◼   ► Like that was just kind of like, huh, I wonder if I can think of, cause this was in the days

00:09:06 ◼   ► before today view widgets.

00:09:07 ◼   ► And so I was like, how can I show you your step count without launching the app?

00:09:10 ◼   ► Like, Oh, what if I make it a badge?

00:09:12 ◼   ► Okay, that's great.

00:09:13 ◼   ► And it worked all right.

00:09:15 ◼   ► And turns out though that once you get to really big numbers of badges, because I'm

00:09:20 ◼   ► abusing the API, I discovered that it would start to truncate, you know, so if you, once

00:09:26 ◼   ► you got to above typically it was about 10,000, the 10 thousands of steps.

00:09:32 ◼   ► So once you hit 20,000 steps, the badge would start to truncate and it would just be like,

00:09:37 ◼   ► you know, two dot, dot, dot six is all that would show when you, you know, rather than

00:09:41 ◼   ► showing the actual step count.

00:09:44 ◼   ► And for a while I was just like, Oh, that's fine.

00:09:45 ◼   ► Like how often do people actually going to, you know, does it really matter that once

00:09:49 ◼   ► you've hit 20,000 steps that it did truncates, but it bothered me.

00:09:54 ◼   ► Like, you know, in the back of my mind, I'm like, I really don't like that.

00:09:56 ◼   ► There's got to be a way to work around it.

00:09:59 ◼   ► And one day, of course, it was while I was taking a shower, because that's where I

00:10:02 ◼   ► have all my best ideas.

00:10:03 ◼   ► Of course.

00:10:05 ◼   ► I had the thought, I was like, I wonder if I can rather than if the actual number that

00:10:12 ◼   ► I display there is important for what gets truncated, because it's why it goes from

00:10:17 ◼   ► what, you know, 10,000 to 20,000, it starts to truncate.

00:10:20 ◼   ► And it turns out, it gets truncated if you have, you know, the numbers are too wide,

00:10:26 ◼   ► because it's proportional font.

00:10:28 ◼   ► And so if I put a lot of ones in the number that gets displayed, it doesn't get truncated.

00:10:35 ◼   ► And, you know, this is why 10,000 doesn't get truncated, but 2000 does, because 2000

00:10:40 ◼   ► is wider.

00:10:42 ◼   ► And so once I had that, you know, test try that out, then I, what I've started to do,

00:10:46 ◼   ► but I started to think is like, huh, what if I just changed the step count so that it

00:10:51 ◼   ► always includes at, you know, at least when it's five digits long, it has to include

00:10:55 ◼   ► at least one one.

00:10:57 ◼   ► And when it's, you know, gets longer, you start to increase the number of ones that

00:11:00 ◼   ► it starts to do.

00:11:02 ◼   ► And it worked.

00:11:03 ◼   ► So if you, so if you once you get above 20,000 steps, the last digit is always a one, which

00:11:10 ◼   ► most customers will never notice, because it's the least significant digit, like the

00:11:14 ◼   ► difference between one, you know, the number ending in 21 and 23.

00:11:18 ◼   ► Like you're not going to really notice, you're mostly focused on the, you know, the more

00:11:21 ◼   ► significant digits at the front.

00:11:23 ◼   ► So I just sit there and I go through and I take, you know, I take the number and I just

00:11:26 ◼   ► count the number of ones.

00:11:27 ◼   ► And if there's not enough, then I add one at the end and replace that digit.

00:11:32 ◼   ► And I go from there.

00:11:33 ◼   ► And it's this like awful hack that kind of changing the, you know, I'm just dynamically

00:11:37 ◼   ► changing the step count so that the badges doesn't truncate.

00:11:40 ◼   ► But it works.

00:11:41 ◼   ► So I was able to abuse this system API for badges that was never really intended to display,

00:11:46 ◼   ► you know, numbers in the 20,000s and 30,000s.

00:11:49 ◼   ► Like if you have that many unread email, emails on the mail app, like that's not really telling

00:11:55 ◼   ► you anything.

00:11:56 ◼   ► It's just telling you, you have a lot of things.

00:11:58 ◼   ► And so Apple never really intended for this badge to be accurate, you know, to this and

00:12:02 ◼   ► this and this many digits.

00:12:03 ◼   ► But if you just randomly, if you just sort of go through and replace the, you know, digits

00:12:08 ◼   ► with a lot of ones that are nice and thin, it works.

00:12:12 ◼   ► And like that's the kind of hack where it takes something that doesn't seem like it

00:12:14 ◼   ► should be possible.

00:12:15 ◼   ► Like it shouldn't be possible to display the number 20,000 as a badge or an app icon.

00:12:21 ◼   ► But you know, find this kind of glorious hack by switching out a few digits and then it

00:12:26 ◼   ► was possible.

00:12:27 ◼   ► And like those are the best kind of hacks.

00:12:28 ◼   ► The places where we can make something that doesn't seem like it should be possible actually

00:12:33 ◼   ► work.

00:12:34 ◼   ► And in that kind of case, like that was also good because there were really no massive

00:12:39 ◼   ► side effects to it.

00:12:40 ◼   ► Like you weren't like, you know, like if, you know, the worst case scenario was Apple

00:12:44 ◼   ► updates the OS and the font is slightly different and the bounds of that box is slightly different

00:12:49 ◼   ► and then it doesn't fit anymore at all.

00:12:51 ◼   ► But you know, ultimately like that's a pretty safe hack because like worst case scenario

00:12:56 ◼   ► you got to update something, you know, later on but it's not going to break, you know,

00:12:59 ◼   ► like that's, and it doesn't really touch anything else.

00:13:01 ◼   ► And you are technically corrupting the display of the data but in a way that doesn't matter.

00:13:09 ◼   ► So like that's glorious, you know.

00:13:11 ◼   ► And this reminds me like, you know, a lot of times, you know, you can build a whole

00:13:15 ◼   ► feature on hacks.

00:13:16 ◼   ► Like you know, the entire badge icon feature is itself a glorious hack.

00:13:23 ◼   ► You know, back when I did Instapaper, the very first pagination algorithm I did, this

00:13:28 ◼   ► was, you know, now I think it's a lot easier on a web view.

00:13:31 ◼   ► I think they just built it in.

00:13:32 ◼   ► But back then there was no built in way to offer pagination of a web view.

00:13:38 ◼   ► You could scroll it and that was it.

00:13:41 ◼   ► That was, you know, your only choice.

00:13:43 ◼   ► And you could programmatically scroll it but, you know, there was no way to like split the

00:13:47 ◼   ► content into pages.

00:13:48 ◼   ► Even like WebKit now has ways to do that I think but it didn't back then.

00:13:52 ◼   ► And so I brainstormed lots of different ways that I could like figure out where the page

00:13:59 ◼   ► breaks were and paginate a large rendering of a webpage.

00:14:04 ◼   ► But because I had control over the background color and I knew that it was always normalized.

00:14:12 ◼   ► It was always like, you know, either your background color is either white or black

00:14:15 ◼   ► or whatever it is and like that's it.

00:14:18 ◼   ► And I also knew that I was doing things like sizing images and stuff such that they were

00:14:22 ◼   ► never taller than one page of the screen and things like that.

00:14:25 ◼   ► And so my crazy idea was, you know what, and this was back with the iPhone 1 hardware,

00:14:33 ◼   ► and that was a pretty slow device.

00:14:34 ◼   ► I'm like, you know, if I just take like a screen grab of the rendered page and just

00:14:43 ◼   ► search for like what is the, like go from the top and the bottom and try to find like

00:14:49 ◼   ► where is a solid color line of pixels.

00:14:54 ◼   ► And then just draw opaque views.

00:14:56 ◼   ► Once I find like where the solid lines of pixels are, basically draw like curtains,

00:15:01 ◼   ► one on top, one on bottom, to just black out the area up to that point.

00:15:06 ◼   ► And then I have pagination.

00:15:08 ◼   ► And all I have to do is when the user turns the page, draw the screen up, you know, scroll

00:15:15 ◼   ► up to the next page and then before it displays to the user, like during the same iteration

00:15:21 ◼   ► of the run loop, before it displays to the user, render it again to a bitmap, find that

00:15:26 ◼   ► next line and put those curtain views where they need to go.

00:15:29 ◼   ► So the user always sees consistent pages and it never breaks.

00:15:34 ◼   ► I thought there is no way this is going to work on the iPhone 1 and it did and it was

00:15:40 ◼   ► fast and it was great.

00:15:42 ◼   ► And the only downside was that if you had a line that included all lowercase letters,

00:15:48 ◼   ► it could theoretically and sometimes did cut dots off of i's and j's and put them on separate

00:15:54 ◼   ► pages because it could slice between the line, like the one pixel line between the i and

00:16:01 ◼   ► its dot, it could cut a page there because it didn't have any concept of line height

00:16:06 ◼   ► of the text being shown.

00:16:08 ◼   ► And that was the original pagination algorithm and it worked great.

00:16:11 ◼   ► And it was fast and that was the only downside and it didn't matter really much, you know,

00:16:16 ◼   ► it hardly ever was actually a thing.

00:16:18 ◼   ► So it was glorious and I could build this entire feature and because I had come up with

00:16:24 ◼   ► this crazy hack, actually had the initiative to try it and then was able to technically

00:16:28 ◼   ► do it and then of course had the guts to ship a horrible hack like that.

00:16:34 ◼   ► Because of that, I had this like must have feature of read later apps that no one matched

00:16:42 ◼   ► I think for like two years or something.

00:16:43 ◼   ► It was a long time before anybody else had pagination and that gave me a competitive

00:16:47 ◼   ► advantage and it was a great feature to use.

00:16:49 ◼   ► It was fun, my users liked it, I liked it and so it was kind of like, the only downside

00:16:55 ◼   ► was I didn't know if it would work in the future and this was always a problem but it

00:16:59 ◼   ► seemed like a pretty safe bet and it indeed did work.

00:17:03 ◼   ► I think I did eventually change the algorithm but I think it would have worked for basically

00:17:09 ◼   ► indefinitely into the future and I absolutely loved it.

00:17:12 ◼   ► Yeah and I think that speaks to some of the best sources of these kind of like these glorious

00:17:17 ◼   ► great hacks.

00:17:19 ◼   ► Is whenever you can think of the problem from a completely different perspective.

00:17:25 ◼   ► So in this case you took something that was like the usual solutions would involve dealing

00:17:30 ◼   ► with the HTML, right?

00:17:32 ◼   ► Dealing with the text itself and instead you're like, eh, rather than dealing with any of

00:17:38 ◼   ► that stuff that sounds really hard, I'm just going to think of it as a bitmap.

00:17:42 ◼   ► And like you completely take the problem and turn it around when rather than dealing with

00:17:46 ◼   ► like the really hard problem domain of like HTML layout and things that are just really

00:17:52 ◼   ► hard problems, it's like, you know what?

00:17:54 ◼   ► Bitmaps are easy, they're just arrays of arrays.

00:17:57 ◼   ► That's a really, like anytime you can kind of find a way to do that, it's these really,

00:18:02 ◼   ► I remember when I was doing computer science at college where you'd have these, and obviously

00:18:07 ◼   ► this was like an intentional exercise, this was a journey the professor was intentionally

00:18:12 ◼   ► taking you on where you start off with this really like naive solution that's kind of

00:18:18 ◼   ► really hard and tricky and then all of a sudden you end up at the end of this journey and

00:18:22 ◼   ► you're like, you're solving this problem in a really clever and novel way.

00:18:27 ◼   ► And usually it's like there was this magic point where you rather than solving the problem

00:18:30 ◼   ► directly, it's like you went around back and came in the side door and suddenly all these

00:18:36 ◼   ► other things are possible.

00:18:37 ◼   ► All these other things that should be hard suddenly aren't hard because rather than dealing

00:18:43 ◼   ► with text, you're dealing with pixels.

00:18:45 ◼   ► Or rather than dealing with the obvious solution, you're dealing with something differently.

00:18:51 ◼   ► You're not dealing with the raw data itself, you just deal with some other kind of meta

00:18:55 ◼   ► situation on it.

00:18:56 ◼   ► And that switch, that little insight that you can have is usually the source, I think,

00:19:03 ◼   ► of the best kind of hacks.

00:19:06 ◼   ► We are sponsored this week by Dice.

00:19:08 ◼   ► Dice has been helping tech professionals advance their careers for more than 20 years.

00:19:12 ◼   ► They have the tools and insights needed to give you an edge.

00:19:15 ◼   ► The Dice Careers mobile app is the premier tool to manage your tech career from anywhere.

00:19:20 ◼   ► With thousands of positions from top companies, you'll find exactly what you're looking for.

00:19:24 ◼   ► And if you're wondering what's next in your career, Dice's new career pathing tool can

00:19:28 ◼   ► help you learn about new roles based on your job title and skills.

00:19:32 ◼   ► They'll even show you which skills you'll need to make the next move.

00:19:36 ◼   ► And so the Dice Careers market value calculator allows you to understand what your skills

00:19:40 ◼   ► are worth.

00:19:41 ◼   ► You can discover your market value based not only on your job title and location, but also

00:19:45 ◼   ► your specific skill set.

00:19:47 ◼   ► So don't just look for a job, manage your entire tech career.

00:19:51 ◼   ► And Dice will help you do that.

00:19:53 ◼   ► Download the Dice mobile app and you can learn more at dice.com/undertheradar.

00:19:58 ◼   ► Once again, download the Dice mobile app and learn more at dice.com/undertheradar.

00:20:03 ◼   ► Our thanks to Dice for sponsoring this show and all of Relay FM.

00:20:07 ◼   ► So not all hacks are glorious though.

00:20:11 ◼   ► There are some hacks that are probably best left behind or the ones that at least you

00:20:15 ◼   ► need to be incredibly careful about doing.

00:20:19 ◼   ► And I think those tend to, at least from my experience, they come in kind of two categories.

00:20:23 ◼   ► There's the ones that you should never ship with that are really bad and dangerous.

00:20:27 ◼   ► And then there's the kind of like, "Mmm, maybe this is okay."

00:20:31 ◼   ► So I think of things like all the hacking that we end up doing to poor UITableView,

00:20:36 ◼   ► where we do all these things to kind of make some behavior work, but we're kind of abusing

00:20:42 ◼   ► the API in the way of doing this.

00:20:44 ◼   ► Or we use an API because it kind of lets us easily solve the problem when we know that

00:20:50 ◼   ► a better solution exists.

00:20:52 ◼   ► And so for that I think of something like using Background App Refresh.

00:20:58 ◼   ► For example, in a podcast app, you could use Background App Refresh to keep the subscription

00:21:04 ◼   ► list up to date.

00:21:05 ◼   ► Or you could do server-side crawling.

00:21:07 ◼   ► And server-side crawling is hard, but you can kind of make it kind of work with Background

00:21:10 ◼   ► App Refresh.

00:21:12 ◼   ► But it's kind of a hack because it's never going to be as good and a better solution

00:21:16 ◼   ► does exist and you're intentionally working around it.

00:21:20 ◼   ► It's fine, it's probably okay.

00:21:22 ◼   ► I think that kind of hacking, especially the things that we have to do around UIKit,

00:21:26 ◼   ► where it's like, "I want to style this element and I find some kind of weird way

00:21:31 ◼   ► to do it."

00:21:32 ◼   ► Or I find a way of, you know, like I remember trying to do something where I was inserting

00:21:37 ◼   ► elements into the top of a UITableView without affecting the current scroll position of the

00:21:45 ◼   ► UITableView, which seems like it should be somewhat straightforward but is actually fiendishly

00:21:51 ◼   ► hard.

00:21:52 ◼   ► And you just end up with these crazy hacks, you know, adjusting.

00:21:56 ◼   ► You kind of work out how the UITableView, how many pixels down it would shift down,

00:22:02 ◼   ► and you're in the same run loop shifted up.

00:22:05 ◼   ► But what happens if the user is touching it and scrolling while you do that?

00:22:09 ◼   ► All kinds of weird things happen.

00:22:10 ◼   ► You end up with these kind of awful hacks that don't work 100% of the time.

00:22:14 ◼   ► But you know, will work well enough most of the time, but are often kind of an essential

00:22:19 ◼   ► part of being an iOS developer.

00:22:21 ◼   ► So we kind of have to hack on these things.

00:22:23 ◼   ► And we kind of use these APIs in ways that they're really not intended for.

00:22:29 ◼   ► But when we do this, you know, it's probably good to keep in the back of our mind that

00:22:31 ◼   ► we are kind of hacking and we are doing these things that are almost certainly going to

00:22:35 ◼   ► come back to bite us at some point.

00:22:38 ◼   ► Oh yeah.

00:22:39 ◼   ► I mean, because, I mean, the thing is, like, you know, many of the UI hacks, like, you

00:22:44 ◼   ► know, something like a feature hack or something like, you know, something that's kind of

00:22:49 ◼   ► confined to your own code and your own components is way safer and a much, like, better idea

00:22:55 ◼   ► usually than hacking UI kit stuff.

00:22:59 ◼   ► Unfortunately, hacking UI kit stuff is often what we need to do.

00:23:03 ◼   ► And this is what makes, you know, so many of us depend on horrible hacks.

00:23:07 ◼   ► And you know, much to the chagrin of the Apple staff members whose job it is to deal with

00:23:13 ◼   ► us and the ramifications of us doing this.

00:23:16 ◼   ► We apologize.

00:23:17 ◼   ► But, you know, oftentimes that's what you need to do.

00:23:20 ◼   ► And fortunately, over time, as UI kit has gotten more mature and has gotten kind of

00:23:25 ◼   ► more built out, there are so many capabilities that are just built in now using officially

00:23:29 ◼   ► supported methods that before you'd have to do horrible hacks to achieve.

00:23:33 ◼   ► So certain appearance techniques or, you know, different behaviors, different traits.

00:23:39 ◼   ► But still, like, even in this day and age, like, here I was just shipping over CAS3 with

00:23:42 ◼   ► tons of table view hacks.

00:23:45 ◼   ► And even, like, even the collection view.

00:23:47 ◼   ► I hacked the collection view in my add podcast screen because I add a search controller to

00:23:53 ◼   ► it.

00:23:54 ◼   ► And UI search controller is itself a giant pile of hacks that shouldn't work but somehow

00:23:59 ◼   ► does.

00:24:00 ◼   ► And I, it really doesn't want to work in a collection view.

00:24:03 ◼   ► I have been unable to make this work consistently reliably in one way.

00:24:09 ◼   ► That is, since Overcast 1.0, if you type in a search query in my search box in the add

00:24:14 ◼   ► podcast screen and you select it and you hit copy in the pop up menu, it crashes.

00:24:22 ◼   ► It crashes deep within UI kit in some weirdo method.

00:24:26 ◼   ► This bug has been there since 1.0.

00:24:28 ◼   ► People report it to me almost every day.

00:24:31 ◼   ► But I can't fix it.

00:24:32 ◼   ► I have tried so many different things to fix it.

00:24:34 ◼   ► I can't fix it.

00:24:35 ◼   ► The only way I can fix that bug is to not use UI search controller on that screen.

00:24:41 ◼   ► And that is a significant re-architecting and the result would be worse.

00:24:46 ◼   ► So I've just kind of decided, you know, it's not something that people do very often.

00:24:50 ◼   ► The results aren't that bad.

00:24:52 ◼   ► I mean, it crashes, which is embarrassing, but I think it's long shabby and it's fine.

00:24:56 ◼   ► So I've decided for now that that's actually worth the bad hackness because the solution

00:25:03 ◼   ► of rewriting it to be something else is actually worse to me than that because it's such a

00:25:09 ◼   ► rare action anyway.

00:25:12 ◼   ► But I recognize that's a terrible hack.

00:25:14 ◼   ► In order to get a search controller working in a collection view, you've got to do some

00:25:17 ◼   ► weird stuff and it clearly is not made for that and I have no idea how to ever make that

00:25:22 ◼   ► work.

00:25:23 ◼   ► But I did it and it worked and it's fine.

00:25:25 ◼   ► But sometimes that's the wrong idea.

00:25:27 ◼   ► Yeah, and I think too it speaks to the, there's this funny line that you will eventually get

00:25:34 ◼   ► I think an instinct for, of like, at what point of hacking UIKit have you gone too far?

00:25:41 ◼   ► And like, anytime you find it, like, you know, you're trying to deal with, like, I ran into

00:25:46 ◼   ► this a lot when I was trying to, you know, you're trying to style a UIKit component in

00:25:49 ◼   ► a particular way.

00:25:51 ◼   ► And at a certain point, at least in like every like Stack Overflow thread about how to style

00:25:56 ◼   ► something, at some point someone will have like, now what you do is you iterate over

00:26:00 ◼   ► all of the subviews of this view until you find a particular view with this type and

00:26:08 ◼   ► this is apparent and like, it's like, no, you have crossed the line, my friend.

00:26:12 ◼   ► That is like you are going to a place where you're not just sort of hacking like you are

00:26:18 ◼   ► like just you've descended into madness because immediately that is going to break the next

00:26:24 ◼   ► time Apple changes something deep inside that.

00:26:27 ◼   ► And like those are the kinds of hacks where it changed, like you suddenly crossed the

00:26:31 ◼   ► line from like, this is okay, this is, you know, just kind of part of doing business,

00:26:37 ◼   ► this you have to kind of sometimes work around UIKit in ways that you might not like.

00:26:41 ◼   ► But as soon as you start kind of getting, becoming so dependent on very specific behaviors,

00:26:49 ◼   ► like the more tightly coupled you get, the far more likely your hack is to fall apart

00:26:53 ◼   ► at some point and can often fall apart in really spectacular ways that you may or may

00:26:59 ◼   ► not want.

00:27:01 ◼   ► So that's something that I definitely have seen.

00:27:03 ◼   ► It's important to develop this kind of instinct for like, you know, this isn't a good hack.

00:27:08 ◼   ► This is not the way to implement this feature.

00:27:11 ◼   ► And if that's what I have to do, if I have to go like spelunking down through the view

00:27:15 ◼   ► hierarchy until I can find the view that I want to change the appearance of, like, okay,

00:27:20 ◼   ► maybe it's just not going to be styled and that's probably okay.

00:27:24 ◼   ► - Yeah, I mean subview diving is almost always a terrible idea.

00:27:29 ◼   ► That's not to say I never do it.

00:27:30 ◼   ► In fact, I do it a few places in Overcast in order to get certain behaviors.

00:27:34 ◼   ► But there are ways to do it that are less risky than others.

00:27:36 ◼   ► I mean, obviously like simple things like just styling tweaks, that's really easy to

00:27:40 ◼   ► just bail out of.

00:27:41 ◼   ► Like, you know, like if you can't find what you expect to be there in this hack, then

00:27:45 ◼   ► just skip it and just bail out.

00:27:47 ◼   ► Like, you know, don't, and you can always do things like make sure that you're checking

00:27:51 ◼   ► the classes of things, using response to selector or is type of class, stuff like that, but,

00:27:57 ◼   ► or is kind of class rather.

00:27:59 ◼   ► You know, so there are ways you can do that are less fragile, but ultimately any kind

00:28:02 ◼   ► of dependence on subview diving for any kind of critical feature your app is a very bad

00:28:07 ◼   ► idea.

00:28:08 ◼   ► And if you can avoid it at all, please avoid it.

00:28:11 ◼   ► However, I, you know, do as I say, not as I do.

00:28:14 ◼   ► I do subview diving.

00:28:16 ◼   ► If I need to do subview diving, I'll do it and I'll just try to do it safely.

00:28:19 ◼   ► And that just means you're increasing your risk of having to rework your entire UI component,

00:28:24 ◼   ► whatever this thing is, next time a new iOS version comes out.

00:28:28 ◼   ► And I think the last kind of hack that I was thinking about too is like so often hacks

00:28:33 ◼   ► are the shortcuts, right?

00:28:34 ◼   ► There are these like approaches that we're taking to a problem to do something like we

00:28:38 ◼   ► have this big, this huge, this big amount of work that we're trying to avoid and we

00:28:42 ◼   ► find this clever way to avoid it.

00:28:44 ◼   ► Like it is not a good hack to do things like, to avoid things like error handling, right?

00:28:51 ◼   ► Like it's an easy, it's an easy time saving measure to, you know, not check the error

00:28:57 ◼   ► parameter of a callback or things like that.

00:29:00 ◼   ► Like they're easy, which you get into these kinds of situations where I'm like, oh, I'm

00:29:04 ◼   ► just going to quickly hack this together.

00:29:06 ◼   ► And you know, you download the JSON blob and turn it into object and work with it.

00:29:12 ◼   ► And assuming that JSON is there, assuming that JSON is well formed, it'll work perfectly.

00:29:17 ◼   ► Like great, like that was a really quick time saving hack to not check any of the resulting

00:29:22 ◼   ► values.

00:29:23 ◼   ► But don't do that in production.

00:29:24 ◼   ► Don't do that in something that you're going to actually, you know, ship out somewhere.

00:29:28 ◼   ► Like that's not a, it's like that's a hack in the wrong way.

00:29:32 ◼   ► That's when your hacking makes your app fragile and pretend, you know, and unreliable and

00:29:38 ◼   ► not good.

00:29:40 ◼   ► So don't do that.

00:29:41 ◼   ► Do the other kind.

00:29:42 ◼   ► The curious kind where it's awesome and clever and you look at it and you can show it to

00:29:45 ◼   ► your friends and be like, isn't this sweet?

00:29:47 ◼   ► That's the way, that's the kind you want to do.

00:29:49 ◼   ► Thanks everybody for listening this week, and we'll talk to you next week.

00:29:52 ◼   ► Bye.

00:29:53 ◼   ► [BLANK_AUDIO]