Helper Apps and the Sandbox

@Sam : many month ago, my App was rejected because the helper don’t have the same ID, when corrected an submitted once, the App was approved.

I am curious : what is the point of launching the app through a helper versus launching it directly ? What is achieved that the main app could not ?

Relaunch the main app?

I have a similar setup: main app and helper app. The helper app is practically just a timer, which checks if it’s time to launch the app so that the app can do it’s thing - archive emails in an interval here.

I see better. Thank you.

Bollocks, this is going to destroy Window Restoration in one of my apps that I’m designing! Not to mention it should screw heavily with the application container, as each application will have a different UUID and may swap between the two…

Fingers crossed they’ve wised up, otherwise I might just not launch the next one on the App Store!

[quote=94074:@Michel Bujardet]I am curious : what is the point of launching the app through a helper versus launching it directly ? What is achieved that the main app could not ?[/quote] I didn't do this for any other reason then reading that this is the accepted method of doing it. The only reason I can why, is because you have to allocate permission to the helper application via the security API, and this is something that your main application doesn't need.

I am very grateful for the many responses to my initial inquiry. The inverted case, where the helper app launches the main app, is one I had never thought of.

One aspect that has not come up, but which baffles me, is the apparent difference between calling a helper at the app bundle (.app) level and calling the executable directly, either down inside the bundle or just on its own, bundle be damned. For me, launching the executable directly, using LaunchServicesOpenMBS, also launches the Terminal window. This happens independent of sandboxing, but of course stops a sandboxed version in its tracks. Any insights as to where this behavior comes from? Can it be avoided? Putting a command-line executable inside an app bundle just to avoid a gratuitous terminal window, seems dorky.

I also sense a conviction that the standard case–a sandboxed-by-AppWrapper Xojo app that has one or more helper executables somewhere in its app bundle–should be acceptable to Apple. The problem we are facing is to find a way to get this configuration to work, not an argument with apple, though that may lurk in the future as well.

I have tried calling a command line executable through a shell in or out of the bundle from a sandboxed app and it was always refused.

When not sandboxed, the command line program is called through a shell and it works fine without the terminal window appearing.

@James: what exactly are you doing? I’ve never seen something like that. Can you post your code?

[quote=94119:@Beatrix Willius]James: what exactly are you doing? I’ve never seen something like that. Can you post your code?

[/quote]

consider the following trivial example:

A Xojo app has a helper app in its MacOS bundle subfolder (or other place once we converge on the correct place for it to be.) The main program executes something like:

[code]HelperFolderItem = GetFolderItem( "" ).Child( "MyXojoApp.app" ).Child( "Contents" ).Child( "MacOS" ).Child( "Helper.app" )
Call HelperFolderItem.LaunchServicesOpenMBS[/code]

The helper app might be something like the following Applescript:

[code]set appSupportPath to ((path to application support from user domain) as text)
set inputPath to appSupportPath & “SandboxTest:input.txt”
set outputPath to appSupportPath & “SandboxTest:output.txt”

set inputIndex to open for access inputPath
set sourceData to read inputIndex before return
close access inputIndex

set outputIndex to open for access outputPath with write permission
write sourceData & " It writes to file:" & return & return to outputIndex
write outputPath to outputIndex

close access outputIndex[/code]

Outside the sandbox, this sort of thing works fine, assuming the main app has created the input file in an Application Support subfolder named SandboxTest. The helper starts up, reads from a file, adds some text, and writes back out. Sandboxed, it just crashes for me. I need this sort of thing to survive sandboxing.

Of course, I have bigger fish to fry. Xojo actually wrote my project up as a case study (“Emergent Mathematic” under education on the Xojo web site.) The basic paradigm is to take real open source apps that scientists use every day and add a Xojo front end to them to make them accessible to students. It all works great when I do the communications with shells, but I need to make my apps easily accessible, which means app store which means sandbox.

No doubt others will have this same need.

What happens if you use just folderitem.launch instead?

5/30/14 7:28:58.573 PM lsboxd[302]: Not allowing process 651 to launch "/Users/Mitch/Documents/MatchFonts/1-Development/scratch/Builds - strings.xojo_binary_project/Mac OS X (Cocoa Intel)/strings.app/Contents/Resources/Epub to Text.app/Contents/MacOS/Epub to Text" because the security assessment verdict was denied.

I think we have to conclude at this point that the answer to the original question, “Is there an approved way to call a helper from a sandboxed xojo app?” Is “no.” There may not be any clean way at all. I will continue to experiment and report back if I find anything.

Anyone know if it is possible to pass command line parameters along to a helper app when using LaunchServicesOpenMBS? Or perhaps know of a declare that can be used instead?

Using folderItem.Launch(commandParams) works when launching an app, but as discussed above I need to use LaunchServicesOpenMBS for a helper app.

Perhaps NSTaskMBS would be better as it allows the passing of arguments? Any gotchas with NSTask that I should look out for?

Any ideas?

OK, here’s the results of my experiments. I too have a main app that spins out a helper app to do some heavy lifting. So I need the main app to start the helper app.

Using NSTask gives the error:

04/06/2014 18:00:25.371 sandboxd[168]: ([68552]) MYAPPNAME H(68552) deny forbidden-sandbox-reinit

I can’t find much about this online but it appears that the helper app tries to reinitialise the sandbox, which is a no-no. There was someone online who had the same issue and said they managed to get around it with a shared NSWorkspace (see here).

So I tried using NSWorkspaceMBS.launchApplicationAtFile and this time I receive this error:

04/06/2014 18:03:15.571 lsboxd[323]: Not allowing process 69282 to launch “FULL/PATH/TO/MY/HELPER/APP.app” because it has not been launched previously by the user,

This is the same error I receive when trying to use LaunchServicesOpenMBS.

Reading the Apple documents about sandboxing (here) it says that one of the conditions of using Launch Services is that:

This means it’s completely useless if you want the helper app to be a worker that is started by the main app. A user is never going to be able to manually start it at least once.

This is a real headache and could be a show stopper for my app. I thought one of the main uses of a helper app was to spin out some heavy lifting into a separate process? Seems weird there isn’t a sanctioned way of doing this within a sandbox.

This seems ugly, doesn’t it. It looks like there’s some sample code here : AppSandboxLoginItemXPCDemo https://developer.apple.com/library/mac/samplecode/AppSandboxLoginItemXPCDemo/Introduction/Intro.html which might allow you to set up the helper app as a login item, get it to launch once, and then un-set it as a login item, so you could thereafter just launch it while the main app runs? Seems very hacky-though.

My app got rejected, for something else… Hopefully I don’t have a reviewer who rejects each time he finds something that he thinks is rejection worthy, I’ve had these guys in the past and they’re a pain.

Fingers crossed, the way I’ve done it will be approved!

Are you using the same Bundle Identifier for both apps?

Tried it with the same and different identifier. Same result unfortunately.

[quote=95540:@Sam Rowlands]My app got rejected, for something else… Hopefully I don’t have a reviewer who rejects each time he finds something that he thinks is rejection worthy, I’ve had these guys in the past and they’re a pain.

Fingers crossed, the way I’ve done it will be approved![/quote]

Fingers crossed. If it works I will certainly appreciate you post your secret recipe :wink:

Rejected again - This time the reviewer managed to make it error, I wish when thy did, they’d also provide information on how they did it.

I feel sorry for App Reviewers, it’s gotta be horrible; your sole purpose in life is to crush App Developers, to do everything you can to prevent their application from being sold.