My macOS app+helper is not in the System Preferences/Login Item/ "Allow Background" list

I created a macOS app that can run in foreground (NSApplicationActivationPolicyRegular) and in background (NSApplicationActivationPolicyAccessory) and can be launched by an Helper (Login Item) and run in background. I use XCode 15.3 (15E204a) on macOS 14.2.1 on a MacBook Pro 16", 2019, 2,3 GHz Intel Core i9 8 core.

I archive my app, I notarize it for direct distribution then I save it to the /Applications folder. Then I delete my Debug app from …/Xcode/DerivedData/MyApp-dal…xu/Build/Products/Debug so I am sure I have one only copy of my app on the disk.

I firstly launch my app as NSApplicationActivationPolicyRegular then I select my menu item "Set the app as Login Item". So I call

SMAppService *service = [SMAppService loginItemServiceWithIdentifier:@"com.mydomain.Helper"];

I get a

service.status == SMAppServiceStatusNotFound

So I am stuck. I notice that my app doesn't show up in the System Preferences/Login Items/ "Allow Background" list. So on Terminal I run the command

sudo sfltool resetbtm

Now the "Allow Background" apps list is empty. Then I reboot. All the apps listed in "Allow Background" list reappear and are all turned "on". I turn them back off. My app is on the list too (turned "on" too). I leave it on. Now I can launch my app as NSApplicationActivationPolicyRegular, select again my menu item "Set the app as Login Item" and call

SMAppService *service = [SMAppService loginItemServiceWithIdentifier:@"com.domain.Helper"];

Now I get a

service.status == SMAppServiceStatusEnabled

so I install the NSStatusItem and switch to background (NSApplicationActivationPolicyAccessory). I can logout and login and my app gets properly launched by the Helper and run in background. Everything works well.

I guess I miss something,

because I think this is not the way to distribute my app to the customers. I can't ask my customers to run the Terminal command sudo sfltool resetbtm, reboot then turn back "off" all the unwanted apps from the "Allow Background" list then turn my app "on".

Furthermore, if I delete my app, it disappears from the "Allow Background" apps list, then if I copy it back to the /Applications folder, it doesn't show up yet in the "Allow Background" apps list. I have to invoke again the sudo sfltool resetbtm Terminal command, reboot… to see it in that list. I tried on 3 machines with macOS 14.2.1. Same result.

I have read several articles and posts about NSApplicationActivationPolicyAccessory, SMAppService, but I didn't find my case. The Info.plist file of the Helper properly contains

<key>LSBackgroundOnly</key><true/>
<key>LSUIElement</key><true/>

• What do I miss?

• Why my app doesn't show up in the "Allow Background" apps list when I simply copy it within the /Applications folder?

I archive my app, I notarize it for direct distribution then I save it to the /Applications folder. Then I delete my Debug app from …/Xcode/DerivedData/MyApp-dal…xu/Build/Products/Debug so I am sure I have one only copy of my app on the disk.

First off, a general warning around LaunchServices and development machines. Basically, very typical developer workflows often create situations which are WILDLY outside normal customer usage patterns. The same app is being created, version rev'd, deleted, created... over and over again with a volume that is WILDLY beyond what any normal user would ever do. A developer could easily do this 30-100 times a day while a normal app user might not have the app update more than a few times per year.

This can be particularly problematic if you're also using your app (as a user would), not just testing, as now you have multiple versions of the app that are "live" and which the system can't always differentiate very well. SO, a few broad suggestions on all this:

  • Don't assume what you experience is the same as what an actual user would. Use a test machine or a VM to make sure you're not seeing something an actual user wouldn't see.

  • If you're also going to be "using" (not just testing) your app regularly, you may want to consider having a "development bundle ID" and your "distribution bundle ID". Using different bundle IDs means the system won't "entangle" the two different cases, avoid odd edge cases like your development build colliding with the components of your shipping build (or vice versa).

In terms of the specific failure case here:

service.status == SMAppServiceStatusNotFound

What's going on here is that the system is trying to resolve the bundle ID "com.mydomain.Helper" to find the helper. It couldn't find the old helper (you deleted it) and it didn't find the new app version. WHY it didn't find the new app version is hard to speculate/guess at. There are a variety of different mechanisms that trigger registration. In practice, they work really well for normal app usage patterns (which is why you've never really notice them) but, yes, they do sometimes fail ESPECIALLY for developers who are heavily interacting with area of the system.

As a side note here, I believe the reason this works:

sudo sfltool resetbtm

...is that by resetting the list, you forced a rescan of the Applications directory which ended up registering the helper with LaunchServices.

However, what is worth being aware of here is that the most direct way to trigger registration is for the app itself to run. If you have your main app launch it's helper using NSWorkspace before you call "loginItemServiceWithIdentifier" (make sure you let the helper actually finish launching before you call "loginItemServiceWithIdentifier"), I suspect you'll find that the error stops happening.

• Why my app doesn't show up in the "Allow Background" apps list when I simply copy it within the /Applications folder?

Where did you copy it from? I'm not sure if this will work or not, but what happens if you zip the app up, copy the zip file into "Downloads", decompress the zip file inside "Downloads", then copy the app into "/Applications/"?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

My macOS app+helper is not in the System Preferences/Login Item/ "Allow Background" list
 
 
Q