Apple Mac OS X Notarisation of multiple bundles sharing common frameworks - macos

I'm struggling to find a solution to notarise my app with Apple.
I've passed the complete process and I'm also able to stamp my DMG that actually contains 3 bundles that shares a vast amount of common frameworks.
While launching the application once downloading it on a new machine, Gatekeeper keep saying that the application is from an unknown developer. After an extensive research and through the system.log , the problem seems to be that any framework or .dylib MUST BE inside the bundle into the Framework directory, while in my scenario, I've a top level folder with the frameworks , and all 3 bundles uses #loader_path to link to the frameworks that are 1 level external to their root.
So, if I want to distribute the application into a single DMG and avoid having a 200+ MB DMG by duplicating the frameworks into each bundle (and this will be also a mess because the apps shares some common configuration files and the entire directory structure will be somewhat incompressible to the end user), is there a solution ?

Okay got a ticket back from Apple, for the ones with my problem, the choices are basically 2:
1) Duplicate the frameworks, this includes only frameworks directly linked by the executable. Plugins or other stuff that's loaded at runtime can stay on another location
2) Install the shared frameworks inside /Library/Frameworks.
No other options, thanks Apple I have to work several hours to rework the entire thing!

Related

macOS Application Bundle Frameworks Directory Codesign

I am packing my macOS application into an application bundle. I need to codesign it and pass notarisation. It is possible to put the frameworks in the "Resources" directory?
I have two frameworks. Normally, I used to put such frameworks into the "Frameworks" directory of the bundle. However, for (stupid) designing reason I need to have some more libraries in the same directory of my frameworks. Since such libraries will prevent code signing if placed in the directory "Frameworks", I want to move frameworks + extra libraries into the "Resources" directory.
Reading Apple documentation it seems that frameworks should - of course - belong to the "Frameworks" directory, however I could not find any reference to what should NOT be included into the "Resources" directory. Is this bad practice? Would my .app structure not pass gatekeeper?
Any suggestion would be very much appreciated
You've probably already tried putting a frameworks in Resources by now. As you said, even if it works today, this is not a good idea.
You might be able to work around whatever issue caused you to want to do this by using the install_name_tool to change one of the paths built into your frameworks. Adding symbolic links are another handy device for issues like this. This kind of stuff can be done automatically in a Run Script Build Phase or a Build Phase Post Action.

Connecting dots from self-contained Java application to Mac OS installation

I am not a Mac owner and am putting myself through a crash course to get up to speed (e.g., reading "Switching to the Mac"), to give you an indication of my current level of understanding. The access I have to a physical Mac is limited, so I am trying to connect as many dots as possible before my next session with my friend's computer.
I have: a file folder containing all resources needed for a self-contained application written with Java (OpenJDK 11, JavaFX 11). The JLINK tool was successfully used to create this file folder, and it holds all necessary Java libraries as well as the code I wrote for the application. The executable resides in a subfolder: /bin. The program runs perfectly well on the Mac when the executable is run.
I want: something that is easy to download, install and run.
I'm unclear about what needs to be done to get this. The road map seems to have two main steps:
the file folder needs to be converted into something that responds as if it were an application (e.g., a Bundle? or an .app?)
the resulting folder-as-executable can be shipped via either .dmg or .pkg
For the second part, I've researched and found tools such as Packages or create-dmg. It seems to me these tools are pretty straightforward and shouldn't be too difficult to learn to use. (Just have to pick one or the other or something similar.)
For the first part, I'm on shaky conceptual ground. I've found info about Bundles, but no tutorials, walk-throughs or examples. It looks like a key step is understanding how to make a proper Info.plist file, but doing this properly looks tricky. Also, I'm not clear on how the resulting Bundle will become an .app file or if it needs to, or if there is another, more direct way to make my file folder be viewed by the OS as an application.
Some hand-holding or references to tutorials or even assurance that I am on the right track (if that is the case) would be much appreciated. Thanks!
The Java Deployment guide from Oracle relies heavily on ANT, but doesn't cover the case of a self-contained, customized JVM via JLINK well enough for me to decipher. So, I've taken the approach of trying to learn/understand the necessary steps using command-line commands.
While creating a Bundle is certainly an option, there is an easier way.
Step one is to make an .app manually. An answer to this question: "How to make a Mac OS X .app with a shell script?" goes over the basic steps. The Java file system that results from jlinking has a folder /bin in which there is a bash file that runs the program. This file should be moved to the outermost folder, and it should be named the desired name of the application. The bash file itself will have to be edited and "/bin" added to the address in last command so that the executable will be found. In addition, the folder itself will have to be renamed to be the same as the bash file, but with .app added as an extension.
The next thing I wanted to have was a custom icon. The question "Include icon in manually created app bundle" shows how to do this.
For the next step I made use of the program "Packages". I'm a bit confused about where I downloaded this from (there seem to be multiple sites), but here is a link to the manual. This tool allowed me to create a .pkg file that, when executed, installs my .app in the Applications folder. Then I compressing the .pkg file (to .zip) and made it available at a URL for downloading.
I've had a friend do a test download and install, and the program works!
This isn't meant to be a complete tutorial, and there are a few steps more that I want to figure out pertaining to sandboxing and sealing, but I believe this is a reasonable roadmap that can be used for simpler jlinked Java applications for Mac distribution.

Can I put info about multiple executables inside the same bundle in Info.plist?

