Two executables in one bundle on MAC - macos

Is it possible to have two executables each with its own plist to share the same bundle. Then depends on the way app is executed (parameters) to load the appropriate executable.
Imagine the case where we have a main application (executable with UI) and the mini application (shorter version of the main app also with its own UI) and then depend on the parameters user used for starting the application execute the appropriate executable in the same bundle.
Cheers

Not exactly, but you could achieve something similar.
You could have a master Application bundle, which figures out which version of the code to run, and then have multiple plug-in bundles (as resources of the application) which actually implement the different versions. Each plug-in bundle would have its own Info.plist / nib files / etc.
See the documentation for NSBundle for details of how to load bundles and run their code.

I think I understand you. You want to share a plist between two executables. Just refer to the same plist in each case: tutorial for single executable plist.

Don't know if it's possible. Honestly I doubt it because the plist information is also used to define the icon and so on, so you would confuse the Finder if this would be possible (which icon should it display?). However, I am not an expert in Bundles, at all.
I give you a workaround. Create a demultiplexing script that runs the proper executable according to your parameters, and then associate the script with the plist information.

Related

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.

Can you dynamically assign CFBundleDocumentTypes to your Cocoa application?

Can you dynamically assign CFBundleDocumentTypes to your Cocoa application? Meaning during run time can I assign more extensions for my app to handle.
Currently I set some extensions for my app to handle using CFBundleDocumentTypes in the Info.plist, but I would like to do this through code while the application is executing (during run time). Basically can I make Launch Services aware of new extensions without modifying the Info.plist file.
Thanks.
At the moment, there’s no public API1 for an application to dynamically (un)register document types with Launch Services during runtime.
Open Emu faces this very problem. Users are able to selectively download/install emulators, which are bundles whose Info.plist files define document types. Upon installing an emulator, the types defined in the bundle need to be part of the types as defined in the application Info.plist. Open Emu rewrites the application Info.plist in order to do so — see -updateInfoPlist in OEGameDocumentController.
Note that overwriting the bundle Info.plist is a violation of Mac App Store’s policy.
We have filed radars asking for runtime (un)registration of document types. I suggest you file another one, too, which should be closed as a duplicate of #2526726. Even if it’s a duplicate, it’s important to file it anyway so that Apple have an estimate of the number of people that need this feature.
1It might be possible via SPI, though. When I was looking into this, I stumbled upon _LSRegisterItemFromItemInfo() in Launch Services.

Application permission issues on OS X, when distributing application

we are making an Application for OS X, however, when the .app is copied on another MAC, we have problems with reading and writing files
on one MAC, everything works great from the start...
the other one will not write certain files and another 2mac will not write certain different files
if i go to show application contents and wants to edit the file by myself, i get a writing permission denied
how to distribute an MAC application so there are no such issues? so all files can be read and write by the current user
does there have to be some authorization or code sign, or smth. different in this form, in addition to normal code?
thank you
It sounds like your application tries to write files within its own application bundle. The correct solution here is: DON'T DO THAT! The only time your application bundle should be written to is when it's installed or updated.
Files that the application needs to write to should be stored in the user's home folder, generally under ~/Library. See this note in Apple's dev docs.
Preference and settings files in ~/Library/Preferences/<appbundleid>.plist; use NSUserDefaults.
Data the app manages for the user in ~/Library/Application Support/<appname> (the docs say to use the bundleid, but everyone -- Apple included -- uses the app name instead).
Cache files in ~/Library/Caches/<appbundleid>.
Temp files, use NSTemporaryDirectory
If you need to share settings & files between users, that should generally go in /Library/Application Support/<appname>, except that you really shouldn't be doing that at all.
In the past I've always used PackageMaker to create installers. An installation package can authenticate with root privileges so you can set permissions after the install. I don't have it in front of me right now but if you look around you should be able to see a Post-Installer script line. Write a shell script that manually sets the permissions of each file you have in question and then have the package execute that script after the install is finished.
You can find PackageMaker at /Developer/Applications/Utilities/PackageMaker

cocoa + .app file

i have an executable for my cocoa application as xyz.app file. But when i copy this on windows, it is showing this as a directory with all the resource files and stuff. Is there any way to create a single file executable on mac also (like .exe file on windows) so as to disable the user from seeing the resource files and other files?
Thanks
You talking about a Bundle, which is a folder that is given an extension and the OS treats it as if it is a single file, while in reality it is a folder with resources in it. The NIB files are stored in this bundle as well as your executable and the info.plist file. This is just the way apps work in Cocoa.
The only way around it would be to write your app in a different language, but i'm not sure which, if any, will give you a single file executable.
What are you storing in your app directory that you don't want people to have access to?
There are ridiculously complicated ways to do that, sure. For example, you could gzip all your resource files and decompress them at runtime. But there's no good reason to do so — all it does is make more work for you, introduce additional complexity and make your app slow. Adobe doesn't do this, Microsoft doesn't do this, micro-ISVs don't do this — it's just not advisable.

Resources