In 2011 I had an idea for a tiny little Mac app called CommandQ.
I’m a terrible touch-typist and it just so happens that on U.S. style keyboard layouts, the Q and W keys are right next to each other. That means I’d often press ⌘W to close a window and accidentally hit ⌘Q – quitting the entire app instead of just the window.
So I spent a few hours each night over the course of a week or two and built a tiny little Mac app that intercepts your ⌘Q presses and stops the frontmost app from quitting. Instead, it shows a window with a timer. If you keep holding down ⌘Q until the timer finishes, it will go ahead and quit the app just like you wanted. But if you let go before time runs out, you can avoid a dumb mistake.
I named the app CommandQ and put it for sale on my company’s website for a few bucks. It was unlike anything I had built before. All of my other apps were more complex and primarily focused on helping web developers and designers do their jobs better.
But my existing user base welcomed CommandQ with open arms. I iterated and added a whitelist / blacklist feature to let you choose which apps CommandQ works with or ignores.
And then I left the app alone – I haven’t shipped a single update for it since mid-2012.
But, to my pleasant surprise, in the eight years since its release, my little utility app has gained over 20,000 customers!
It’s also brought me a lot of guilt.
The code was so old (pre-ARC Objective-C, targeted against the 10.5 SDK, and linking against OpenSSL), that every time I thought about trying to fix a few bugs, I got blocked just trying to get the project to compile on modern versions of Xcode and macOS. Not being able to add some requested features or even fix the one crashing bug just made me feel awful and even less motivated to actually improve the app.
So, CommandQ languished kinda-sorta-working for a number of years, but people still kept buying it and emailing to say how much they enjoyed the app.
With WWDC 2019 a few weeks behind us, it’s again that time of year where I spend my nights testing my Mac apps for bugs against Apple’s upcoming OS. And I quickly discovered that CommandQ is very much, incredibly broken on 10.15 Catalina.
What to do?
I don’t normally ever suggest a rewrite of a working app, but with CommandQ being such a small codebase, I figured why not? And spent the next week rewriting it with Swift and modern macOS technologies.
I’ve fixed all the known bugs and crashers, added the ability to prevent accidentally closing windows (⌘W), and pushed the app through Apple’s notarization process as well.
If you’re an old CommandQ user, I hope you enjoy this new version for many more years to come. You’ll be able to upgrade to version 2.0 for a one-time purchase of $6.99 – no subscriptions here! Check your registered email next week for the coupon code I’ll be sending to claim your discount.
With last week’s WWDC news announcing that Catalyst (Marzipan) is now an official thing, there have been a metric crap-ton of Twitter Hot Takes™ declaring UIKit the one true way forward.
I’m not going to debate that.
Instead, I just want to point out that not everything in computing revolves around a 44pt tap target by highlighting a few amazing Mac apps from oft-overlooked developers who do a phenomenal job adhering to the very best parts of macOS while continuing to push the platform forward.
First up, Acorn by Flying Meat. For $29, an absolute bargain, you get a top-notch, native image editor designed exclusively for the Mac that is sure to make ex-Photoshop users feel immediately at home. It’s a first-class Mac citizen, not some cross-platform Frankenstein, which means it opens lightning-fast, is easy on your battery life, and can take advantage of the latest graphics tech that Apple offers.
I use Acorn almost every day for editing images before I drop them into my Xcode projects and for optimizing photos I post to this blog. Is it as powerful as Photoshop? No. Of course not. But in the many years I’ve relied on Acorn (as a power user, not as a professional designer) I can’t remember a single time I’ve needed to reach for an Adobe app.
It’s a prime example showcasing how a solo developer can build an outstanding app when they take full advantage of Apple’s powerful frameworks.
Anesidora is a native Mac app for listening to Pandora.
The streaming music giant has long-offered a pretty good iOS app, but only recently launched their Mac version. Unfortunately, it’s an Electron turd. (Man, I wish I had coined that phrase.) Luckily for you and me, Adam Różyński has built this wonderful app directly on top of Pandora’s API.
What I love most about Anesidora, besides the beautiful UI, is how well it integrates with all the various macOS nooks and crannies. You can see track changes in Notification Center, assign global hotkeys, Apple’s keyboard media keys do the right thing, and it will even pause the music if you take an AirPod out of your ear.
And because it’s a real Mac app, there’s no need to fire up a full instance of Chrome and Node just to play some music. Right now as I’m typing this and listening to Talking Heads, Anesidora is using 92MB of RAM and virtually no CPU. For comparison, Safari, idling in the background with no windows open, is using 105MB.
I’ve writtentwice about DEVONthink recently, but holy damn do I ever love this app. It’s been around for years – I’ve been a customer since at least 2009. It’s where scanned copies of all the documents that would normally be in my fireproof safe are stored, along with any piece of paperwork I might need to refer to in the future, tons and tons of reference material, archived bookmarks, and more. And whether PDF, image, or what-have-you, it’s all indexed, made searchable, and synced across every Mac and iOS device.
DEVONthink has a truly deep and powerful feature-set. But the reason I want to highlight it in this post is because it’s a perfect example of how you can use AppKit to build a dense, information-rich, highly usable interface. UIKit is wonderful for its simplicity, discoverability, and ease of use, and you can certainly design powerful, professional apps with it, but that’s not its default state. Not even on iPad. AppKit, however, naturally lends itself to concurrent areas of focus and visual hierarchies. You can see more of your work at once and do more with it. Part of that, of course, is that AppKit can run on giant screens compared to what UIKit has traditionally been constrained to. But it’s also a matter of a different philosophy between the two (competing?) frameworks.
Fantastical is the calendar app that Apple should have shipped with macOS. Flexibits goes beyond the basics and shows how powerful a pro version of Apple’s consumer-focused software can be.
Whenever I open a new Mac app, the first two things I do are to look at every menu item and then explore all the settings available in Preferences. Nothing gives me more joy (or sick pleasure) than hitting ⌘+comma and seeing a big, beautiful Preferences window with multiple panes full of fiddly settings I can tweak to my liking. I’m not advocating that developers should provide a switch for every option they were too afraid to make a decision about – sane defaults are a good thing and there’s paralysis in choice, etc – but flexible third-party software is a hallmark of the Mac experience.
Fantastical takes the solid foundation Apple built into Calendar.app (née iCal) and extends it for power users in the ways indie developers are famous for.
As a geek first, a developer second, and someone who just wants to get shit done third, I love how scriptable macOS is – how automation is part of its DNA.
At the lowest levels you’ve got full access to a Unix environment with Bash (haha) and all the other standard scripting languages and tools. (For now.)
And at the graphical level you’ve got AppleScript and its friendly cohort Automator as well as the Accessibility frameworks. The former allow novice users to bend the system to their will without having to be a real programmer, while the latter gives developers powerful means to manipulate, control, and extend other apps in ways the original developers would never have thought of. (Love OmniFocus? Wait til you hear how it began.)
Keyboard Maestro is a shining example of a best-in-class automation tool for Mac. No matter how I try and describe the app, I’ll be doing a disservice to how insanely powerful it really is. Any time I come across a repetitive task, or wish another app behaved in a different way, or wondered if I could connect this with that, chances are, there’s a way to do it with Keyboard Maestro. It’s probably best I just let the expert tell you how it’s done.
I love my phone. I love my iPad. The watch is pretty great and tvOS is tolerable.
But the Mac.
Wow, did they get a lot of things right 35 years ago. It just fits how my brain works.
I’m not afraid of change. I don’t care if I build my UI with drag and drop, purely in code, or with a whizz-bang new DSL. What matters to me is the end result. And after a decade of near stagnation, I want to see macOS pushed forward in bigger and better ways.
Taking an iPad app and adding a menubar, sidebar, mouse support, and even multiple windows may be fine for Twitter, but it’s not going to cut it for end users who expect a level of power, finesse, flexibility, and soul that the Mac exudes. At least not in the Catalina release.
Steve told us there will be trucks. And there will be cars. It’s OK if they’re not the same. I know which one I want to be driving.
And across those two domains I basically have just three email addresses. [email protected] is my primary email address that I migrated to when I switched away from Gmail five years ago. And then there’s [email protected], which was originally my customer support address but has since been (mostly) replaced by [email protected].
However, one of the really cool things you can do when you accept email at your own domain name is a catch-all address. This means that [email protected] and [email protected] will be delivered to me.
This is great because I can easily create one-off or throw-away addresses like [email protected] or [email protected] that I can filter or block entirely. (You can also do this with Gmail by using [email protected]. Unfortunately, because some web developers are stupid and others are outright malicious, many websites will reject emails containing a +.)
The downside is that spammers are just bizarre. I’ll get random spam sent to [email protected] and [email protected]. As well as seemingly-possibly legit messages sent to [email protected]. (An address I’ve never used, so someone is obviously trying to correlate names to domains.) Its clear some spammers are just blindly sending to random addresses. While others are from bots (people?) trying to intelligently guess possible addresses.
Luckily, FastMail’s spam filters are great, so I don’t ever see most of that junk. But a lot of the more legitimate looking ones do make it through. How do I filter those out?
I could simply just block anything not sent to my real address, but I like having the option of using the catch-all feature as I do make use of it quite frequently. Another option might be to setup a whitelist of allowed recipient addresses, but that would quickly become a pain to remember to update anytime I gave out a new email.
The solution I came up with is simple. (It’s hardly innovative, and I doubt I’m the first person to come up with this method, but I thought it worth sharing.)
I created a rule that moves any email not addressed to one of my primary emails to a folder called Aliases. This serves three purposes:
It allows me to continue using my domain name’s catch-all email address feature, but keeps the truly bizarre as well as possibly legit spam from clogging up my inbox.
Much like SaneBox‘s @SaneLater feature, I can check-in on this other folder at my leisure because I know that any email that ends up there is either unimportant or plain spam.
It lets me quickly see at a glance and setup a rule to block any repeated, bogus emails. If these types of emails where mixed in with the ones sent to my real address in my inbox, it would be harder to spot the invalid catch-all ones – especially on mobile devices which typically don’t show the full to: address.
Like I said, this isn’t exactly rocket-science. But it’s a nice improvement I made a few months ago, which has saved me a good bit of time dealing with those extra obnoxious emails that slip through my spam filter.
First, in my last post, I said “I recently stopped using Pinboard as my primary bookmarking service”. I misspoke. I’m still using Pinboard to bookmark websites I want to remember as I come across them. However, I’m no longer paying for their add-on archiving service. It’s a great feature, but it had just a little too much friction for me to make genuine use of it. I like my new solution, which I’ll detail below.
Second, I just want to give a heartfelt shout-out to Pinboard for simply being an amazing example of a phenomenal service that a solo developer can build “the right way” over many years into a sustainable, profitable business without relying on venture capital. While not nearly as successful, it’s the same path I’ve tried to follow with my own business.
Anyway, here’s what I’m doing now.
With all of my previous bookmarks safely archived in DEVONthink, I turned my attention to automatically importing new ones as well.
I’m using the new version 3 beta of DEVONthink and discovered it has a new “Smart Rules” feature. (At least I think it’s a new feature. If it’s not, how its the world did I miss it for so many years?) Smart Rules are like the typical NSPredicate-based Smart Folders you see in other Mac apps such as Mail. But instead of simply showing you a filtered view of your data, Smart Rules allow you to perform a chain of actions on items that match your criteria.
Both Pinboard and Pocket offer RSS feeds of your bookmarks. And DEVONthink allows you to subscribe to a feed and import its items into your database.
So, I added my Pinboard and Pocket RSS feeds into DEVONthink, and then created a Smart Rule that runs whenever a new item is imported. The rule takes the URL of the new item, converts it into a .webarchive, and moves it into a pre-determined group for permanent storage.
The result is that I now have an automatic snapshot of everything I bookmark as it appeared at the time I saved it, which can be searched and retrieved via DEVONthink’s amazing full-text search engine, or exported as a PDF at a later date if I ever have the need. And with DEVONthink To Go, those archives are also available across all of my iOS devices as well.
After you’ve added your RSS feeds to DEVONthink, here’s a screenshot of the Smart Rule I’m using to do the archiving.