#40: Ship It
00:00:00
◼
►
[MUSIC PLAYING]
00:00:03
◼
►
Hello, and welcome to Developing Perspective.
00:00:05
◼
►
Developing Perspective is a podcast discussing news of note
00:00:08
◼
►
in Apple, iOS, and the like.
00:00:10
◼
►
I'm your host, David Smith.
00:00:11
◼
►
I'm an independent iOS developer based in Herndon, Virginia.
00:00:14
◼
►
This is show number 40, and today is Tuesday, May 1.
00:00:17
◼
►
Developing Perspective is never longer than 15 minutes,
00:00:19
◼
►
so let's get started.
00:00:21
◼
►
All right, today I'm going to be talking about my process
00:00:25
◼
►
for releasing a new app.
00:00:26
◼
►
Like I mentioned yesterday, I'm working
00:00:28
◼
►
to audiobooks, which is one of my sort of main sort of bread and butter apps, and it's
00:00:33
◼
►
kind of something I've been working on for a couple of months now in reality.
00:00:36
◼
►
And so I kind of thought it would be interesting to share what that process looks like, how
00:00:41
◼
►
I start with something that is in the store right now, you know, it's shipped, it's working,
00:00:46
◼
►
it's making me money, and take that and sort of decide how I'm going to work on it, how
00:00:52
◼
►
I'm going to improve it, what makes sense.
00:00:54
◼
►
So essentially what typically happens when I launch an app is I'm going to take something,
00:01:01
◼
►
put it in the store, you kind of say whatever, like the last version 3.0, say, and I ship
00:01:07
◼
►
it and you kind of hope, you pray, you see what happens and you kind of see how people
00:01:13
◼
►
like it, some people don't, some people like it, some people won't.
00:01:16
◼
►
I've been doing this for long enough that I can't, I must say that I don't really read
00:01:20
◼
►
my app store reviews very much anymore.
00:01:23
◼
►
just not a lot of useful information in there very often.
00:01:27
◼
►
I tend to base my sort of decisions on things like people who take the
00:01:31
◼
►
effort to write me an email and do so in a sort of a non-anonymous way
00:01:35
◼
►
that I can react to.
00:01:36
◼
►
But you know, you kind of get into a bug fix phase where I'm like,
00:01:40
◼
►
okay, now I'm going to add, you know, oh, some reports are a problem
00:01:45
◼
►
Oh, I shipped something that was, you know, that was silly, that was
00:01:47
◼
►
silly, that was silly.
00:01:48
◼
►
Kind of work my way through that process.
00:01:51
◼
►
And then I will sort of hit a point where I'm like, "Okay, I think it's about time to
00:01:58
◼
►
kind of do something new."
00:02:00
◼
►
Or "I'd like to improve it."
00:02:03
◼
►
Or you know, kind of maybe wonder if I'd do better sales if I did something else.
00:02:10
◼
►
And so this kind of is a tricky thing to do, to sort of make that decision.
00:02:15
◼
►
Because I want to always make sure that I'm not shipping updates just for the purpose
00:02:19
◼
►
of shipping updates.
00:02:20
◼
►
I think there's kind of, you can kind of get used into this cycle of like, okay, well,
00:02:24
◼
►
you know, software that gets updates is, that's what you do.
00:02:30
◼
►
It's like, I'm writing software, it needs an update.
00:02:31
◼
►
I'm writing software, I need an update.
00:02:34
◼
►
But that cycle you can also kind of end up just sort of with the Microsoft Word approach
00:02:38
◼
►
or you, well, we're just going to throw in features.
00:02:40
◼
►
We're throwing features, throwing features.
00:02:42
◼
►
Whereas what I tend to do for a major update is to kind of think, okay, what are some of
00:02:48
◼
►
the marquee features that people have talked about that they would like, or features they
00:02:54
◼
►
don't like how they work currently, those kinds of things.
00:02:58
◼
►
I put all that together.
00:03:00
◼
►
And then I take those, work through from all the help desk requests we've gotten, and think
00:03:07
◼
►
about, okay, so that's the starting point.
00:03:10
◼
►
Here's the big features.
00:03:11
◼
►
Here's things I'm thinking about.
00:03:14
◼
►
And then I'm like, OK, let's draw a line, kind of branch the code and say, OK, so I
00:03:19
◼
►
might do some bug fixes on what's in the store now, but I'm going to work on this new thing.
00:03:24
◼
►
And this is just probably worth pointing out that this is slightly different than my process
00:03:27
◼
►
when I'm working on an update that's motivated by Apple.
00:03:33
◼
►
So like when the Retina iPad came out, I needed Retina graphics.
00:03:37
◼
►
That update is just kind of like, I see the need, I do it, and you move on.
00:03:40
◼
►
But for these kind of more functional updates, I then I can draw a line, say, okay, now I'm
00:03:46
◼
►
working on whatever numbering thing I'm working on.
00:03:50
◼
►
I'm working on version 5.0.
00:03:52
◼
►
And just kind of branch the code and start diving into that.
00:03:56
◼
►
And for me, the way that I kind of work that tactically, I'm not a big fan of these, or
00:04:01
◼
►
I tend to not do things like feature branches and kind of have this very complicated sort
00:04:06
◼
►
configuration management process internally
00:04:09
◼
►
for a project where I'm the only person working on it
00:04:12
◼
►
because it tends to just sort of
00:04:14
◼
►
make... I don't tend to find a lot of value in that.
00:04:17
◼
►
I build it if I'm doing something very experimental or when I'm doing something
00:04:21
◼
►
that really just
00:04:23
◼
►
really touches a lot of things and breaks stuff in
00:04:26
◼
►
ways that would be... if I needed to undo, it would be kind of annoying to do
00:04:30
◼
►
undo through the git process. Like for example when I recently converted audiobooks to
00:04:34
◼
►
I made a branch for that because it changes literally every class in the application was
00:04:38
◼
►
changed and in a way that is not reversible easily.
00:04:42
◼
►
So I did that in a branch, but generally I just kind of work and you just kind of start
00:04:46
◼
►
plotting along on big features.
00:04:50
◼
►
Maybe it's just my background, but I've found it better to get a feature working and then
00:04:56
◼
►
make it look good than it is to spend a lot of time up front in things like Photoshop
00:05:02
◼
►
or fireworks or even sometimes even a pen and paper, I find that I'm often even just
00:05:06
◼
►
quicker just like, "Okay, well, I know it's kind of going to be a table view with some
00:05:10
◼
►
stuff on it, so okay, let's make a table view and see what that looks like."
00:05:13
◼
►
Then I can play with it.
00:05:14
◼
►
I can throw data into it.
00:05:15
◼
►
I can kind of mock it up in a way that is actually useful, and that's not work that
00:05:19
◼
►
I'm going to necessarily be throwing away.
00:05:23
◼
►
So that's kind of my process internally that I know some people like each screen mocked
00:05:27
◼
►
up, you know, specifically in Photoshop and all this.
00:05:31
◼
►
I tend to, it's like, all my buttons to start with are just UI round wrecked buttons.
00:05:37
◼
►
And all my text is just Helvetica standard, and you just kind of run with that.
00:05:44
◼
►
And then as I go, I'll work on sort of improving that, cleaning it up, fixing it.
00:05:49
◼
►
As I'm going, I'm definitely not thinking about performance, really.
00:05:52
◼
►
I'm not thinking about sort of file management or sort of just clean up things.
00:06:00
◼
►
I'm not really worried about--
00:06:01
◼
►
and back in the old days, it was like,
00:06:03
◼
►
I wouldn't worry as much about even somehow precise
00:06:06
◼
►
my memory management was in the days before ARC.
00:06:10
◼
►
My goal was to make it work, to make it work quickly
00:06:12
◼
►
so I could see if this is something
00:06:13
◼
►
that I would actually want.
00:06:17
◼
►
And as I'm doing that, this is especially
00:06:19
◼
►
something relevant for a project like, say, audiobooks,
00:06:22
◼
►
or even when I'm working on my recipe book, my other app,
00:06:25
◼
►
where these apps have been around for years.
00:06:28
◼
►
audiobooks is coming up on its three year anniversary of being released into the app
00:06:32
◼
►
store which is kind of crazy for, you know, the app store's only been around for three
00:06:36
◼
►
and a half years I think, or maybe four, or four years from the SDK launch I think. And
00:06:41
◼
►
so it's been a long time. There's a lot of code that's kind of, some of it's been, is
00:06:46
◼
►
probably from that initial commit, you know, way way long ago, you know, years ago. And
00:06:54
◼
►
It's always one of those things that you kind of have to, as a developer, be constantly
00:06:58
◼
►
sort of thinking about is you have to fight the urge to rewrite everything.
00:07:04
◼
►
You see something and you're like, "Oh, I could do that better."
00:07:06
◼
►
You know, say a classic example now that we've run into a lot is there's new block-based
00:07:10
◼
►
APIs for all kinds of things, or I can write my own block-based API.
00:07:15
◼
►
And I have to kind of always be thinking to myself, "Does doing that make the user's experience
00:07:22
◼
►
better. And does doing that, how likely am I to get it right? How likely am I to actually
00:07:28
◼
►
correctly replace, if I'm taking, if I'm not adding functionality, if I'm just trying to
00:07:35
◼
►
take something that works, you know, something that takes input A and has output B, and I'm
00:07:40
◼
►
just going to change the middle, what's the likelihood that I'm going to give it input
00:07:43
◼
►
A and then it's going to give me C back? And more often than not, all the weird edge cases,
00:07:50
◼
►
all the things that you've kind of dealt with are hard to recreate.
00:07:54
◼
►
And often this is something that I know I've seen myself do dozens of times, is you have
00:08:00
◼
►
the bigger problem of you say a given function that you're thinking of rewriting, that you're
00:08:06
◼
►
thinking, "Oh, I could make that better.
00:08:07
◼
►
Oh, I could make it faster.
00:08:08
◼
►
Oh, I could use this hot new thing and it'll be awesome."
00:08:16
◼
►
function has some built-in latent, some built-in assumptions inside of it and if
00:08:21
◼
►
you rewrite it you'll often rewrite it in perhaps improving it to the ideal and
00:08:27
◼
►
what you'll end up doing then is that ends up breaking a whole bunch of other
00:08:32
◼
►
things that were assuming that it was slightly broken that you've coded around
00:08:36
◼
►
these problems and this isn't a novel concept that I'm talking about but it's
00:08:40
◼
►
something that as a software engineer you have to be think cognizant of that
00:08:44
◼
►
that you have to keep in mind that your code is likely not perfect, and beyond that, your
00:08:50
◼
►
code is actually probably kind of broken, in some way at least.
00:08:55
◼
►
And you have to be careful about ripping it out and changing it too much, because you
00:09:00
◼
►
may actually be making it worse, or you may be creating this whole can of worms for yourself
00:09:05
◼
►
down the road.
00:09:06
◼
►
And then related to that is just something that I always try and think about as I'm like,
00:09:10
◼
►
when I see something that I'd love to fix that, oh, I'd like to change that, is, you
00:09:14
◼
►
that will the user notice that I did this and if the user won't notice I
00:09:20
◼
►
almost never do it and unless it makes my life as a developer much better and
00:09:27
◼
►
much simpler so then you know an example of a lot of these things is you'll often
00:09:32
◼
►
kind of rewrite something refactor it because you can because you oh I could
00:09:38
◼
►
make it cleaner code I could make it better code I always get now I try and
00:09:43
◼
►
shy away from that because if it works now, I should just run with that. If it doesn't
00:09:48
◼
►
work, okay, well then I'm fixing it and the user will notice. And then the only exception
00:09:52
◼
►
are those areas where it really makes my life better. So it's like recently I converted
00:09:56
◼
►
audiobooks to ARK. And ARK makes my life easier, makes it simpler, means that I'm not doing
00:10:03
◼
►
a lot of this sort of bookkeeping grunt work in my coding, I'm focusing on sort of higher
00:10:08
◼
►
level features. And so for me, that's kind of my rule of thumb. And then I kind of work
00:10:15
◼
►
from there, once I've got these big features, you kind of get into this polish phase. And
00:10:20
◼
►
I kind of like to think about this kind of like a lathe, which is, if you're not familiar
00:10:24
◼
►
with this, a tool for carpentry and metalwork, where you take a big hunk of wood, put it
00:10:29
◼
►
on a thing and it spins it. And then you can take a tool and just run it across the lathe.
00:10:35
◼
►
And you kind of have, you know, you may start off with a big chisel, like a big honking
00:10:41
◼
►
piece of metal that you run across the wood, and you're just letting huge chunks fly.
00:10:46
◼
►
And this is kind of that big feature phase.
00:10:48
◼
►
You're just getting it working.
00:10:49
◼
►
You're getting the rough shape of what you want.
00:10:52
◼
►
And then, okay, so now you're past that, so now you're going to go in there with kind
00:10:55
◼
►
of a fine pick.
00:10:56
◼
►
And you're going to be cleaning up these little details.
00:10:58
◼
►
You're going to be making sure, this is where you're like, okay, I'll make the buttons look
00:11:03
◼
►
you know, tweaks and performance things.
00:11:06
◼
►
Oh, I'll make sure, you know, deal with some of these edge cases.
00:11:10
◼
►
And then you get into the fun part.
00:11:11
◼
►
But also perhaps the most dangerous part is the polish phase.
00:11:14
◼
►
So this is you've got your sandpaper out and you're running it along what you're trying
00:11:18
◼
►
You're just trying to get rid of all the rough edges, all these little things that may annoy
00:11:24
◼
►
your user, may make them, or just adds that sort of richness to the experience that shows
00:11:30
◼
►
that you actually are paying attention to what they want.
00:11:32
◼
►
I say this is dangerous because this is the phase that I find a lot of independence gets stuck in
00:11:37
◼
►
Where they'll never actually ship or it'll take hugely more time than they actually need to ship
00:11:44
◼
►
Because they constantly have that thought of "Oh, what if I did X? Oh, what if I did Y? I could make it better
00:11:52
◼
►
I could do this, I could do that" and you're starting to get beyond actually polishing something into
00:11:58
◼
►
You know you're pulling out your chisel again, and you're actually hacking away at something
00:12:03
◼
►
That was almost ready to ship now if what you had to start with was not good well
00:12:07
◼
►
Then you need to fix it, but if what you're doing is just creating new features and doing these things
00:12:13
◼
►
You have to be so careful of that
00:12:15
◼
►
I just think that I've seen so many times in you know my friends and other independents
00:12:19
◼
►
Or you'll kind of get stuck and you'll be like oh, man. This is almost ready. Oh, man. This is almost ready
00:12:24
◼
►
I'm going to ship it soon." And then six months later you don't. And it's often because you're
00:12:29
◼
►
kind of, instead of polishing, you're still kind of polishing with one hand and you've
00:12:36
◼
►
got a chisel in the other and you're kind of still hacking away on it. And so then you
00:12:39
◼
►
start breaking things and things start not working exactly how you'd like. So you just
00:12:43
◼
►
kind of have to draw a line at some point and say, "All I'm going to do is tweak things.
00:12:47
◼
►
All I'm going to do is polish things." And you hit a point that you're like, "Okay, I've
00:12:51
◼
►
I got my release candidate.
00:12:52
◼
►
I recently hit that, I think last Wednesday or so, I hit my release candidate.
00:12:57
◼
►
And so now I'm not working on any sort of really new stuff.
00:13:01
◼
►
I'm just trying to polish and tweak the experience, do bug fix testing,
00:13:05
◼
►
make sure that it actually works, make sure that, and this is where you start,
00:13:09
◼
►
I have whatever, 40 different devices, not 40, I have a dozen different devices.
00:13:13
◼
►
All kinds of different software configurations, things.
00:13:16
◼
►
I have, luckily I was able to recently drop my support for 3.0, so
00:13:20
◼
►
to, you know, I have an iPad and I can put iPod touches on three various flavors of three
00:13:25
◼
►
that I don't need to use anymore. And I can, you know, just sit there and I'll run it on
00:13:29
◼
►
my iPhone 4S, an iPhone 4, an iPhone 3GS, which is all I need to do, I think, and I
00:13:35
◼
►
think a 3G. Make sure it works on there. I'll put it on an iPad, put it on an iPad 2, put
00:13:41
◼
►
it on an iPad 3, just kind of play with it and make sure that it works across the way.
00:13:45
◼
►
Install the old version, do a bunch of stuff, install the new version, make sure that it
00:13:49
◼
►
updates correctly and then recently I've added iCloud support so then you're doing
00:13:53
◼
►
kind of even this other level of testing where I'm going back and forth
00:13:57
◼
►
and then you ship it. And I think it's an important thing to celebrate that shipping.
00:14:02
◼
►
It's something that a lot of developers actually never get to or
00:14:05
◼
►
it's a thing that
00:14:07
◼
►
and if you don't relish that, if you don't
00:14:08
◼
►
when you sell it, it's like yeah man I did it and you know take your wife out for a nice dinner
00:14:12
◼
►
or get a beer or whatever, whatever you like
00:14:15
◼
►
and celebrate the fact that you know you shipped
00:14:18
◼
►
That's a big deal.
00:14:19
◼
►
Alright, so that's today's show.
00:14:21
◼
►
Hope you enjoyed it.
00:14:22
◼
►
If you have any questions, comments, concerns, as always, hit me up on Twitter.
00:14:25
◼
►
I'm @_davidsmith.
00:14:28
◼
►
Underscore D-A-V-I-D S-M-I-T-H.
00:14:31
◼
►
Otherwise, follow me on Twitter if you like what I say.
00:14:33
◼
►
If you like the show, as always, please tell a friend.
00:14:35
◼
►
Tell two, tell three.
00:14:36
◼
►
It's the best thing you can do if you like it and want me to keep recording.
00:14:40
◼
►
Alright, otherwise, happy coding and I'll talk to you later.