Angelo Stavrow [dot] Blog

Missives and musings on a variety of topics.

This post is part of a series about rewriting my iOS app, Per. Per is a price per unit comparison app with a bunch of neat convenience figures, but it hasn't been updated in years, so I'm rewriting it from scratch to eliminate a bunch of technical debt. Just because it's not an open-source app doesn't mean I can't share what I learn as I go!

See the rest of the series here.

Tabula Rasa

Rewriting Per from the ground up is going to be a learning experience, and I'm going to take this opportunity to write about the process as I go. I'm aiming to make one (relatively) small change per day, with the goal of having a functional MVP by the end of February 2020 that's not using any custom design work — i.e., using built-in animations, colour palettes, fonts, and icons.

Working this way —without custom design work— means that I can focus on design patterns, unit testing, and so on, moving quickly without getting blocked on UI decisions. It also de-couples the development work (which I'm doing) from the design work (which someone else is doing), so that we can move through this iteratively, but without deep dependency on each other's progress.

I should pause here to define the functional MVP. By the end of the month, I want to replicate the functionality of Per in its current iteration, plus one more feature, which means it should:

  • Provide a quick, easy way to compare price per unit (existing feature)
  • Handle unit conversion automatically (existing feature)
  • Allow simple arithmetic when entering price or quantity (existing feature)
  • Expand the number of compared products from two to “unlimited” (new feature)

So, I started with a single-view iOS app, added the bundle identifier, and then started ripping out Main.storyboard from everywhere. Thankfully, my podcast co-host Frank Courville posted a great article on the topic last month to follow.

View controllers all the way down

I also started implementing a “layered view controller” concept presented in another article of Frank's — this uses coordinator view controllers, that manage container view controllers or wrap context view controllers that are composed of content view controllers. Read Frank's article, and be sure to download the sample app. You'll need to sign up for his newsletter, but I've been subscribed for a couple of years now and it's all been high quality articles on iOS development.

Per isn't an especially complex app, so this may seem like overkill. I'm going to be building this iteratively, though, and while this does mean I'll be creating several view controllers, this method will keep things small and loosely coupled.

Today was spent setting up this hierarchy.

Specifically, I created a simple top-level Product List coordinator view controller that sets a UINavigationController as its root view controller, which in turn embeds a Product List context view controller.

That context view controller wrap a Product List content view controller that implements UITableViewController. Why a table view controller? That feels like the fastest way to add a list of several products for comparison. I didn't yet set up any delegates or data sources for that table view, nore did I create a Product detail view controller or any way to navigate to it.

I'll kick off work on that tomorrow by creating some very basic models.

#per #perRewriteDiary #ios

Discuss...

One of my goals for 2020 is to share more, and one of the ways I intend on doing this is to take photos more often and share them on Flickr. There's even a daily-photo challenge on Micro.blog to help kickstart that challenge. And since I can just plug any RSS feed into Micro.blog to pull in content, and I can generate Flickr RSS feeds from a given tag, we're golden! Just add the Flickr feed to Micro.blog, post one photo to Flickr daily with the tag photoblog, and it'll get shared to Micro.blog (which then cross-posts to other platforms, like Twitter). Great!

Except, right now, Flickr search is broken, so getting a feed of my photos filtered by tag returns… nothing.

But! I can create a Glitch app that uses the Flickr API to pull in my photos, filter them by tag, and generate an RSS feed of them. Yeah, that duplicates the functionality of Flickr's own built-in feed services, but hey, they're broken, and I can make this pretty easily, right? And once search is fixed, I can just turn off the app. It'll be a fun learning experience.

I'm in the middle of working on some other stuff right now. Those projects are far more important and/or time-sensitive, so I add this Flickr feed-generator app to my Someday/Maybe list in OmniFocus; it's neither important nor time-sensitive. Someday/Maybe lists are a collection of “nice to haves” — a backlog of project that you maybe want to do, someday.

A better turn of phrase is the side-project graveyard, as we call these lists on the show.

Inflating the numbers

But the nature of this list, for me, is a little bit more insidious than that. As part of the weekly retrospective that I do, I go over my Someday/Maybe list, automatically bringing every one of those projects to the front of my attention. This routine signal boost makes sure these backlogged projects are kept on the radar.

I have never actually promoted anything from my Someday/Maybe list to an actual project that I tackle.

I have also almost never deleted an idea from my Someday/Maybe list, except during my annual purge.

I have demoted actual projects to my Someday/Maybe list.

I've been thinking about what this does to me. Here's this list of projects that aren't important or urgent enough to take on, but I'm reminded of them week after week. Hey, my system says, don't forget about these things. And so, as I go through my week, my planning is distracted by these ideas. I could be more ruthless about deleting them from the list, but, the fact is: I'm a digital hoarder.

So, today, I deleted the Someday/Maybe list in OmniFocus.

Organic Growth

For myself, it's probably better to ignore a new idea. I'm too easily pulled off course by the promise of something new and shiny. Going forward, if I think of something interesting to make or do, I'm going to push it aside.

If it eventually comes back, that'll be interesting. But that's not good enough — maybe I turn the idea over in my head a bit more, and write it down in my journal where I'll only see it maybe another couple of times in the year, and then I'm going to push it away again.

But if it comes back to me a third time? That's probably a sign. That's maybe where you decide to create a project for it, either to tackle right away or sometime in the future. It's planned, and it's considered.

The ideas that pester you, that won't leave you alone, those are probably the ones you want to pay attention to. And you can't tell which ones they are, if you're pestering yourself with every idea you have.

More TK.


Interesting reads this week

  • Tuning the distraction machine — Tanya Reilly: Our smartphones default to Do Not Disturb being off. Peel away the double negative and consider what this actually means: our smartphones default to Disturb being on. As I'll ask anyone who'll listen, what do you think that does to our psyche? (Yeah, I'm real popular at parties.)
  • Why Software is Slow and Shitty — Robin Rendle: “You don't need a plan to make a beautiful thing” is something I need to remind myself of again, and again, and again.

#projects #focus

Discuss...

From Intelligencer:

If you let products spoil, or you decide you don’t like them anymore halfway through the box, or if you forget what drawer your huge package of batteries is in, then you’re not getting as much value out of your bulk purchase as you had planned. Your effective investment return is likely to be negative; you would have been better off paying more per unit to buy less.

— Source: Buying in Bulk: When Is It a Mistake?

It's this philosophy of “cheaper isn't necessarily saving you money” that drove the development of Per, my little price-per-unit utility calculator. From the marketing copy:

Just because you’re getting more for your money, doesn’t mean that it’s a good buy. Maybe you’re not sure you’ve got the space to store eighty rolls of toilet paper. Or that you can get through sixteen heads of lettuce before they spoil.

Per tells you just how much more you’re getting for your money, so you can make those decisions confidently.

(I'm still planning updates for the app. Stay tuned for V2.)

#behaviour #per

Discuss...

Monday morning, I got up a little earlier than usual, and —despite being pretty tired— was looking forward to getting back to the gym. I'd taken a week off to get over a cold, and while I'd have to reduce the weight I was lifting to avoid soreness, it felt really good to have recovered enough to get some exercise.

In our apartment, everything was ready for my triumphant return, too: my gym clothes were neatly folded and ready to go, the coffee machine was ready to brew, and I had all the ingredients I needed for a quick pre-workout snack (9-grain toast with orange marmelade and peanut butter, if you must know).

And yet... I found myself having a very hard time getting out the door.

Why? Because since Saturday night, we'd gotten a bunch of freezing rain followed by snow, and the thought of having to de-ice my car felt like a huge hassle that I didn't want to deal with.

Sorry, let me rephrase that: it was a huge hassle that I didn't have to deal with.

In other words, I'm feeling lazy about going to the gym because I'm allowed to be lazy about it. When you think about it, skipping the day's workout didn't have any real consequence (unlike, say, skipping a day of going to work), but it also had no real, immediate reward, either (unlike, say... going to the guitar shop to buy a new guitar, I dunno).

So there I was, yanking on door handles trying to get into my car, realizing that it's surrounded by hardpack snow that'll require going back up to my apartment to get a shovel, and watching the available time for a workout that morning dwindle.

You can bet that if I had to get into that car to drive to a job, or to pick up a new Telecaster, I'd have made it happen. But having neither the forcing function of work nor the reward of made-in-California twangy goodness, the motivation to get into that car and on my way to Do The Thing™ was approaching zero, and that I'd have to rely on good ol' discipline.

And really, all I could really think to myself was: Montreal winter: 1, Discipline: 0. Also, that my bed was probably still pretty warm.

Well, it was worth a shot.

The thing is, discipline isn't the kind of thing that goes from zero to one easily. Discipline is built on routine. On habit. On showing up, day after day. And sure, I try to go to the gym fairly regularly, but after two and a half weeks of sleeping in because of holidays and then illness, my routine had been broken.

When you're trying to kick off a new habit, you can rely on your motivation to get started, but you'll also want to stack the deck in your favour, too. Setting yourself up to develop discipline can be made easier by two things: minimizing the friction between where you are and where you want to be, and rewarding yourself for actually doing the thing you're trying to make a habit of.

It's hard to look at a protein shake as a reward for going to the gym. There's pretty much nothing good about going to the gym, in my opinion, beyond eventually witnessing some progress. So for now, I need to focus on minimizing friction. I thought I did a pretty good job of making sure that I was ready to go, but really I failed to account for the biggest obstacle: fighting the elements.

How could I have made that hurdle lower (i.e., set myself up for success)?

I know that getting into the car afterwards dumping of freezing rain and snow is a lot harder than just dusting off some snow, so I could have instead taken public transit and/or walked. This multiplies my travel time by a factor of about four or five, and nearly doubles the amount of time I have to dedicate to my workout. That extra time commitment then eats into the other stuff I do in the morning, which is the opposite of a reward. Knowing myself, that isn't going to happen.

I could have instead gone out and cleared the ice and snow on Sunday afternoon, so that the car would be ready to go Monday morning. In fact, I was telling myself that I should exactly that, after a morning of chores. And if I needed to drive to work or go buy that Tele, you can be sure I would have found the energy to do that. But instead, I mostly convinced myself that it probably wasn't too bad and I could leave it to the next day.

There's a word for this: procrastination. But that's a topic for another day, because I think there's a more subtle and interesting takeaway here.

What fascinates me is how good and positive I felt about what Monday morning would look like, as Sunday evening crept towards bedtime. Somehow, I'd already done the calculus that I was going to have a tough time getting where I needed to go. And still, I was able to push the impending failure outside my door to the back of my mind, and instead point to all the things I'd done right in my immediate environment to slam dunk a home run.

(Clearly, I'm not a sports person.)

Yes, skipping the gym is trivial, but it points to something bigger: the ability to tell myself that everything's great and trick my mind and body into believing it when there's obvious evidence to the contrary. This is powerful, and insidious, and probably invades other, more important things. I sometimes describe myself as a “cautious optimist” — but maybe I'm not as cautious as I think.

This is probably also why reflection and introspection have made such a difference in my life. There are only so many times you can fool yourself when you're faced with the same evidence week after week. That gut-check is something I'm doing more and more of in my weekly retrospectives as I focus on less and less, and while I still have a long way to go, being more honest with myself about the time, energy, and attention I have available is already paying off.

More TK.


Interesting reads this week

I'm trying something new, where I'll share two or three articles that I read this week (they may be relatively new, or really old — so long as I read them this week).

  • Thinking in React Hooks — Amelia Wattenberger: Not only is this a fantastic explainer of the mindset shift required to make the most of React Hooks, I really love the interactive presentation of the post's code examples. This isn't the kind of thing that can be done anywhere but on one's own website. (H/T: Keith Kurson)

  • The Wages of Productivity — Anne Helen Petersen: I first became aware of AHP from this interview on the Hurry Slowly podcast. The fetishization of productivity is invading our leisure in ways that not only exhaust us, but —more dangerously— fuel classism and further divide our society. (H/T: Jocelyn K. Glei's newsletter)

  • Brainstorming: how I start a project — Brett Terpstra: I'm fascinated by the idea of mind-mapping (and have been purchasing MindNode's upgrades for years now), but for some reason, it's just not something that I jump to when I want to brainstorm on and/or flesh out a project. I think that's because I've never been sure how to start, exactly, and this article (along with BT's related mind-mapping posts) has given me some ideas.


PS: No guitars were purchased in the writing of this post. Unfortunately.

#behaviour #progress

Discuss...

Despite having fifty-two weekly retrospectives over four notebooks to look back on, I didn't write up any kind of “2019 In Review” post here. I did spend the morning of New Years Eve writing up an annual retrospective, though, as discussed in [episode 17 of Make Before Break]; I just didn't share any findings and insights.

Read more...

I was invited to chat with [Anil Dash] about tech and self-care on the Function podcast's season 2 kickoff. Function examines the intersection of tech and culture, and I'm grateful to have been invited to share my thoughts.

Read more...

A couple of months ago, [Glitch] CEO [Anil Dash] got to interview Mindy Kaling at Twilio's [SIGNAL conference]. We built an [app] that let people text in their questions for Mindy, and it added a lot of fun interactivity to their chat!

Read more...

This site runs a customized version of [Indigo] — essentially, a different colour palette and some custom styling for the [Updates] page. Because of this, it's always been a bit of a headache to update to the latest version of the theme. No more! I'm happy to announce that you can now easily import custom CSS into Indigo.

Read more...

It's been over 10 months since I [released] my theme for Hugo, called [Indigo].

Some changes have been made since launch, but it always seems to take so much longer to build out new features or fix bugs than I'd like, and a recent [breaking change] in Hugo 0.57 (temporarily rolled back in 0.57.2) that I have to [fix] really drove that point home.

Read more...

Debugging code can be either very rewarding or extremely frustrating. If you're feeling frustrated, here are a couple of tips that will make it easier for others to help you.

Read more...

Enter your email to subscribe to updates.