I have a Qt app that uses Assistant to display help.
On Mac, I am packaging he Assistant inside the bundle. The only way I can include all its libraries is by placing the Assistant executable inside the same MacOS folder as the app executable, and properly link all the library dependencies.
Is there a way to place information about both executables in the Info.plist ?
No, you can't put info about multiple executables inside the same Info.plist. (Well, you an always puts custom keys into the Info.plist and store whatever property list data you like there, but the system won't pay any attention to those keys.)
Why not bundle the Assistant into its own bundle and put that bundle inside the main app's bundle? The Assistant bundle would have its own Info.plist file. Also, if you create a question about whatever linking or dynamic loading problems made you think you had to put it all into the main bundle, you might find there's a better solution.
placing the Assistant executable inside the same MacOS folder
I recommend not to do this. The Assistant is a resource to the main application and so it should reside in the resources folder. If you want to launch the Assistant app from the main app, you can then locate it by name.
You can only define one application in the Info.plist. If you were to add more, there would be a conflict in keys.
For example, CFBundleIdentifier is a unique URI that names the bundle (e.g. com.apple.calculator). The OS uses the URI to register the application with the OS when an application is, for example, copied to the /Applications folder. The OS expects the key to be a child of the root dictionary and its value must be unique. If there were multiple keys named CFBundleIdentifier, it would not know which is valid.
Although you can throw almost any junk into a Mac application bundle, much good will not come to you.
If I understand right, you have both a Mac Application (bundled normally) and a side-application you call the "Assistant" you want embedded in the same application bundle.
You also mention libraries (.dylib's I guess) that must reside in the same directory as the assistant.
Now - if these libraries are only used by the Assistant side-application, I would recommend that you bundle the assistant as a Code-bundle (Apple provides lots of information about these, and you have easy to use templates from Xcode). You can then use Xcode to copy it into the right place within the main application's bundle (I'd choose "Plugins") and use NSBundle APIs to launch it.
However, if those .dylibs are shared between the main app and the assistant - then I'd say go ahead, stick your assistant, .dylibs and main app's binary files in the same "MacOS-X" directory, and use posix APIs, or shell command to launch the assistant. Of course it will share (if possible) every resource of the main application, because they are located at the same place. However, the main app's bundle can only have ONE CFBundleExecutable entry, and that should point to your main application's binary.

How to associate file during folder copy on Mac OS X

I involved with the development of an application that is intended to deploy on multiple desktop system including the Macintosh.
Our team decided we would like to a drag and drop installation for the Macintosh. However, the application is intended to ship with other content besides the application itself such as example files.
Originally these files were placed in the application bundle, however this was discovered to be problematic as the cross platform libraries used for the user interface will not allow someone to access the contents in the bundle. Also force users to have to dive into a bundle to find content does not offer a great user experience.
To that end, we decided to pull these examples file and what not out of the bundle and place them in a separated folder that lived along side the application bundle. To make sure everything including the examples and the application were copied together during the drag and drop installation, a new top level folder was created that contained everything to be copied.
The problem that now exists is that whereby when originally just the application bundle was copied over to the system, the copying of this top level folder does not cause file associations for the application to occur automatically.
What can be done to associate an application with certain files when someone installs by dragging a folder contain the application bundle?
I suggest you to deliver it separately in one dmg. So your dmg structure will look like next:
MyApp -> Applications
MyApp Examples -> Application Support
Simple, user-friendly, no problems with association.
Actually it looks like the file association is working after all. Someone reported a defect against the installation not making the associations. However, I just tested the installation on a clean system and copying over the folder does seem to make the associations.

Cocoa framework development: sharing between projects

I am currently developing a handful of similar Cocoa desktop apps. In an effort to share code between them, I have identified a set of core classes and functions that can be common across all of these applications. I would like to bundle this common code into a framework which all of my current applications (and any future ones) can link against.
Now, here's the hard part: I'm going to be developing this framework as I go, so I need each of my desktop apps to have a reference to it, but I want to be able to edit the framework source code from within each of the app projects and have the framework automatically rebuilt as required.
For example, let's say I have the Xcode project for DesktopAppNumberOne open, and I decide that one of my framework classes needs to be changed. I would like to:
Open and edit the source file for that framework class without having to open the framework project in Xcode.
Hit "build" on DesktopAppNumberOne, and see the framework rebuilt first (because one of its sources has changed), then see parts of DesktopAppNumberOne rebuilt (because one of the frameworks it links against has changed).
I can see how to do this with only one app and one framework, but I'm having trouble figuring out how to do it with multiple apps that share a single framework.
Has anyone had success with this approach? Am I perhaps going about this the wrong way? Any help would be appreciated.
Make an XCode Project for you framework.
In the 'Groups & Files' Panel > See the Blue Project Icon at the very top left? Drag and drop that into the 'Groups & Files' Panel of any other project you like.
So, make an app project, and drag in the project icon from your framework project.
CMD-i on your app target. Here you set your dependency on the framework and Link against it.
A few points
Linking multiple apps to one framework can be stressfull. You will either need to install your framework into /Library/Frameworks or equivalent or bundle up into each app.
For development purposes, i find setting a custom, common build directory for each of the projects eases things. I set each project to build into /Code/Build/Debug. This means that framework search path for debug build can be $CONFIGURATION_BUILD_DIR. For your release builds you will still have some work todo with install paths, rpaths, etc. Pain in the Ass!
XConfig files are your friends. The Open source google mac toolbox stuff is a good example of how to use them. You will probably need at least a Project_debug.xconfig, Project_release.xconfig, Target_framework.xconfig, Target_application.xconfig.

Resources