Apps · Practical · Software Dev

UX teardown: make your own guides in  Maps

I always found the “favorites” feature in Apple Maps to be too general and dissatisfying. I quit using that feature once I had 48 places saved all across the world. 🤷🏻‍♂️

Before that, I saved specific lists of places in Google Maps, but found their mobile app to be cluttered and confusing. 😖 So I gave up and started using Trello.

Trello is cool for some things like trip planning and small projects, but it did not scale well and didn’t handle lists of places well. So I gave up on that. 😢

 Maps guides

I’m happy to have just discovered that you can save your favorite places as “guides” in Apple Maps. Finally, this is genuinely useful!

I just set up my own guide for coffee places open early for when I’m looking to get our early. Quick and easy and right to the point! 🤩. I can immediately see all the places I saved and their hours. Check it out for yourself! (This is my own personal guide, so it’s focused on Austin, TX.)

Of course this guide automatically syncs to my iPad and Mac as well. ✅

Rechecking Goole Maps

Forgive me if I sound like an  fanboy, but out of genuine curiosity I went back and I did the same thing in the latest Google maps. It was a bit painful. 😢

Notice how the “main” screen is oddly not a map but more of a picture of a cup of coffee and therefore not useful to me.

And even when I drilled into an actual map view, the places I care about are unlabeled in favor of (1) a notification that HEB has an offer and (2) the Texas Capitol and Congress Ave. Bridge exist. Again, not useful.

I just want to know where a coffee shop is open at 7am! Now that would be useful. 👆

Software Dev

The what, why, and how of the RIBs mobile architecture

Continuing my mobile architecture kick, let’s look next at RIBs. In this case, RIBs is not a delicious, slow-cooked entrée but rather a software architecture that Uber developed a few years ago.

Why RIBs?

RIBs lets Uber’s 200+ mobile developers knock out features quickly without stomping all over each other.

The original design worked well for the first three developers. (via Uber)

Back in 2016, the Uber team had just expanded from three mobile developers several hundred developers. And the app’s design did not scale well to that large of a team. From both a UX/design perspective and a technical perspective, it became difficult to add features. Citing “quite a few examples of, you know, pretty bad UI”, the design team bravely demanded a rewrite.

The design team came in and said, you know, ‘We probity have to redesign the whole application.’… Everybody was super concerned.

Classic engineering understatement

The Uber engineering team resisted the rewrite (which can be nightmare for a large app) for a year, but eventually came around to its necessity. So they defined a few goals for the new design (99.99% reliability, scaling to ~1000 developers, …) and experimented with that they knew – MVC, MVVM, MVP, and VIPER.

But nothing worked. 🤦🏻‍♂️

The problem is that all these architectures are based around the view, and if you base everything around the view, everybody has to integrate at one point, and that becomes a mess at the scale that we have.

The state tree solution

So they came up with a fresh idea, which was to model the whole app as a state tree. Much to their surprise, it worked really well. 🤷🏻‍♂️

We haven’t found an application that you couldn’t model with this very nicely.

A special architecture subteam spent six months reworking some “super ugly looking” core use cases and then turned the rest of the team loose on the new architecture.

Now we have RIBs and the modern Uber app.

Whoa! That looks too easy! (via Uber)

But how does it work?

A RIB is a combination of Router/Interactor/Builder (plus Presenter/View, but I guess “RIBPV” doesn’t sound very good). Each RIB represents a state of the app, which can have sub-states as children.

For example, the root of the tree has two children: logged-out and logged-in. Every RIB under logged-in can safely assume that the user is logged in, and it has an authenticated user token 🔑 to prove it.

RIBs can present themselves hierarchically on top of each other on the screen. Some RIBs just do background support don’t show themselves at all.

No auth token for you, left side. (via Uber)

For more…

Pretty cool, eh?

Okay, I’ll stop here since this is a conceptual overview (aka a teaser) and not a tutorial. ✋ For more details, see the original Uber presentation below or try it yourself.

Up next in the architectural series, we’ll attack The Composable Architecture, which is responsible for at least one cool game and, like RIBS, has a concrete implementation rather than just a bunch of vague ideas. 🙏

Software Dev

“What you can see here is that I was learning…”

I love this post from

👉 Things I Made That Sucked

Not only does he detail the interesting stories of some old apps he made, but also the valuable lessons learned from each app that he shipped.


Aim first, then shoot. “Ask yourself why you’re doing what you’re doing and channel your excitement into less action and more thinking before you fire away.”

Pace yourself and don’t complicate. “Take time to learn about design and holy moses don’t toss in an open source project just because it’s shiny.”

There is no overnight success. “Always remember that character is carved out rather than instantly created. Each of these misses can eventually add up to a win.”

My own lessons

Applying the same thought process to my own old sucky apps, here is what I come up with…

Where in the World is Santa Claus?

Ignorance is bliss. I genuinely thought it would be easy to make an augmented reality Santa tracker as my very first iPhone app. Who cared that built-in AR support on the iPhone was years in the future?

I understood that I’d have to learn Objective-C and Xcode as I went. However, I did not appreciate how much there was to learn about location APIs, motion APIs, audio APIs, audio editing, 2D animations, CoreData, the State Pattern, linear algebra 🤯, the terrors (at the time) of shipping in the App Store, plus legal/privacy matters. Also why not translate the app into six languages, starting with Spanish?

