Error when enabling auto login of macOS app using a helper

MacOS

Question or issue on macOS:

I’m trying to have my app auto launch on login following Tim’s tutorial: http://blog.timschroeder.net/2012/07/03/the-launch-at-login-sandbox-project/

I followed the instructions to the letter but I’m getting an error when I re-login to my computer as follows:

Jan 10 12:55:01 pc61 com.apple.xpc.launchd[1] (com.myApp.macgap.helper[25725]): Could not resolve CFBundleIdentifier specified by service: -10814: com.myApp.macgap.helper
Jan 10 12:55:01 pc61 com.apple.xpc.launchd[1] (com.myApp.macgap.helper): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.

To outline:

Another point worth mentioning, is when I do “Show package content” on the app and double click the helper app, it does launch the main app…

How to solve this problem?

Solution no. 1:

I had the exact same problem just now, and while looking for a solution found this (unanswered) question.

At least in my case, this desired functionality of the worked fine when I copied the app (exported from Xcode as a dev-id signed .app) to a fresh OS X install/account without all my development stuff on it. Of course it must also be in /Applications, as stated in the tutorial referred to in the question.

I am not sure why this feature of the app did not work on my development machine. Perhaps the problem could be due to some form of conflict with all the other near-identical copies of my app I have on disk (I have an archive of different versions of the app, plus the copies Xcode stores itself), all with the same bundle id of course.

Hope this helps in one way or another!

Solution no. 2:

It all comes down to how launchd and launchctl work, as already answered, the regular use case often can be solved by reinstalling the app and ensuring the app is inside the applications folder. But there’s another case that @byb is talking about, when this happens on your development machine – this can be caused by invalid launchd configuration.

When you run SMLoginItemSetEnabled it registers your bundle identifier along with other information in launchd service. At some point later, when your app changes, gets cleaned, or something else happens to it, which gets picked up by launchd, launchd may disable that particular login item. Apparently, sometimes this doesn’t go smoothly, and consecutive calls with SMLoginItemSetEnabled will not work as expected or the agent / helper app simply won’t launch.

The first thing to try is simply changing the bundle identifier for your launcher. If this solves the issue, try figuring out what’s wrong with the original. Run launchctl print-disabled "user/$(id -u)" to display disabled services and login item associations. If the output contains your troubling bundle identifier – you are in luck.

I didn’t find a way of removing disabled services by name using launchctl and had to do it by manually editing configuration files. Because they system-owned, you won’t be able to simply click and edit, instead launch Xcode as root and remove the necessary references.

sudo /Applications/Xcode.app/Contents/MacOS/Xcode "/private/var/db/com.apple.xpc.launchd/loginitems.$(id -u).plist"
sudo /Applications/Xcode.app/Contents/MacOS/Xcode "/private/var/db/com.apple.xpc.launchd/disabled.$(id -u).plist"

Restart, run launchctl print-disabled "user/$(id -u)" to confirm removed items are no longer in the list. Try SMLoginItemSetEnabled again, hopefully now it will work as expected.

Solution no. 3:

I had the same problem, removing other copies of app except one in /Applications solved the problem for me. To remove .app files generated by Xcode you can run Product->Clean.

Solution no. 4:

I was struggling with this for hours. I had many apps with auto login but a new one just did not want to work.

Strangely this worked on the development machine:

  1. Build App as normal
  2. Move it to Application directory
  3. Clean Xcode (CMD+k)!!
  4. Enable auto login in the app.
  5. Logout Login

I accidentally noticed that the system started the app (it tries in every 10 sec) when I clean Xcode 🙂

Solution no. 5:

I can’t find the duplicate copy but did find you can remove the service:

In a terminal window:

launchctl remove com.annoying.service

Solution no. 6:

As it was already stated if there are more then one copies of service bundle on the machine launchd cannot resolve which one must be started by bundle identifier.

What I would recommend to you is find all copies of your service and then remove not desired ones.

For this you need to run following Swift code (It works even in Swift Playground):

import Cocoa

let bundleId = "com.your.bundleId"
let paths = LSCopyApplicationURLsForBundleIdentifier(bundleId as CFString, nil)
print("Available service instances by bundle id: \(paths)")

In my case it produces:

Available service instances by bundle id:
Optional(Swift.Unmanaged<__ObjC.CFArray>(_value: <__NSArrayI 0x6000002234a0>(
file:///Applications/MyApp.app/Contents/Library/LoginItems/MyService.app/,
file:///Users/igor/Library/Developer/Xcode/Archives/2017-12-27/MyApp%2027-12-2017,%2016.06.xcarchive/Products/Applications/MyService.app/
)
))

So I easely identified copy to be removed:

file:///Users/igor/Library/Developer/Xcode/Archives/2017-12-27/MyApp%2027-12-2017,%2016.06.xcarchive/Products/Applications/MyService.app/

Hope it help.

Solution no. 7:

Assuming that you followed Tim Schroeder’s recipe at: http://blog.timschroeder.net/2012/07/03/the-launch-at-login-sandbox-project/ :

What actually ended up working for me, was, in Xcode, to change my main project’s build number from 1 to 2. I also tried a build number of 1000 and that worked fine as well.

In Xcode, select your main project target. Then, select the ‘General’ tab. If you see your Build is set to 1, change it to 2 and then rebuild, redeploy and see if that resolves the issue for you.

This was probably one of the screwiest bugs I have run into, in a while.

Hope this helps!