0

I have some MacOS client/server software that originally installed as a folder containing two separate .app folders; one for the client, and one for the server.

That worked fine, except that it meant that I had to include a separate copy of every bundled shared library in each *.app/Contents/Frameworks sub-folder; and given that both apps have a Qt-based GUI, that was a substantial amount of overhead.

Someone suggested that instead of shipping the two programs as separate .app folders, I simply move the server's executable file (TheServer.app/Contents/MacOS/TheServer) into the client's Resources folder (TheClient.app/Contents/Resources/) and then add a "Launch Server" button to the client GUI that launches TheClient.app/Contents/Resources/TheServer as a child process when clicked.

I did that, and that also works well, and reduces my application's .pkg size by about 25 megabytes.

The only downside is that now when TheServer runs, its icon in the Dock is a generic Terminal icon (see attached screenshot) rather than its intended custom icon; presumably this is because TheServer no longer has an associated Info.plist file in which to declare its CFBundleIconFile attribute specifying where its .icns file is.

My question is, is there any way to remedy this situation and allow TheServer's GUI to have its custom Dock icon again? Or am I just out of luck here?

generic Terminal icon

12
  • Hmmm, don't know the answer, sorry, but that might break Apple's ever stricter code signing rules. Have you tried notarising your app, or don't you need to? No code is supposed to reside in the Resources folder. Also, if both apps install from a single .pkg, you might be able to work some kind of magic with a symlink. Commented Oct 22, 2023 at 2:05
  • 1
    @PaulSanders the app is signed and notarized and Gatekeeper isn't complaining, so either it doesn't break the rules or Gatekeeper isn't enforcing that particular rule yet. Commented Oct 22, 2023 at 6:16
  • How are launching it? And where did info.plist go? Commented Oct 22, 2023 at 10:10
  • 1
    Ah, yes, that did it. I moved TheClient.app into the TheServer.app/Contents/Resources, and that gets me the icon; of course it also gets me two copies of all the shared libraries again, which I was trying to avoid. To fix that, I deleted TheClient.app/Contents/Resources/TheServer.app/Frameworks, and then used install_name_tool to retarget TheServer to reference the shared libraries in TheClient.app/Contents/Resources instead. Remarkably, neither Gatekeeper nor the notarization server seem to mind this (I suppose because the shared libraries are still within the overall package) Commented Oct 26, 2023 at 5:27
  • 1
    I do all of the codesigning steps after all of the above, so AFAICT there's no need to re-sign. Commented Oct 26, 2023 at 11:08

1 Answer 1

1

One possibility that works with raw binaries without bundles is to simply replace the Dock icon programmatically when the program starts:

[NSApp setApplicationIconImage:nsImage]; 

This way you don't really even need an icon file at all, as you can create the NSImage programmatically if you feel like it.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.