MenuBarExtra for Mac Catalyst App

I have a Mac Catalyst App that I switched over to the SwiftUI lifecycle. I am trying to add MenuBarExtra to the app :

if #available(macOS 13.0, *) { MenuBarExtra("....", systemImage: ......) { .......... } }

However, I get an error : 'init(_:systemImage:content:)' is unavailable in iOS 'MenuBarExtra' is unavailable in iOS

How do I add MenuBarExtra to the app?

Answered by DTS Engineer in 771181022

In many cases, wrapping your UIKit code in UIViewControllerRepresentable works well, since (by its sort of legacy nature) it's likely to still be pretty self-contained, functionally.

I don't really have any other suggestions. The likelihood was that one of your porting steps would turn out to be awkwardly big, and maybe this is the one. 🙂

You're using a Mac Catalyst target, so it's essentially an iOS app, which doesn't support MenuBarExtra.

You don't provide much information about why you're using Mac Catalyst here, but if your app's UI is largely SwiftUI, then you're likely better off switching over to a pure macOS target. I'm not sure Mac Catalyst buys you much when you're using (cross-platform) SwiftUI anyway.

I have a fair amount of legacy UIKit code since I support iPadOS as well. Is there a way around that? The app started out as UIKIt and I am progressively moving it over to SWiftUI as it supports more features.

Accepted Answer

In many cases, wrapping your UIKit code in UIViewControllerRepresentable works well, since (by its sort of legacy nature) it's likely to still be pretty self-contained, functionally.

I don't really have any other suggestions. The likelihood was that one of your porting steps would turn out to be awkwardly big, and maybe this is the one. 🙂

If you are using Mac Catalyst, you could create a bundle (NSBundle) which has direct access to the AppKit lifecycle and APIs and load the bundle from Mac Catalyst (just be sure you only load the bundle when you are running on Mac Catalyst because it'll crash your app on iOS, in fact you should only add the bundle to the Mac Catalyst target). From the bundle you can call anything in AppKit (and make a menu bar item).

This is a widely used technique in Catalyst apps to implement missing functionality that the framework doesn't provide. No private APIs are involved. Apple doesn't like to recommend this but I'm pretty sure SwiftUI just shims over the same APIs (related to status items and such) that they seemingly don't want us to access directly anymore, for whatever reason. Maybe they think they are "abstracting" things away to make it simpler for us but often, for me, it feels like they are tying one hand behind my back.

MenuBarExtra for Mac Catalyst App
 
 
Q