vi.
Introduction
Written by Marin Bencevic
Since the introduction of the first iPhone, Apple has been building and maintaining two parallel operating systems: macOS and iOS. Both are based on Darwin but optimized for different types of interaction. As time passed, the apps and features on macOS and iOS started to converge slowly. It became very common for developers to create and support apps that ran on multiple types of Apple devices, from iPhone, iPad and Mac.
The trouble with building an app that runs on both iOS and Mac is that you need to learn and use two different UI frameworks: UIKit
and AppKit
. And, therefore need to maintain two distinct codebases. While it is, of course, possible to share some code using frameworks, the entirety of an app’s UI-related code effectively needs to be done twice.
With the arrival of Catalyst, it’s now possible to bring an iPad app to the Mac using a single, UIKit-based codebase. With minimal effort, your iPad app can function quite well on macOS, and with a bit of additional effort, can become a world-class Mac citizen.
What is This Book?
Throughout this book, you’ll work with on a sample app called Journalyst. Starting with a basic iPhone-only app, you’ll learn how to first enhance for iPad with some of the features that apply to both iPad and Mac. Once your iPad app really shines, you’ll take the next step by optimizing it to run on Mac using Catalyst. Finally, you’ll learn how to build and distribute your new Mac app to both the Mac App Store and independently.
Who is This Book Written for?
This book is for you if:
- You have an existing UIKit iPhone app that you want to bring to iPad or Mac without much hassle.
- You have an existing UIKit iPad app that you want to bring to Mac.
How to Use This Book
This book is organized into three sections, carrying you through optimizing an iPhone app for iPad, then bringing that iPad app to Mac, and finally distributing the Mac app. It’s best read linearly, but if you already have a great iPad app, you can jump straight to the Mac section. Do note, however, that Apple has added some new iPad capabilities alongside the introduction of Catalyst that you may not be familiar with. Even if you have an existing iPad app, it’d be a good idea to review the first section before proceeding.
Catalyst
If you’ve made it this far, you likely know what Catalyst is. But in case you need a refresher, it is Apple’s mechanism for bringing iPad apps to the Mac. Introduced in macOS 10.15, it enables you to simply check a checkbox in your UIKit-based Xcode project and begin running your app on the Mac.
Starting in macOS 10.15, many of Apple’s own apps that run across iOS and macOS have been built using Catalyst, including Maps, News, Voice Memos, Podcasts, and Reminders. If you’ve used any of these apps on Mac and iPad, you’ll note that they are similar in structure, but the apps feel quite genuine on their respective platforms. Even when you run your iPad app on Mac without modification, you’ll find that it already adopts many of the Mac-standard UI idioms, it’s not just your iPad app running on a desktop simulator.
Here’s a look at how the Reminders app looks, first running on iPad:
And now, on Mac:
A few more things to note about Catalyst before you learn more about how it works:
First, you’ve probably noticed the word “iPad” used over “iOS” or “iPhone and iPad” when Catalyst is being discussed. This is not a coincidence. Catalyst is only available for apps that support iPad. This is because iPad apps have already gone through changes required to take advantage of things like a larger display, keyboard, multi-window, etc. Thus, they make a much smoother transition to the Mac.
Secondly, while Catalyst apps run on Mac, they are not AppKit apps, and can’t easily accomplish some of the feats achieved by AppKit apps. Catalyst is a powerful first step towards a new way of building Mac apps, but a first step nonetheless. For this reason, AppKit is still a fully supported method for building Mac-only apps and is going to be the best approach for some classes of apps.
Lastly, when you build using Catalyst, you may end up with a separate Mac binary, although you’re using one single codebase. You can distribute your app as a universal app binaries for iOS that run on iPhone, iPad and the Mac. You can also distribute your app separately, just like any Mac app, on the Mac App Store or independently.
Now, let’s take a deeper dive into how Catalyst does what it does.
Catalyst Under the Hood
As mentioned earlier, Catalyst is not merely taking your iOS app and running it in a simulated Mac environment. Nor is it some variation of AppKit, which still exists separate from Catalyst and UIKit. So what is it then?
Well, it’s UIKit running under the x86 architecture, and rendering Mac-style UI. But, it’s not just UIKit. It’s also many of the system frameworks you know and love, some that were already available on Mac, and some that were not. Because AppKit remains as a first-class method for creating Mac apps, Apple now has two stacks for doing so.
Instead of maintaining two entirely separate framework stacks, Apple has wisely unified frameworks where possible and left them separate otherwise. In the above diagram, you can see where the stacks continue to have separate components (WebKit, SceneKit, etc.), and where they converge (frameworks like Foundation and various types of user data stores).
Framework Availability
While Apple has made the experience of running iPad apps on Mac quite frictionless, not all frameworks available on iOS are available on macOS. Frameworks that take advantage of hardware features found only on mobile devices aren’t available on macOS. Therefore, code that uses these frameworks must compile out when building under Catalyst.
You’ll learn more about how to conditionally include or exclude code when running under UIKit for Mac later on in the book.
UI Availability
Much like with frameworks, there isn’t always going to be a 1:1 analog between an iOS UI component and a Mac equivalent. As you start porting your iPad apps to Mac, you’ll notice that many controls on iOS, such as UITabBar
, don’t exist on Mac. So, they must be replaced with suitable Mac-style alternatives.
Tabs, for example, are typically found in macOS toolbars at the top of windows as opposed to a dedicated lower area on iOS. The top of a window is where a user expects to find hierarchical controls on a desktop app. Whereas, for one-handed touch device use, it is more ergonomic to have tabs at the bottom. In this case, you could simply render a standard UITabBar
when running on iOS, but move those same tabs to NSToolbar
for the app window when on macOS.
Which Apps Should Make Use of Catalyst?
Now that you have a good idea of how Catalyst works, it’s worth asking the question: Which apps make sense to be ported to the Mac? The answer, as you’d expect, is: Not all of them.
In general, any iPad app can be configured to run on Mac. But, if your app falls into one of the below buckets, it might be particularly ripe for Catalytic conversion:
- Existing UIKit iOS apps. If you have a large UIKit-based codebase, it might be easier to use Catalyst to bring your app to macOS instead of rewriting your whole app in SwiftUI.
- Apps with comprehensive iPad support. If your app is already well supported on iPad, and you’ve put off making a Mac app for lack of time or wanting to maintain another codebase, now might be the time to bring it to Mac.
- Apps with old or poorly maintained AppKit counterparts. Likewise, if you already have a Mac version of your iOS app, but it has fallen into disrepair or is out of date, it may be a good idea to sunset it in favor of a Catalyst app based on your iPad project.
Conversely, if any of the bullets in the below list describe your app, you may not need to use Catalyst:
- Apps that make extensive use of mobile-device hardware. An app that is entirely based on ARKit for example (like an AR-based game), would be almost entirely non-functional on Mac.
- Apps that leverage cross-platform engines. A game build using a tool like Unity, for example, can already be built for Mac without the use of Catalyst.
- Apps that already have well-supported AppKit versions. Many iOS apps already have very well done and maintained AppKit counterparts. In these cases, there isn’t a huge benefit to switching to using Catalyst.
- SwiftUI apps. If you app is written completely in SwiftUI, you don’t really need Catalyst! SwiftUI supports all three platforms out of the box.
Where to Go From Here?
Now that you’ve been introduced to Catalyst and have a general understanding of what it does and how it works, it’s time to put it to the test. In the first chapter, you’re going to check some checkboxes and find out how easy it is to get started running your app on both iPad and Mac.