Command line argument behaviour in macOS 15 after compiling with Xcode 16

I encountered this issue with an app I'm writing that accepts arguments. With some troubleshooting I've determined that this is an inherent behaviour in how Xcode 16 compiles SwiftUI apps and how macOS 15 launches them.

The issue: Launching the app as open /Applications/AppName.app --args --arg1 --arg2 --arg3 etc should allow the app to process the arguments as CommandLine.arguments and this is still the case. How the app sees arguments is unchanged and doesn't matter if you use CommandLine.arguments or swift argument parser or don't have arguments at all. This will affect any SwiftUI app as I'll demonstrate below.

The problem is that if you use a mix of arguments as --arg value pairs or --arg as a flag, then depending on the order the arguments are provides, the app won't launch properly. The icon will appear in the dock but no window appears until you click the icon in the dock. (BTW, having "Application is agent (UIElement)" set to YES in the Info.plist makes this task rather difficult.)

In testing if you use all flags, it's fine. if the flags are in pairs, it's fine. if you have one flag and then a --arg value pair, you will see the issue. If you reverse the order so the flag is after then it works fine.

How to replicate: On macOS 15 and Xcode 16

  • Open Xcode
  • Create a new macOS App (called demoapp in my example)
  • Select SwiftUI as the interface
  • Build

That it. Don't add anything and just build the boilerplate hello world app that Xcode makes for you. Once that's built, cd to your /Build/Products/Debug/ directory in terminal and try the following (this happens if you build for release as well):

note, the app window will display when you click the icon in the dock, just not on initial launch

# three single arguments
open ./demoapp.app --args --foo --bar --baz
# App window displays as expected

# one single argument, one arg value pair
open ./demoapp.app --args --foo --bar baz
# The app window will not appear.

# same arguments as before but the single argument is after the arg value pair 
open ./demoapp.app --args --bar baz --foo
# App window displays as expected

# arg[1] without `-` or `--` prefix
open ./demoapp.app --args foo --bar --baz
# The app window will not appear. 

# arg[1] and arg [2] without prefix
open ./demoapp.app --args foo bar --baz
# The app window will not appear.

# single - in front of the first two arguments
open ./demoapp.app --args -foo -bar baz
# The app window will not appear.

# single - in front of the first three arguments
open ./demoapp.app --args -foo -bar -baz bob
# App window displays as expected

No idea what is going on but I suspect macOS does some pre-processing before launching the app, for example you can do stuff like open /Applications/SomeApp.app --args -AppleLanguages '(de)' to run using a specific language. I presume the OS is pre-processing arguments before launching the app proper.

If I compile the app using Xcode 15.4 then this issue is not present. Also Apps compiled with Xcode 16 do not exhibit the issue on macOS 14 or earlier. It's a specific Xcode 16, macOS 15 thing in the way the app is compiled that makes it behave this way.

I hope I've explained it correctly, but it's very easy to replicate. I filed a feedback for it (under a different apple account), FB15577018.

Any insight into what's going on here would be helpful. Also if there's any compiler flags I could be setting. In my actual project, I'm not making any other changes. The same code compiled under Xcode 16 (.0 or .1RC) behaves differently to Xcode 15.4.

Command line argument behaviour in macOS 15 after compiling with Xcode 16
 
 
Q