Mac Catalyst was the previous macOS target. It’s superseded by the native macOS build described in Working with macOS, which produces an AppKit application rather than a UIKit one.
Mac Catalyst remains buildable and is still exercised by the compliance suite, so existing projects keep working. New projects should use the native macOS build.
What Mac Catalyst Is
Mac Catalyst isn’t a macOS port. It’s a slice of the iOS Xcode project: the same build pipeline, the same UIKit controls, one additional SDK. Apple’s compatibility layer runs that UIKit application on macOS.
That’s why the behavior differs from a native Mac app in ways no amount of configuration reaches:
Windows are
UIWindowSceneinstances rather thanNSWindowinstances.The menu bar is built through
UIMenuBuilder, and keyboard accelerators areUIKeyCommandobjects.Controls are UIKit’s, drawn by the compatibility layer rather than by AppKit.
Building It
Catalyst has no build target of its own, because it isn’t a separate build. It
is the iOS build with one hint set, and IPhoneBuilder emits the Catalyst
slice whenever it sees that hint:
codename1.arg.macNative.enabled=true
With it in codenameone_settings.properties, the ordinary iOS targets produce
the Catalyst app — ios-source for a local Xcode project, ios-device for a
build-server build:
# Catalyst is an iOS build. Turn it on with the hint, in
# codenameone_settings.properties, and build the iOS project target:
# codename1.arg.macNative.enabled=true
mvn -B -Dcodename1.platform=ios -Dcodename1.buildTarget=ios-source package
mvn -B -Dcodename1.platform=ios -Dcodename1.buildTarget=ios-device package
Generating the project locally requires Xcode and the Ruby xcodeproj gem. The
Catalyst path injects its build settings into an already-generated iOS project
after the fact, and that gem is what performs the injection; the native macOS
build generates a macOS project directly and needs neither.
Build Hints
Mac Catalyst reads the macNative. hint family: distribution, teamId,
bundleId, deriveBundleId, minDeploymentTarget, iosMinDeploymentTarget,
appCategory, copyright, the signingIdentity. pair and the notarize.*
group. They’re listed in the build-hint reference under Mac Catalyst builds.
iosMinDeploymentTarget exists only here. It sets the iOS half of the Catalyst
slice, and the native macOS build has no such half.
Deployment floors are macOS 10.15 and Catalyst 13.1.
Windows
Windows are off by default here, and turning them on isn’t recommended. Set
macNative.multiWindow=true alongside macNative.enabled=true if you need
them anyway.
They’re off because the implementation has limits Catalyst can’t lift, listed below, and because enabling them costs the rest of the application a layout shift — see Mac Catalyst (legacy) for the measurement. Neither was worth paying once the native macOS build existed: there, windows are on with no hint at all and every operation on the API is implemented, because AppKit is a multi-window system and Catalyst is an iOS one wearing a Mac frame.
With the hint set, a Codename One Window works, with one difference worth
knowing: the window’s content is rendered into an off-screen raster and
presented to the scene’s view, rather than the window owning its own GPU
surface. Native peer components and native text editing still use the scene’s
real view hierarchy and behave normally.
Some window controls have no Mac Catalyst equivalent, because AppKit owns the
behavior and Catalyst doesn’t expose it to a UIWindowScene. setAlwaysOnTop,
setUtilityWindow, minimize, restore and toggleMaximize do nothing here,
and setDecorated(false) is partial: it hides the title bar’s title and toolbar
but the window frame remains. Modality, minimum window size and resizability all
work. The native macOS build implements every one of them.
Moving to the Native macOS Build
What changes:
The build target becomes
mac-sourceormac-os-x-native.The hint family becomes
macos.. ThemacNative.names are still accepted, so an existing configuration keeps working;iosMinDeploymentTargetis ignored with a warning, because it no longer describes anything.The deployment floor becomes macOS 11.
The window chrome becomes AppKit’s, so a Mac user gets the title bar, menu bar and window behavior they expect from any other Mac application.
What doesn’t change:
Your Java and Kotlin source.
Your signing certificates and provisioning profiles.
Your distribution channels, App Store Connect records and notarization setup.