#118: Ambitious.
00:00:00
◼
►
Hello and welcome to Developing Perspective. Developing Perspective is a podcast discussing
00:00:07
◼
►
news of note, de-noise development, Apple, and the like. I'm your host, David Smith.
00:00:09
◼
►
I'm an independent iOS and Mac developer based in Herne, Virginia. This is show number 118,
00:00:13
◼
►
and today is Tuesday, April 9th. Developing Perspective is never longer than 15 minutes,
00:00:17
◼
►
so let's get started. All right, so it's been quite a week for me so far, and it's only
00:00:22
◼
►
sort of Tuesday. So what I'm going to talk about a little bit this week is kind of the
00:00:28
◼
►
The approach I'm taking and kind of, there's a little bit of it that's crazy, some of the
00:00:31
◼
►
things that I've been doing, and kind of why I'm doing what I'm doing.
00:00:36
◼
►
So first off, I'm going to talk about kind of this week.
00:00:38
◼
►
And it was just one of those strange things where a whole variety of things kind of lined
00:00:42
◼
►
up so that I was essentially going to have three major deliveries that I was going to
00:00:47
◼
►
try and do this week.
00:00:48
◼
►
The first one I did yesterday, I launched Check the Weather 1.4.
00:00:51
◼
►
I changed the weather backend and did a few other things.
00:00:56
◼
►
It's a significant update, but not a major update probably,
00:01:00
◼
►
Today, Tuesday, I launched my Recipebook 3.0,
00:01:03
◼
►
which is an app I've been working on, honestly, for years.
00:01:07
◼
►
It's been quite a while in making to try and get--
00:01:09
◼
►
to decide how I was going to do sync,
00:01:11
◼
►
to decide how I was going to do pricing,
00:01:14
◼
►
and all kinds of things, which I'll talk about in a little bit.
00:01:16
◼
►
And hopefully, actually, my goal is on Friday
00:01:19
◼
►
to submit Feed Wrangler's iOS app
00:01:22
◼
►
to the store, which is turning out to be-- we'll see.
00:01:26
◼
►
I think it's still probably doable,
00:01:28
◼
►
but if it turns out, those would have been
00:01:30
◼
►
three kind of crazy things to all do in one week.
00:01:33
◼
►
Early on Monday morning, I was thinking,
00:01:36
◼
►
and I was like, you know, is this wise?
00:01:38
◼
►
Am I taking on too much?
00:01:40
◼
►
Am I doing something that's kind of foolish
00:01:42
◼
►
by trying to do all these things?
00:01:43
◼
►
And really, the reality I found was,
00:01:45
◼
►
I always find it's the helpful thing to think about
00:01:47
◼
►
of what's the worst that can happen?
00:01:49
◼
►
What's the biggest downside?
00:01:51
◼
►
And is it any different than the downsides
00:01:53
◼
►
of doing things individually?
00:01:56
◼
►
And in this case, I really didn't think that the downsides were that different by doing
00:01:59
◼
►
it all together, that it was kind of nice to be a bit audacious, a bit ambitious, and
00:02:03
◼
►
to try and do all these things at once, because really all of them benefit from being out
00:02:09
◼
►
into the wild sooner and earlier.
00:02:12
◼
►
Things like sync, where there's problems and issues and things, the longer that I can be
00:02:15
◼
►
fixing them, the sooner that'll be the case, and the sooner I can then kind of settle that
00:02:20
◼
►
down and hide in a bow.
00:02:21
◼
►
And similarly with check the weather, it's like I could have held off on the update until
00:02:25
◼
►
next week, but it only sort of helps in that the same issues are still going to be there
00:02:32
◼
►
for the most part.
00:02:33
◼
►
And so in the end I was saying, you know, let's be audacious.
00:02:35
◼
►
And I think it's just as an encouragement to anyone out there, it's don't worry too much
00:02:38
◼
►
about overdoing it necessarily, that you want to be careful obviously, but if you trust
00:02:44
◼
►
yourself and you know your skills, you can kind of understand what are appropriate risks
00:02:49
◼
►
for you to take.
00:02:51
◼
►
All right, so the next thing I'm going to talk about
00:02:53
◼
►
is the My Recipe Book launch, a little bit about My Recipe
00:02:56
◼
►
Book more generally.
00:02:57
◼
►
So My Recipe Book's a recipe manager,
00:02:59
◼
►
fairly straightforward in that sense.
00:03:01
◼
►
It's a place that you can collect, organize, catalog
00:03:04
◼
►
your recipes.
00:03:05
◼
►
You can put it as a grocery list, those types of things.
00:03:08
◼
►
And the app's been around for about three years.
00:03:11
◼
►
And it's, until now, has always been a standalone iPad
00:03:13
◼
►
application.
00:03:14
◼
►
It's been something that is just-- that's
00:03:16
◼
►
the way it always was.
00:03:17
◼
►
I built it that way.
00:03:18
◼
►
And it always sort of just made sense that way.
00:03:22
◼
►
Because in order for it to work on to be universal,
00:03:25
◼
►
to be cross-platform, all those types of things,
00:03:28
◼
►
the recipes have to sync somehow.
00:03:30
◼
►
They have to be able to go back and forth between the server.
00:03:33
◼
►
So if you make a change, you input a recipe in your iPad,
00:03:35
◼
►
it shows up in your iPhone.
00:03:37
◼
►
And that was always a little intimidating.
00:03:39
◼
►
Because obviously, that's a fairly complicated problem.
00:03:42
◼
►
Sync is always complicated.
00:03:46
◼
►
There is no easy sync.
00:03:47
◼
►
And so at first, I tried a couple of things myself.
00:03:52
◼
►
iCloud came out.
00:03:53
◼
►
I tried that.
00:03:54
◼
►
None of those things had been quite right
00:03:57
◼
►
until I took a step back and said, OK, really,
00:03:59
◼
►
what am I trying to do here?
00:04:00
◼
►
And I just really methodically worked it through
00:04:02
◼
►
for a couple of weeks.
00:04:03
◼
►
And I was able to get to a point that, yeah, OK, this works.
00:04:06
◼
►
And I spent a couple of months testing and trying it out
00:04:09
◼
►
and playing with it and doing all kinds of things
00:04:11
◼
►
in the hopes of stabilizing it.
00:04:13
◼
►
Though I will say, sync is the kind of thing
00:04:16
◼
►
that's impossible to fully test until you deploy.
00:04:18
◼
►
I don't think there's any reasonable way,
00:04:20
◼
►
even with a large beta group, that you'll find all the bugs.
00:04:22
◼
►
There are just all kinds of subtle and nuanced things,
00:04:26
◼
►
things that relate to the nature of the user's data,
00:04:28
◼
►
for example.
00:04:29
◼
►
Like it's a recipe manager.
00:04:30
◼
►
It depends a lot on how many recipes some people have.
00:04:32
◼
►
And some people have quite a lot of recipes.
00:04:34
◼
►
I've found several users who have several thousand recipes,
00:04:37
◼
►
which I didn't-- I had test data sets that were that large,
00:04:41
◼
►
but I never really thought that that
00:04:43
◼
►
would be a realistic use case.
00:04:44
◼
►
And it turns out that is a realistic use case.
00:04:46
◼
►
So maybe my test data needs to be even bigger
00:04:49
◼
►
to account for that as an edge case.
00:04:51
◼
►
And also what I want to talk about is a little bit-- the way
00:04:53
◼
►
I took my sync, I've had a lot of questions about if I use
00:04:57
◼
►
iCloud, how I use iCloud, those types of things.
00:05:00
◼
►
I ended up using iCloud for a component of my sync.
00:05:04
◼
►
And what I ended up trying to do is try to be very pragmatic,
00:05:06
◼
►
and look at it and say, what does iCloud do
00:05:09
◼
►
that only it can do?
00:05:12
◼
►
And what are things that it potentially doesn't do as well?
00:05:16
◼
►
So first, what are some of the things that only it can do?
00:05:19
◼
►
And on an iPhone, the simplest version of that
00:05:23
◼
►
is it provides an avenue for ubiquitous login and user
00:05:28
◼
►
And when you have an app with an iCloud account,
00:05:32
◼
►
when they open that app, immediately available
00:05:34
◼
►
is who that person is to some approximation.
00:05:37
◼
►
And so what I started doing is, well,
00:05:39
◼
►
I'm going to sync the user-related profile
00:05:41
◼
►
information using iCloud to improve my user experience.
00:05:44
◼
►
I'm going to look at it and say, hey,
00:05:45
◼
►
if I put user information in the key value store, which
00:05:49
◼
►
is very reliable in my experience,
00:05:51
◼
►
I can create a great login experience.
00:05:53
◼
►
They open up the iPad.
00:05:54
◼
►
It says, hey, my RSP book 3.0 just launched.
00:05:56
◼
►
Would you like to sync?
00:05:57
◼
►
They hit yes.
00:05:58
◼
►
It sends it off to the cloud.
00:06:00
◼
►
They open up their iPhone and say, go to the App Store,
00:06:03
◼
►
get the app, open it up.
00:06:04
◼
►
And it says, hey, I noticed that you also have an iCloud.
00:06:07
◼
►
You've already sunk with this account.
00:06:09
◼
►
Would you like me to use this data?
00:06:10
◼
►
They say, yes, off it goes.
00:06:12
◼
►
And that is a really nice experience
00:06:13
◼
►
that you can only provide with something like iCloud, where
00:06:16
◼
►
it knows this meta information about who this person is
00:06:21
◼
►
and about the devices that they have.
00:06:23
◼
►
And then I take that-- all the hard part of the sync,
00:06:25
◼
►
the recipes and grocery list and those types of things,
00:06:28
◼
►
and I move that into my own cloud storage.
00:06:32
◼
►
And it isn't just because of all the things
00:06:33
◼
►
you hear about with iCloud core data syncing being complicated.
00:06:38
◼
►
I mean, I tried a variety of different solutions
00:06:40
◼
►
platforms. I tried some period of sync for a while. I tried, oh gosh, all kinds of different
00:06:45
◼
►
approaches. And in the end, what I kept coming down to is I wanted to own the sync, not necessarily
00:06:50
◼
►
because that makes my life easier, but because that makes my product better. Let me unpack that
00:06:56
◼
►
a little bit. Any time that you take something as sort of crucial as sync and put it into a third
00:07:03
◼
►
party's hands, whether that could be anything, it can be iCloud, it can be some period, it could be
00:07:07
◼
►
It could be Winder Azure services.
00:07:12
◼
►
I think there's a new thing that Matt Thompson released
00:07:16
◼
►
as part of his AF incremental store backend.
00:07:19
◼
►
There's all kinds of approaches you can take.
00:07:24
◼
►
Anytime you do that, the difficulty you run into is
00:07:26
◼
►
how easily, if at all possible, is it for you to fix problems,
00:07:29
◼
►
bugs, inevitable things that will come up.
00:07:33
◼
►
And usually whenever I was looking at most of these solutions,
00:07:35
◼
►
the tricky part is a lot of it's a black box.
00:07:38
◼
►
You take this data and you put it in there
00:07:39
◼
►
and you hope it works.
00:07:41
◼
►
Which if it works, is great,
00:07:42
◼
►
but it's never gonna work 100%.
00:07:44
◼
►
You have to kind of assume that it can do work
00:07:46
◼
►
a lot of the time, but it's never gonna quite be 100%.
00:07:49
◼
►
So what do you do in the weird edge cases?
00:07:51
◼
►
What do you do in the cases where the user
00:07:53
◼
►
has some strange configuration, some strange thing,
00:07:57
◼
►
weird connectivity, running through a weird proxy
00:07:59
◼
►
that is messing with the data?
00:08:01
◼
►
What do you do in that case?
00:08:03
◼
►
And a lot of times the answer for a lot of the platforms
00:08:05
◼
►
I looked at were, there's not really that much you can do.
00:08:08
◼
►
You can ask them to re-sync maybe,
00:08:09
◼
►
you can hope it's not destructive.
00:08:11
◼
►
But the reality is, what I love,
00:08:13
◼
►
is over the last two days,
00:08:15
◼
►
I've been able to go into the database,
00:08:17
◼
►
oh, go into the app, I can look at exactly what's going on.
00:08:20
◼
►
I can go through the server logs, I can replay stuff.
00:08:23
◼
►
I can look at it and be like, okay, this is the problem.
00:08:25
◼
►
Here's the thing that I need to fix.
00:08:27
◼
►
And the reality is, I think that makes
00:08:28
◼
►
my product a lot better.
00:08:29
◼
►
makes my customer experience a lot better.
00:08:32
◼
►
For example, I had a customer who had a particular data
00:08:35
◼
►
corruption bug that was pretty subtle and worked its way in.
00:08:38
◼
►
And I was able to go into his account, look in the database,
00:08:41
◼
►
tweak a few records, a couple of things that were wrong,
00:08:44
◼
►
and then I can send him an email and say, hey,
00:08:46
◼
►
your account's fixed.
00:08:47
◼
►
Next time you open the app, it'll be working fine.
00:08:49
◼
►
And that's just awesome to be able to reach into their life
00:08:52
◼
►
and do that for them.
00:08:54
◼
►
And so I highly recommend-- at the end of the day,
00:08:56
◼
►
it's a hard thing to say if someone says,
00:08:58
◼
►
oh, I've been thinking of doing my own, what should I use?
00:09:01
◼
►
Well, I can say that I can build my own
00:09:03
◼
►
because I'm an experienced Rails developer.
00:09:06
◼
►
Before I did iPhone development,
00:09:08
◼
►
I was a full-time professional consultant doing Rails work.
00:09:11
◼
►
I sort of knew my way around that world.
00:09:13
◼
►
And it's a hard thing to learn.
00:09:14
◼
►
I'm not saying it's impossible,
00:09:16
◼
►
but the reality is you wanna kind of work your way up.
00:09:19
◼
►
And if maybe you just tackle problems at an easier level
00:09:22
◼
►
if that's something that's above you.
00:09:24
◼
►
But it's really complicated
00:09:25
◼
►
if you're taking your core business value
00:09:28
◼
►
and putting it in someone else's hands.
00:09:30
◼
►
It's just something I get very nervous about.
00:09:32
◼
►
And as I've gone through this, that's
00:09:34
◼
►
kind of where I settled on it.
00:09:35
◼
►
One thing I did about the launch that I thought
00:09:37
◼
►
was also interesting worth mentioning
00:09:39
◼
►
is I did what I call a soft launch in the sense
00:09:42
◼
►
that I released the app to the update, to the store,
00:09:45
◼
►
before I started publicizing it, before I had people
00:09:48
◼
►
in the press talk about it.
00:09:49
◼
►
But the hope that I can kind of gradually work out,
00:09:52
◼
►
A, does my server infrastructure scale,
00:09:54
◼
►
and B, does my server architecture, does my sync,
00:09:57
◼
►
does all these little different components,
00:09:58
◼
►
do they actually work?
00:10:00
◼
►
Do they actually gonna do what I think they should do?
00:10:03
◼
►
And it was kind of fun when I hit update,
00:10:05
◼
►
release to the store, and then I can go into my server logs,
00:10:07
◼
►
I can tail all the production logs,
00:10:09
◼
►
and I can look at it and say,
00:10:10
◼
►
and just watch the first user create an account and log in,
00:10:14
◼
►
and make sure everything works.
00:10:16
◼
►
And then you say there's two people, and there's three people
00:10:18
◼
►
and this kind of gradually building process is great
00:10:21
◼
►
to making sure that everything worked.
00:10:23
◼
►
In the end I'd say it has kind of worked out really well.
00:10:24
◼
►
My server infrastructure that I was kind of building,
00:10:26
◼
►
I think I've talked about a couple of times
00:10:28
◼
►
where I have a couple of line nodes arranged,
00:10:32
◼
►
running rail servers with a Postgres backend
00:10:35
◼
►
and a load balancer in the front,
00:10:37
◼
►
and it ended up working great.
00:10:38
◼
►
And the experience I had,
00:10:40
◼
►
which I think I'd mentioned also,
00:10:42
◼
►
where I had practiced building up and tearing down servers
00:10:45
◼
►
was also really helpful,
00:10:46
◼
►
'cause I found that my original configuration
00:10:49
◼
►
had two front ends and it looked like I needed three.
00:10:52
◼
►
I was able to, in about 10, 15 minutes,
00:10:54
◼
►
spin up a new server, deploy it,
00:10:56
◼
►
sort of go through this sort of checklist,
00:10:57
◼
►
and in the end it worked flawlessly,
00:11:00
◼
►
and it's been great working ever since.
00:11:03
◼
►
And so that kind of a soft launch can, I think,
00:11:04
◼
►
be really effective if you can allow yourself to do that.
00:11:09
◼
►
One way to do that, even if you're launching a new app
00:11:11
◼
►
that you can kind of think about,
00:11:13
◼
►
is to set the app to release the night before
00:11:18
◼
►
you're expecting any kind of, sort of the big hit,
00:11:20
◼
►
the big publicity, the big promotion.
00:11:22
◼
►
You can release it the night before,
00:11:25
◼
►
and kind of trickle it out,
00:11:27
◼
►
maybe reach out to a few friends,
00:11:28
◼
►
kind of see if you can build a little bit
00:11:31
◼
►
of actual production experience
00:11:33
◼
►
without actually having to sort of push it out
00:11:36
◼
►
and then have this big sort of stampede
00:11:38
◼
►
of people working on your app, hopefully.
00:11:41
◼
►
It sort of avoids a bit of the problem
00:11:42
◼
►
if you think about it, like the mailbox
00:11:44
◼
►
or these apps that have been having all this weird,
00:11:45
◼
►
having to take strange tactics to avoid scaling problems.
00:11:49
◼
►
One of the things that I think about
00:11:50
◼
►
is how it's just like trying to sort of slowly
00:11:53
◼
►
the faucet on would be a great way to do it.
00:11:55
◼
►
So that's something that I've tried, seemed to work, and I'm pretty happy with.
00:12:02
◼
►
So where does that put me now?
00:12:03
◼
►
So that's the next thing that I'm working on then is feed wrangler, to turn that around
00:12:08
◼
►
and to hopefully ship three things in a week.
00:12:12
◼
►
And feed wrangler's kept going well, it's getting pretty close.
00:12:14
◼
►
And what I actually really liked about the timing of this is I've been able to prove
00:12:18
◼
►
and verify my server infrastructure approach.
00:12:22
◼
►
under a fairly reasonable load with my recipe book
00:12:26
◼
►
that I can now just immediately take that information.
00:12:28
◼
►
I've learned a whole bunch of lessons.
00:12:30
◼
►
There are some, even the simple examples
00:12:32
◼
►
are some of the things that I wasn't indexing
00:12:34
◼
►
some of my data correctly in the database
00:12:36
◼
►
and I've found these performance bottlenecks immediately
00:12:39
◼
►
when it's, when you have thousands of people
00:12:41
◼
►
hitting it all at once, they become much more apparent
00:12:43
◼
►
than when it's just you and your test data
00:12:45
◼
►
from, there's only so many concurrent connections
00:12:47
◼
►
that you can really simulate.
00:12:50
◼
►
And so when I started using this real data,
00:12:51
◼
►
I was like, oh, here's some indexes I'm missing,
00:12:53
◼
►
here's some things I need to tweak.
00:12:55
◼
►
I'll go into Postgres, do those changes,
00:12:57
◼
►
and then it's awesome.
00:12:58
◼
►
I use New Relic RPM server monitoring,
00:13:01
◼
►
which gives you essentially throughput,
00:13:04
◼
►
request per minute, response time, error rate,
00:13:06
◼
►
those types of information for a Rails app.
00:13:08
◼
►
I think it can work for a variety of servers.
00:13:10
◼
►
But I use it, I don't usually,
00:13:11
◼
►
I'm not necessarily gonna keep it in the long run.
00:13:14
◼
►
It's something that I tend to use targetedly,
00:13:15
◼
►
'cause any time you instrument your app
00:13:17
◼
►
and do a lot of monitoring,
00:13:19
◼
►
there's gonna be a performance hit
00:13:20
◼
►
that you're taking as a result.
00:13:21
◼
►
But right up front, it's always great,
00:13:23
◼
►
because it helps you quickly identify these bottlenecks
00:13:25
◼
►
that you can then very quickly attack.
00:13:29
◼
►
There was, I think, a post at a chart on app.net.
00:13:32
◼
►
There was this crazy call where I
00:13:35
◼
►
was able to take the average response time
00:13:38
◼
►
and cut it into about a third of what it was before,
00:13:41
◼
►
just by adding a few key indexes to the database.
00:13:44
◼
►
Any time you can do those kind of wins,
00:13:45
◼
►
it's just kind of amazing, because it
00:13:48
◼
►
feels like black magic.
00:13:49
◼
►
It's like what you had before was working, it was correct.
00:13:53
◼
►
You add a little bit of something to it,
00:13:55
◼
►
and then all of a sudden it works so much better.
00:13:57
◼
►
And so that was kind of exciting to see,
00:13:59
◼
►
to be able to experience in a production environment,
00:14:03
◼
►
and to know that was improving customers' interactions
00:14:06
◼
►
immediately.
00:14:08
◼
►
And so that's kind of where I am.
00:14:09
◼
►
It's been kind of a crazy week.
00:14:11
◼
►
I know I've gotten a lot of questions,
00:14:12
◼
►
but I'm not sure I answered them all.
00:14:14
◼
►
It's been kind of crazy in terms of stress and worry, too.
00:14:18
◼
►
So it's just kind of, if I didn't answer a question
00:14:21
◼
►
that you had about kind of these launches I've been doing,
00:14:24
◼
►
just the best place is probably gonna be email me,
00:14:26
◼
►
david@developingperspective.com,
00:14:27
◼
►
and I can try and loop back on another show,
00:14:29
◼
►
just to make sure I hit 'em all.
00:14:31
◼
►
But otherwise, it's a busy week, exciting,
00:14:33
◼
►
lots of fun stuff, and I really appreciate
00:14:34
◼
►
you listening to the show.
00:14:36
◼
►
So yeah, so that's it.
00:14:37
◼
►
As always, questions, comments, concerns.
00:14:39
◼
►
I'm on Twitter @_davidsmith, appnet @davidsmith,
00:14:42
◼
►
david@developingperspective.com.
00:14:44
◼
►
Thanks, happy coding, and I'll talk to you later.