And all just to see Santa blink on your screen when you pointed your iPhone north. 😆

My blissful ignorance allowed me to jump in fearlessly and forced me to conquer a mountain of challenges as I went (or quit).

This app only ever sold a few hundred copies but was a goldmine of experience and made me a mobile developer.

Bedtime Balloons

Simpler is better. App #2 was more useful and less technically challenging than the AR Santa app. Bedtime Balloons let me get into some fun art and more interesting animations. Plus this app actually made a difference in at least a few people’s lives.

Third-party frameworks can kill your app. At the time, there was no standard 2D animation engine for iOS. SpriteKit was not a thing yet. 🤷🏻‍♂️ So just like the Santa app, I built the animations around the very nice Cocos2d engine, which would eventually morph and evolve and… break my app. 🤦🏻‍♂️ Yeah, I could have rewritten my app, but again only selling a few hundred copies, I chose to avoid all the sweat and tears and just move on.

Continuous Math Cards

Be practical. I never expected to sell many copies of my barebones but highly configurable math flashcards app for kids.

Written quickly in the new (at the time) Swift language, the app was alright. 🤷🏻‍♂️ But it worked for me professionally. My next step would be a full-time day job as an app developer, which had long been my dream.

Software Dev

Why asynchronous programming is (was) hard

One of the most difficult things about mobile development is asynchronous programming, which means doing different things at the same time. This is not the normal flowchart-style sequence of traditional programming.

Weirdly enough, with Swift completion handlers, an asynchronous function exits before it finishes. Or if you’r not careful, it might never finish at all. 🤯

Oh no! This is entering annoying quantum mechanics territory. 😭

If none of this makes any sense to you, then you’re not alone.

All of this is why I love the following video from WWDC 2021. Nate spends the first eight minutes showing how downloading an image and generating a thumbnail quickly becomes “verbose, complex, and even incorrect” in traditional Swift programming. (Side note: I like how Nate apparently worked hard on his hand gestures as well.)

The payoff: Nate then explains how async/await will let you write asynchronous code basically like “regular code.” 🤩

Software Dev

Mobile Native Foundation: Developing Large-Scale Apps

Writing apps for a large organization has its own unique challenges.

Large teams require that you collaborate in complex ways while keeping quality and delivery speed high. It’s not straightforward, and it makes the days of knocking out an app on your own look fun and easy, if somewhat solitary.


It’s not just about “data structures and algorithms” or any of that Computer Science 101 stuff at this level.

The Mobile Native Foundation is a new organization that focuses on large-scale app development issues for iOS and Android.

It’s mostly just discussion groups right now, but they have contributions from people at large companies with apps you know and respect such as Lyft and Spotify.

The discussions cover relevant topics ranging from organizational (such as Encouraging and enforcing testing), to design (Building Modern UI), to technical (Splitting an app into modules).

👉 This site also reminds me of a book on large-scale app development that I’m currently working through: Building Mobile Apps at Scale.

Via iOS Dev Weekly.

Software Dev

From Four Wheels to Two – Lyft Engineering

This is Lyft’s approach for adding a major new feature to their app. ->

I heard about this on the iOS Dev Discussions podcast.


  • Stay simple and lean
  • Reimagine over reinventing – ““Is it faster to rebuild this or reuse this, and what will we regret later?””
  • Launch what matters

Feature flags, feature modules, launching early and iterating small, facing questions they didn’t have answers to until they did some real world experimenting and iterating.

Love this…

Every new feature is a chance to start with a clean slate, and it’s often tempting to immediately build for scale. We all want our products to launch to massive fanfare and usage, but more often than not, the path to success for new features is slow and steady. With steady growth in mind, we designed our first architecture to support exactly what’s needed for our first product iteration, and nothing more


The computer scientist in me was angry, but when the datasets are small enough, reasonable tradeoffs can be made in the short term without sacrificing the user experience. When choosing the “rewrite” approach, it’s important to be confident that the code will stay simple and easily explainable. In this case, the algorithm wasn’t perfect, but it worked reliably and quickly.

Software Dev

Building reliable apps on unreliable networks – Superhuman

This post describes how we detect and communicate network status as part of making Superhuman the fastest and most reliable email experience in the world. Our previous post described an offline…
— Read on


In this case, they detect online/offline state in a web browser mostly for the purpose of communicating that state to the user so they can tell what is going on.

The web app keeps track of network state. If a network request times out, the state is set to offline. Then it polls every 10 seconds to see when the network comes back online.

This approach seems alright for a webapp, but in a mobile app I think we’d avoid polio every 10 seconds to see if the app is online. Perhaps poll on the next natural network request instead, or trigger on events such as view-will-appear or return-to-foreground.

Software Dev

How to Design Offline-first Approach in a Mobile App – net guru

Nowadays, almost everyone has access to either wireless network or the mobile network. Does it mean that we shouldn’t be concerned with the availability of network when making mobile apps?
— Read on

Great overview of building an app that works offline first as a means to a great user experience.

The offline-first approach is not the universal solution to every problem you will experience with unreliable network connectivity – it heavily depends on your app’s requirements. It’s more like a design approach that lets you focus on what really matters to your end user: a robust app with a great user experience.