Multiple applications in a single bundle
Asked Answered
G

1

6

I am developing a multi-platform presentation application which consists of two parts: An editor part and a viewer part. Both parts are developed as separate programs. The user edits the individual slides using the editor and the editor then launches the viewer whenever the user wants to see his presentation.

On Windows the editor can simply run the viewer by doing a ShellExecute(). On Linux systems the editor could just fork() the viewer but on Mac OS X this looks like it could get complicated because of the infamous application bundle concept.

I'm wondering how this problem should be solved on Mac OS X.

Is it possible to have multiple applications inside a single application bundle or do I have store the editor and viewer components as separate application bundles?

Also, how am I supposed to pass information from the editor to the viewer application? i.e. the viewer needs to know which file to show. On Windows and Linux I can just pass this as command line arguments to the WinMain() or main() function. On OS X it looks like LSOpenApplication() could do the job but this is now deprecated. And I don't know if LSOpenApplication() can open applications inside the same application because I don't know whether that is even possible...

Could somebody shed some light onto this topic? Thanks!

Grefe answered 8/12, 2014 at 14:3 Comment(4)
Sounds like a terrible architectural choice. Make it one app.Ind
That's not easily possible. I'd first like to know if it's technically possible to have two applications inside a single bundle and one runs the other.Grefe
There's nothing wrong with this architecture, particularly if it might also be packaged as a viewer without the editor. Keeping the two pieces separate but integrated can be an excellent design choice if done well.Cappuccino
I suggest using XPC, which you can read about here: developer.apple.com/library/mac/documentation/MacOSX/Conceptual/…Cesarean
C
12

Is it possible to have multiple applications inside a single application bundle or do I have store the editor and viewer components as separate application bundles?

Yes, and yes.

Each application must be its own bundle. But you're free to include bundles inside your bundles. This isn't even that uncommon. Take a look inside of iTunes for instance:

/Applications/iTunes.app/Contents/MacOS$ ls -l
total 116816
-rwxr-xr-x  1 root  wheel  56643216 Oct 15 09:29 iTunes
-rwxr-xr-x  1 root  wheel     42608 Oct 16 20:31 iTunesASUHelper
drwxr-xr-x  3 root  wheel       102 Oct 16 20:33 iTunesHelper.app
-rw-r--r--  1 root  wheel   3617952 Oct 16 20:31 libgnsdk_dsp.3.06.0.dylib
-rw-r--r--  1 root  wheel    328928 Oct 16 20:31 libgnsdk_link.3.06.0.dylib
-rw-r--r--  1 root  wheel   3831312 Oct 16 20:31 libgnsdk_manager.3.06.0.dylib
-rw-r--r--  1 root  wheel   1511792 Oct 16 20:31 libgnsdk_musicid.3.06.0.dylib
-rw-r--r--  1 root  wheel    655328 Oct 16 20:31 libgnsdk_submit.3.06.0.dylib

See how iTunesHelper.app lives inside of iTunes.app? And also the commandline tool iTunesASUHelper? This is fine and normal. Just move it there during the copy files build phase.

A common tool for launching apps now is NSWorkspace. For your particular case, you probably want openFile:withApplication:. You may also want to look at XPC, however, to see if it meets your needs better. It allows much easier inter-process communication, though I find it's best for helper services rather than full GUI apps.

Cappuccino answered 8/12, 2014 at 14:20 Comment(2)
Thanks, this looks like a good solution. Would it also be possible to associate such a hidden app bundle with certain file extensions? i.e. would it be possible to associate "iTunesHelper.app" with the the file extension *.xyz in Finder? Or is this only possible for top-level app bundles? I'm asking because my viewer app (which is stored inside the editor app) should also be runnable from Finder by simply double-clicking on a project file...Grefe
Yes, this is possible, though it's been a while since I've done that. I can't remember if Launch Services will automatically detect it inside the bundle, or if you need to call LSRegisterURL(). You can find out by running /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump to see if your app shows up (sorry for the crazy long path, but that's how it works. I always use locate lsregister)Cappuccino

© 2022 - 2024 — McMap. All rights reserved.