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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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:54
◼
►
And UI search controller is itself a giant pile of hacks that shouldn't work but somehow
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: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: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: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: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: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:53
◼
►
[BLANK_AUDIO]