Forking: Possible with a macOS App Bundle?

Quick thought: What if there was a way to fork a macOS executable (without a GUI interface) to use as a Helper application?

Why the what if?

You can do things like this of course.

But I’d prefer currently to simply run your GUI app as second time with command line parameters to make it run as command line tool with Shell class.

Thats what I mean, I was just checking to see if its possible and if anyone else has tried it, found any drawbacks.

I’ll try a test soon, especially Sandboxed!

[quote=404708:@Sam Rowlands]Thats what I mean, I was just checking to see if its possible and if anyone else has tried it, found any drawbacks.

I’ll try a test soon, especially Sandboxed![/quote]

I have done this in the past. It worked, but I didn’t even think to use it in production because the way I did it it kept showing new icons bouncing and disappearing in the dock and it was a weird user experience.

I’d never thought it could go through the Apple approval process but if there’s a way to not show it on the icon it might work.

That’s one of my concerns. There is an ugly hack I could use to work around it, make it a background task (so no dock icon), but then use declares to show the dock icon for the first process (controller).

I experimented with this a while back. I’m sure the solution I came up with at the time was to make the app default to a background process by adding LSUIElement to the plist file. If the app decided it needed a UI it would call the OS to transform into a normal app. Couldn’t say if it was App Store friendly or not.
With OSX 10.9+ I think you are supposed to use setActivationPolicy instead but I have to say that I have never tried it.

We use it in one of our main applications to handle most synchronous actions (like server communication etc). works very well.

We also use it to extract high res images of pages from a PDF Provider (synchronous) which can freeze, sometimes taking a second to retrieve the image, this approach gives the UI a lagg-less/stutter-less feel when navigating the PDF viewer.

Transforming the second instance of the app to a background process can be done with -

dim myProcess as new ProcessMBS
myprocess.GetCurrentProcess
dim success as integer = myProcess.TransformProcessType(myProcess.kProcessTransformToBackgroundApplication)

pros-
Any thread-blocking methods can be moved to the helper process.

Cons -
Debugging this is sometimes cumbersome, having to pre-build an app to invoke the run-paused version.

Thanks Guys; it’s all theory right now. There’s two problems I see.

  1. Is the dock icon.
  2. is that the helper is the main application and so would use as much memory as the main application, which could make it slower to load. Whereas a separate helper is probably more efficient in terms of memory and loading, just not disk space!

I guess I’ll know for sure, when I actually start testing.

[quote=404960:@Sam Rowlands]Thanks Guys; it’s all theory right now. There’s two problems I see.

  1. Is the dock icon.
  2. is that the helper is the main application and so would use as much memory as the main application, which could make it slower to load. Whereas a separate helper is probably more efficient in terms of memory and loading, just not disk space!

I guess I’ll know for sure, when I actually start testing.[/quote]
What’s the problem with the dock icon?

There are a couple of other things to consider:

  1. All of the processes will have the same name.

  2. There was a bug in Xojo where passing command line parameters to a Cocoa app could cause it to crash on quit. Not sure if it has been fixed or not.

  1. Master instance is run as normal, helper app is set to a ‘background process’ in app.open (ProcessMBS can do this)
  2. Your application handles the System.CommandLine in the app.open event (for instance --mode=helper). when an instance of your app sees this in the command line, it runs down a separate code path with very little resource usage, waiting for the master app to communicate with it by whatever means you choose, it then processes it and sits there idle again.

function set_mode
dim s as string = System.CommandLine

for each part as string in s.split(" “)
if part.InStr(”–mode=")>0 then
mode=part.NthField("=",2)
return
end if
next

select case mode
case"helper"
//go down helper route of code (very lightweight)
case else
//normal instance of the app, run main code path
run_helper_app
//etc
end select

function run_helper_app
dim f as folderitem = app.executableFile
dim com_line as string = “–mode=helper”

#if targetWin32
f.launch com_line
#elseif targetMacOS
dim s as new shell
s.mode=0
s.execute f.shellpath+" “+com_line+” >/dev/null 2>&1 &"
#endif

Switching a desktop app to background app (read: no dock icon and menubar) or the otherway around with declares is not allowed for the Appstore.
One of my apps got rejected for this.