5 lessons from making my first native Mac app
Writing desktop apps is painfully dated, but the process was liberating
I was racking my brain trying to find a good project for January when I came across a tweet that set things moving very quickly.
January 14th:
This really resonated with me - I had the same problem on an almost daily basis since I build UI for clients and need to convert lots of PNG screenshots to JPG to send to them. Plus, I already knew how to build iOS apps so how hard could a Mac app be?
January 15th:
February 10th:
The good news is that it wasn't impossible - here we are a little over a month later and Photo Tamer is finally ready to launch (though it was rejected a couple times, but that's for my next blog post). But along the way I had to completely relearn the process of making apps for a new paradigm: the desktop. Here's the big things I learned in this project:
1. Writing Mac apps is like reading Shakespeare.
Except for you super-cool SwiftUI hipsters and Electron hackers, if you write a Mac app you're going to be writing the UI with Apple's Cocoa framework. Cocoa (aka AppKit) is, as you might be able to guess, the library that predates and inspired iOS's UI framework CocoaTouch (aka UIKit).
But Cocoa is to CocoaTouch what Shakespeare is to "Schitt's Creek." Sure they're ostensibly both in the same language and plots can only have so many shapes, but once you start digging in it's obvious that one of them is far older and carries the burden of that age when you try to stand it up in the modern world.
This shows up in little ways - like the messy verbosity of NSAlert vs the tighter block-based UIAlertController. (Tangent but NSAlert is seriously the worst. Try and tell me without opening the docs which of informativeText
and messageText
is the property for the title and the subtitle.)
But it also shows up in big ways - I had really taken for granted how easy it was to make complex animations in iOS:
// Fade pulseView down to half-opacity and back
// up to 1 over and over again with an ease curve
UIView.animate(
withDuration: 0.4, delay: 0,
options: [.repeat, .curveEaseInOut, .autoreverse]
) {
pulseView.alpha = 0.5
}
I won't even bother to include the Cocoa version of this as it's 15 lines long and is based on a 3rd party library (though you can catch a glimpse of half of it in the screenshot up top).
While Cocoa has the basics of CoreAnimation that would become this wonderfully powerful UIView.animate
, they're still the "v1" of these ideas. A lot of the tools (like view layers) are off by default and a lot of the features you expect, like being able to repeat an animation, are just missing. These little "missed connections" add up to taxing mental overhead, like reading a sonnet and having to glance down at the footnotes every 4 words.
2. Writing and debugging on device is wonderful
On the plus side, being able to write and debug on device is the best of both worlds from mobile and web development. Being able to press "run" and immediately be running without messing around with a simulator or cables is a breath of fresh air coming from mobile development. Meanwhile, having Xcode's "just works" debugger to tear apart misbehaving code almost makes up for all the other ways in which it just does not measure up to VS Code. Plus, if you're coming from iOS development, the freedom to build and run your code on your machine without digging in and sorting out provisioning profiles and test devices is a real "remember the good old days" moment of nostalgia.
This experience really makes me optimistic for a day when Apple brings us Xcode for the iPad, or for tools like the Chrome Debugger for VSCode finally get up to that "80% perfect" threshold of usability.
3. The knowledge you need is preserved in rumor and oral tradition
Writing for the desktop was tough because you had to carefully sort through the 100 Stack Overflow answers that are about doing X on mobile or web to find the 3 answers that are about desktop. But it's even tougher because you then also need to sort through those desktop answers to ignore the ones that are a decade old to find the one answer (if there is one) about the current APIs.
It's like you're a code archaeologist, digging through layers of confused programmers to try and understand the history of the frameworks you're using today.
The thing that was most clear sifting through this record is that things have completely changed in the last few years. Apple's "App Sandbox" security model completely blew up the game for desktop devs. The things that I thought desktop apps could do - like writing to disk freely - turn out to already be fading relics of the past. Apple is working to lock down desktop apps like they've locked down mobile apps and you have to accept this lockdown if you want to sell your app in their App Store. But the only way you'll find out what has changed and which tips and docs you should now ignore is in the shifting sands of our oral history preserved in Stack Overflow answers.
4. Desktop feels like a new frontier
In both good ways and bad, desktop feels like a complete wild west frontier. The good part of this is that because the gold rush for the last 10 years has been on mobile and web, the desktop ecosystem is woefully underloved. Apps and the innovations that power them are now 10 deep for every niche on mobile, but remain relatively sparse on desktop.
Plus, the freedom of desktop is wildly inspiring. I've found that escaping the little boxes we build around web or mobile apps has been revitalizing. I'm coming up with app ideas at an unbelievable pace because I'm no longer confined in the loop of "user remembers the app/site exists and comes to it." The app can instead live on their menu bar, or truly run in the background. It only has to choose to live in the normal window setup if that is what makes sense for it.
But it also feels like the wild west in the worst ways - a ghost town full of tumbleweeds. Even in Apple's own documentation, you're just as likely to run across outdated or broken tips like these instructions on how to get your app to launch at startup. They're just wrong if you are using Apple's new Sandbox controls, and they just never bothered to update them. Indeed, the most popular medium article on the topic doesn't work either, and the Apple forum thread talking about this ends with an Apple engineer telling people they need to get a fresh install of OS X and try their apps on that. You have to trek across the desert of old and abandoned guides and tips to find the few oases like this fantastic Github project that seamlessly enables launch-at-login for your app.
5. Beautiful is harder on desktop
Part of this is because of the age of Cocoa as a framework and the issues I mentioned above about things like a lacking animation framework, but I think even accounting for that it's harder to make an app "beautiful" on the desktop. In the same way that you might be able to learn how to make a pretty good postcard-sized sketch but find it doesn't translate into being able to do a 4x6 foot portrait, the visual vocabulary we use to make our apps "pretty" on mobile and web don't quite translate to the conventions of desktop.
I think this is something that will get better as we swap Cocoa out for more modern frameworks and that I will personally get better at as I practice, but until then I will just be pained because my apps look more like Word Perfect 97 than they look and feel like Apple's Notes app.
But the future looks brighter
Like I hinted at back at the start of #1, the future of Mac apps is starting to shake off the dusty, archaic Cocoa framework. Whether it's via web-on-desktop tech like Electron (note to self - love/hating on Electron can be its own blog post too), or through exciting shake-ups like Apple's SwiftUI and Catalyst frameworks for bringing even more of the iOS and Web's innovations back to Mac, things are about to start moving much more quickly on desktop.
Photo Tamer isn't going to be paying my rent anytime soon (though, dear reader, may I just say that it's an astoundingly good deal at just $2.99 for a powerful photo converter and resizer and you should consider buying it right away 😉), but it has opened a new door for me at the exact right moment. As these new frameworks make desktop more accessible to more developers and as people are spending more time than ever at home with their full computers, it feels like the perfect time to be here thinking of new and exciting ways for us to bring our small app experiences to the bigger screen