On reboot, two instances of faceless app

We have a containing app for our network extension; it's set up as a faceless app and run as a LaunchAgent. It works rather well, we're happy with it.

Except sometimes, possibly only on M1's, on reboot, it'll show up twice. Our name in the plist is com.kithrup.appName -- simple enough. On reboot, launchctl list shows two com.kithrup jobs -- and the extra one is application.com.kithrup.appName.3238445.3238450.

Anyone have any idea about this?

the extra one is

That job label format is used for the transient jobs created by Launch Services. For example, if you launch TextEdit from the Finder, you’ll see something like this:

% launchctl list | grep TextEdit
41199	0	application.com.apple.TextEdit.1152921500311959876.1152921500311959881

It’s likely that the system is launching your app on login as part of macOS’s transparent application lifecycle feature.

Your container app should be a standard app. Running it as a launchd agent is likely to cause problems. If your NE provider needs agent help, create a separate agent and embed that within your container app.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How can I get the system to not run it on login as part of the transparent application lifecycle feature? (This particular issue, btw, may end up being a single person's machine. Since they have installed & deleted & upgraded the app more than even I have, I suspect there's some crumbs left over.)

It's a LaunchAgent because it needs to be run for every user, on login. I initially had the agent invoke the containing app if necessary, but then I realized it was simply duplicating a lot of code and behaviour, and I could simply embed the network extension in the agent.

The only problem I've run into so far has been with fast user switching and the system weirdly trying to reload the extension.

How can I get the system to not run it on login as part of the transparent application lifecycle feature?

I’m not sure you can. This is meant to be under the control of the user. For example, if the user chooses Apple > Restart, the confirmation alert has a “Reopen windows when logging back in” checkbox.

It's a LaunchAgent because it needs to be run for every user, on login.

Right, but I wasn’t suggesting that you give up on running an agent, but rather that you create a dedicated agent instead of running your main app as an agent.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I’m not sure you can. This is meant to be under the control of the user. For example, if the user chooses Apple > Restart, the confirmation alert has a “Reopen windows when logging back in” checkbox.

I really thought I remembered a way to opt out -- but I thought that was part of AppDelegate and I can't find anything there. (I thought it was something like appShouldRestoreState.

that you create a dedicated agent instead of running your main app as an agent.

The only thing the applet does is load and monitor the extension (oh, it also shows some state information, I guess). So given that it would have to always launch a containing app, which would then need to be a faceless app on its own, and which would need to be relaunched if/when it crashed or was killed, that didn't seem too feasible. Especially since we still can't ship a product using Endpoint Security.

The only thing the applet does is load and monitor the extension (oh, it also shows some state information, I guess). So given that it would have to always launch a containing app, which would then need to be a faceless app on its own, and which would need to be relaunched if/when it crashed or was killed, that didn't seem too feasible.

I don’t understand this. To start, you’ve switch to the term “applet”, which isn’t something I recognise in this context. I suspect you mean “agent”. Please confirm.

Assuming that, I’m not sure why you need a second faceless app. Your agent is running in the GUI context and can do everything that needs to be done in that context. If you want the agent to, say, show a menu bar status item, just create an AppKit app, tag it as a UI element (LSUIElement), and start it as an agent by pointing launchd at the app’s main executable.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

My apologies; I forget I tend to rotate through my terms like BIND and A records.

I use the term "applet" to mean an application which only shows up as a menu-bar item. Typically fairly small, our case isn't really any different, except that I rolled the extension loading code into it. It does a few things, including showing status, and ensuring that the extension stays loaded and running when it is intended to. I would prefer to have that capability in a daemon, but Apple insists that the network extension be loaded by an app that lives in /Applications and has the ability to (indirectly) invoke user interaction.

Because we need it to run for each user, and not be (easily 😄) quittable (being a security-focused product), it is started as a LaunchAgent.

So that's a single application. Just faceless, interacted via the menubar, and does the extension loading/unloading.

(There's a bunch of other stuff, such as we need it to keep track of the extension's status because of crashes, and because on upgrades we sometimes get into a state where we can no longer communicate with it via XPC so we need to unload and reload it, so we need to have something ping it to check that, and so forth, and so forth, and so forth.)

Does that make more sense?

And I still can't figure out why it's happening. Or, more importantly, how to stop it. The spurious one can be quit, at least, but I'm not seeing any reason why it would be re-launched on login.

I filed FB11522305 about this.

On reboot, two instances of faceless app
 
 
Q