Streaming is available in most browsers,
and in the Developer app.
-
Qualities of great iPad and iPhone apps on Macs with M1
It's easier than ever to offer your existing iPad and iPhone apps on Macs with M1. We'll show you how to bring your app to macOS, and explore how the system automatically bridges various features of your app to work on the Mac. We'll also provide guidance on best practices in your iPad app, combined with improvements in macOS Monterey — like Apple Pay support, improved AV handling, and shortcuts — to provide the fullest experience on Macs with M1.
Resources
Related Videos
WWDC21
- Design great actions for Shortcuts, Siri, and Suggestions
- Explore advanced project configuration in Xcode
- Focus on iPad keyboard navigation
- Meet Shortcuts for macOS
- Meet TestFlight on Mac
- Qualities of a great Mac Catalyst app
- Take your iPad apps to the next level
- What's new in Mac Catalyst
WWDC20
-
Download
Hello, my name is Nils Beck, and I welcome you to "Qualities of great iPad and iPhone apps on Macs with M1." More than a million iPad and iPhone apps are already available on the Mac App Store. The experience is great on macOS Big Sur, and we've further improved it in macOS Monterey. In this video, we'll discuss how we mapped several iOS APIs to the corresponding Mac features, some general best practices to keep in mind that will also help your app shine on Macs with M1, improvements that we made in macOS Big Sur software updates, as well as in macOS Monterey, and then we'll finish off with Mac App Store deployment considerations. iPad and iPhone apps on Macs with M1 are the easiest way to expand your existing app's reach to the Mac. This is your unmodified iPad or iPhone app, as submitted and approved for the iOS App Store, offered through the Mac App Store to anyone with an M1 Mac. To make this possible, we focus heavily on compatibility. System APIs are mapped to their natural Mac equivalents wherever possible. Our aim is to ensure a smooth app experience on the Mac without you making any changes. And most existing apps work great! This includes everything from small iPhone utilities to cutting-edge iPad games and Pro Apps. A variety of extensions are also supported. For example, share extensions, WidgetKit widgets, photo editing extensions, VPN network extensions, audio units, and more. So, it's very likely that your existing iPad or iPhone app already works well on the Mac, right out of the box. Of course, we support all basic functionality, such as text interactions, copy and paste, a Mac menu bar, and so on, but there is also a lot of advanced functionality, like background app refresh, user notifications, camera access, Siri intents, and more. Many of these topics are discussed in the video, "iPad and iPhone apps on Apple silicon Macs," so check that out for more details. And when you want your app to take advantage of even more of what the Mac has to offer, consider building a Mac Catalyst version of your app. You can learn more about that in the videos, "Qualities of a great Mac Catalyst app" and "What's New in Mac Catalyst." Now, let's dive into more detail for some of the APIs I just mentioned. You are likely already using these to make your app great on iPad and iPhone, and we've bridged them to seamlessly give you the same great features on the Mac. Naturally, you can use the Mac keyboard for text input into text fields, as well as for UIKeyCommand keyboard shortcuts. But if you need more control and want to write your own keypress handling, you can do that with the UIPress API on UIResponder. All Macs have a physical keyboard, so apps that have taken the time to add support for physical keyboards on iPad and iPhone are greatly improved on the Mac at the same time. Next, let's talk about the menu bar. As a reminder, the Mac menu bar is intended to help with the discoverability of app features and keyboard shortcuts. The menu bar structure is determined at launch, and should remain more or less constant after that. Items are not added or removed, but rather, they get enabled or disabled, depending on whether they currently apply.
We automatically populate your app's menu bar, taking into account your app's features. For example, we might add menu items to create a new window, to work with rich texts, or to change the device orientation. Note that UIKeyCommands that are directly attached to UIResponders through the keyCommands property do not appear in the menu bar, but their keyboard shortcuts will take priority over the shortcuts of menu items, whenever they apply. You might already be using the more recent UIMenuBuilder API that we introduced in iOS 13. This adds semantic structure to your UIKeyCommands. This structure is visible in the Keyboard Shortcuts menu that appears when you hold down the Command key on an iPad with a keyboard. On the Mac, the default structure that gets passed into the builder will be different, but your customizations to the structure will be reflected in the main menu. UIKeyCommands rely on the responder chain to find an applicable target for their action, and this determines whether or not a menu item is enabled. For much more on this, check out the videos, "Take your iPad apps to the next level," "Focus on iPad keyboard navigation," and "Qualities of a great Mac Catalyst app." For apps that use drag and drop on iPad and iPhone, using UIDragInteraction and UIDropInteraction, this automatically carries over to the Mac as well. This lets people seamlessly drag content between your app and others, like in this example, where I'm dragging a QR code from Qrafter to my desktop. And for apps that print with UIPrintInteractionController, this is automatically bridged to a Mac print dialog when printing is initiated in your code. Even better, when you adopt the new Info.plist key "UIApplicationSupports PrintCommand" and implement the corresponding standard print action, the Print and Export as PDF menu items will be added to your app's menu bar automatically. For more details on this new API, check out "What's new in Mac Catalyst." Many apps use a settings bundle, and we will automatically generate a Mac-style preference panel from this. It is also common to put credits in the settings bundle, and we identify such cases and move that text to the About box for you. But if you want more control over what is shown in the About box on the Mac, you now also have the option to add a credits file to your bundle. You can use RTF, RTFD, or HTML files, the same way Mac apps do this. There are a number of iPad-centric APIs that will help make your app a great iPad app. These all come across wonderfully on the Mac. So, by making a great iPad app, you're also making your app better on Macs with M1. If your app supports multiple scenes according to the UIApplicationSupports MultipleScenes Info.plist key, each scene is translated into a separate window, and we automatically add a menu item to create a new scene. On the Mac, a system-wide setting determines whether all windows are closed when the app quits, or whether existing windows are restored on the next launch. We respect this setting if your app supports multiple scenes, so don't be surprised if all scenes disconnect, or if state restoration does not occur in some cases. iPad multitasking support, on the other hand, automatically translates to resizable windows on macOS. Since your app already supports dynamic layout changes on iPad, you get live resizing windows on the Mac. You can limit the range of allowable scene sizes using the minimumSize and maximumSize API on UIWindowScene. Note that only the window scene size will change when the window is resized. The UI screen size, on the other hand, will continue to report the device size, which doesn't change in this case. So, make sure you don't use the screen size for your layout calculations, even on iPad, or your UI elements will end up in the wrong place. If your app expects to be in control of the entire screen of the device, we will use a fixed scene size and aspect ratio. But window contents may be scaled up or down as needed, in a way that is transparent to your app. And if your app supports multiple user interface orientations, the window orientation can be changed using the automatically added menu bar items, or by dragging the edges of the window. Here, I am using the menu bar items to change the orientation of the Chess.com app, and the user interface adapts to make optimal use of each device orientation. These and other mappings are able to remove most of the friction when bringing your iPad or iPhone app to the Mac, but let's touch on some coding practices that you should follow to ensure that your app works well across all platforms, including the Mac. When using Apple frameworks, it is important that you only use officially supported APIs, as undocumented methods in our frameworks may not exist on the Mac, or could change at any time.
Avoid hard-coding paths to file system locations, as these may be different on the Mac. For example, do not prefix your paths with "/private," or "var mobile." Instead, use the appropriate APIs to determine each path at runtime. Similarly, for UI that is not under your direct control, it is best not to make assumptions in your code about the onscreen positioning of views and alerts, or the exact setup of such view hierarchies, as these can be drastically different on the Mac. Please also be aware that the available camera resolutions and orientations might be quite different on the Mac. For example, if your iPhone app is in portrait orientation when a picture is taken, you might expect the resulting camera picture to be in portrait orientation as well. But this is not necessarily the case when the app is in portrait orientation on the Mac. You might receive images in landscape orientation instead, because that's how the camera is positioned. We've already included a number of heuristics to improve compatibility with many apps. For example, we will give you the picture of the Mac's front-facing camera, even when you asked for the rear-facing camera. But it's much better if you use the AVCaptureDeviceDiscoverySession and related AVFoundation APIs to gather information about the available cameras and their true properties, such as the preview dimensions. And you should aim to handle all possible configurations well in your UI. Also keep in mind that some hardware features are unavailable on the Mac. Your code should be able to handle such situations gracefully, and offer alternatives. For example, augmented reality with ARKit is not supported on the Mac. If ARKit is the core functionality of your app, you have likely made it a required device capability, so your app will not appear on the Mac App Store. But if the ARKit is an optional feature, you should already be checking the isSupported property of the appropriate ARConfiguration subclass. And for the best experience on the Mac, and elsewhere, make sure you only show augmented reality features in your UI on devices that have this capability.
If your app relies on direct Multi-Touch or on CoreMotion, consider additionally offering alternatives that are more suitable for the Mac keyboard and trackpad. That said, Touch Alternatives may be able to help in this case. I'll talk more about that in a moment. And if you use CoreLocation, your app should remain usable even if no accurate location data is available. For example, you can offer manual location entry as an alternative, like the Lowe's app does here. Next, let's go over some of the improvements we've made since we first started shipping Macs with M1. In macOS Big Sur 11.3, we made several improvements to the way that windows of iPad and iPhone apps behave on the Mac. If your app has a fixed content size because it does not support multitasking but it does support large device sizes, at launch we will now pick the largest supported device size that fits onto the screen where the app is launching. As far as your app is concerned, the device size still remains fixed for the entire session, but the window makes much better use of the available space. There is also a preference to use the smallest supported device size instead. And as I mentioned earlier, the window contents will be scaled up or down as needed. For example, when I make the window full screen, the window contents are automatically scaled up to fit the available space while maintaining the original scene aspect ratio. Or, if the window is moved to a smaller screen after launch, we will automatically reduce the scale as needed to ensure that the window still fits. It is now also possible to use the Window Zoom feature to toggle between two zoom factors, one prioritizing the natural size of UI elements, the other prioritizing pixel-perfect accuracy. Here, I am using this feature to switch between the two zoom factors in the Chess.com app. Game controllers have been supported from day one through the GameController.framework, which is available on all of our gaming-capable platforms. Starting with macOS Big Sur 11.3, we've made it possible to use the Mac's keyboard and trackpad as a virtual game controller. So, even if you don't have an actual controller handy, it is easy to use the keyboard to access all the functionality that your game maps to controller buttons. And in macOS Monterey, we've further refined this with the addition of a sensitivity slider and pointer hiding, as shown on this picture of the corresponding preference panel. For more on this framework, check out "Advancements in Game Controllers." Moreover, since day one, Touch Alternatives have mapped the keyboard and trackpad to several interaction styles that would otherwise not be easy to use on the Mac, such as Multi-Touch, drag, tap, and swipe. And with MacOS 11.3, we've made a number of improvements. For example, you now have the ability to virtually tilt your device. This opens the door to a number of additional games. Also, the preference panel now includes a helpful graphical representation that illustrates how to access each of the five interaction styles through the keyboard and trackpad. In addition, we've made it possible for apps to automatically opt themselves into Touch Alternatives. When you opt in, an onboarding dialog is shown on first launch, in order to help with the discovery of this feature. The graphics are similar to those from the preference panel, but we only highlight the interaction styles that you've selected. In this example, only Tilt and Multi-Touch are shown.
If you determine that your app would benefit from any of these Touch Alternatives, here's how you can enable Touch Alternatives for your app, right from the start. All you need to do is add a new.plist file to your bundle, named "com.apple.uikit.inputalternativ es.plist." Then, add the keys and values shown in the snippet. And for the requiredOnboarding array, include only the features that are useful for your app. That way, only those features are highlighted in the onboarding dialog. Let me demonstrate this for you. Take, for example, this iPad game called "Assoluto Racing," running unmodified on a Mac with M1. The app enables Touch Alternatives automatically, right from the start, so on first launch, this onboarding dialog shows us the keyboard controls. But first, let's show the software keyboard and take the window full screen. The contents are now scaled up to fit the screen, and we maintain the iPad aspect ratio.
Let's head over to the "Airport" level for some freestyle drifting.
This app uses CoreMotion, so that on iPad, I can tilt the device to steer. With Touch Alternatives enabled on Macs with M1, the W, A, S, and D keys simulate tilting. And here I control the car that way, while using my trackpad to click the accelerator button on the screen. And all of this is completely transparent to the app. Let's see how I do.
That worked great! I need to work on my drifting skills a bit, though. With macOS Monterey, we have made even more improvements. Apple Pay is now available for iPad and iPhone apps on M1 Macs using the same enhanced cross-platform API we introduced for Mac Catalyst applications in macOS Big Sur. This means you can now accept payments on every platform where Apple Pay is available, using a single implementation. Just make sure you've implemented the "paymentAuthorizationController, didRequestMerchantSessionUpdate" delegate call on your PKPaymentAuthorizationController Delegate. For more details, check out the video, "What's new in Wallet and Apple Pay." We've also made full-screen video with AVKit even better. AVPlayerView and AVPlayerViewController can now automatically take a video full screen using a separate window. This means that even apps whose window is otherwise restricted to the launch-time resolution and aspect ratio will make full use of the Mac display, as appropriate for the video content. And in case you need more control over the full screen experience, we've added new API to AVPlayerViewDelegate and AVPlayerViewControllerDelegate.
On top of that, AVFoundation supports HDR playback and streaming on Macs with M1. No Mac-specific adoption work is needed in your app. Finally, AVKit controls in iPad and iPhone apps now look the same as they do in other Mac apps. We even take full advantage of the Mac trackpad with support for new gestures. For more details, you can hop over to the video, "What's new in AVKit." And if your app uses the intents framework to offer custom SiriKit Shortcuts, on macOS Monterey, those are now supported for iPad and iPhone apps on M1 Macs. For more on Shortcuts, check out the talks, "Meet Shortcuts for macOS" and "Design great actions for Shortcuts, Siri, and Suggestions." Good news! It's easy to be on the Mac App Store. In fact, most apps are there automatically. As I mentioned earlier, in most cases, it makes sense to be on the Mac. After all, even a Bluetooth door-lock app, designed to be mobile, might prove useful if you've locked yourself out of your home without your phone, but you have your Mac with M1 in hand. So, if you've previously opted your app out of the Mac App Store, now may be the time to reconsider. With improvements such as Touch Alternatives and enhanced full-screen video playback, your app may very well be a great fit for the Mac. In that case, simply recheck the "Make this app available" checkbox in App Store Connect to make the app available on the Mac App Store. Regardless of whether you previously opted out, you will want to confirm that your app really works well on Macs with M1. Once you're confident that the user experience is up to your standards, click the Verify Compatibility link in App Store Connect, shown here. This removes the "Not verified for macOS" text, which is shown next to your app on the Mac App Store, and replaces it with "Designed for iPad." App shoppers will take this as a sign that you have taken the time to make sure that they will have a good experience with your app on the Mac. You only have to do this once per app. Oh, and we've also made iPad and iPhone apps much more discoverable on the Mac App Store. When customers search for them by name, they no longer have to switch to the iPhone and iPad Apps tab. Apple will automatically pick the recommended minimum macOS version required for compatibility, and for most situations, this is fine. But in certain rare cases, you may wish to override this with a custom macOS availability. For example, your video app may work fine on Big Sur, but if you want to ensure that you have access to the AVKit full screen improvements, you may decide that it should only be available on Monterey and beyond. In this case, you have two options. Starting shortly, you will be able to choose a different minimum macOS version on the Pricing and Availability page of App Store Connect. This is great for apps that are already on the store because you don't have to resubmit a new version. Or, you can specify the LSMinimumSystemVersion in the Info.plist, and submit this change as part of your next update. This is the recommended approach for apps that are under active development. Note that this does not replace the MinimumOSVersion key, which specifies the iOS minimum system version. But really, both options should rarely be needed. Finally, let's talk for a moment about testing. Testing on macOS is very similar to testing on iPad. You can use the same workflows you are already familiar with. For local testing in Xcode, simply select My Mac (Designed for iPad) as the run destination, and debugging, unit testing, et cetera, all work just like they do for other devices. For beta testing, we've added TestFlight support for all apps in macOS Monterey, including iPhone and iPad apps, so you can now distribute your app to beta testers who are using Macs with M1. For more information on this, head over to the video, "Meet TestFlight on Mac." So, welcome to the Mac! Go verify your app and opt in. It's easy. And just remember, as you continue to improve your iPad and iPhone apps, you're also making those apps better on Macs with M1. Thank you very much. [upbeat music]
-
-
7:16 - Limit the range of allowable scene sizes
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene, let sizeRestrictions = windowScene.sizeRestrictions else { return } sizeRestrictions.minimumSize = CGSize(width: 640, height: 480) sizeRestrictions.maximumSize = CGSize(width: 1920, height: 1080) }
-
15:03 - Automatically enable Touch Alternatives
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>defaultEnablement</key> <true/> <key>version</key> <real>1</real> <key>requiredOnboarding</key> <array> <!-- Only include applicable features! --> <string>Tap</string> <string>Arrow Swipe</string> <string>Scroll Drag</string> <string>Tilt</string> <string>Trackpad Capture</string> </array> </dict> </plist>
-
17:17 - Required delegate method to enable Apple Pay support
optional func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didRequestMerchantSessionUpdate handler: @escaping (PKPaymentRequestMerchantSessionUpdate) -> Void)
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.