Friday, January 23, 2015

Modern Login Items

Cory Bohon:

Login Items have previously been a way for OS X apps to provide this service to users, but is not compatible with the sandbox requirements of the Mac App Store. Fortunately, there is a much more modern way to handle this, and I’ll walk you through setting it up in your own projects.

[…]

In order to launch our application at login, we’ll create a separate application that is included in the signed main application bundle. The sole purpose and function of this separate application will be to launch our main application at login, if it is not already launched.

[…]

This code uses the ServiceManagement framework’s function called SMLoginItemSetEnabled. The first parameter in this method is a CFString containing the bundle identifier of your Helper application. The second parameter is a BOOL indicating whether the Helper should launch at login or not.

The helper app is required because SMLoginItemSetEnabled() only works with paths inside of the app’s Contents/Library/LoginItems folder.

Tim Schröder:

Consider further that you have successfully implemented such a feature and shipped your application, but now want to update your application to not run in a sandbox anymore. Sounds like a strange turn of things, but this may happen, e.g., if you designed an application to be distributed in the Mac App Store (and shipped it), but now there are compelling reasons to remove the sandbox functionality and to switch to direct distribution outside the Mac App Store.

It is then sensible to provide launch at login functionality no longer via SMLoginItemSetEnabled (and a helper app), but via a shared file list as provided by the Launch Services Framework, which has the distinctive advantage that your application will be visibly marked as launching at login in the System Preferences and that the user can edit this behaviour from the System Preferences (which is not the case with the launch at login functionality providing via SMLoginItemSetEnabled).

Update (2015-01-27): Stephane Sudre says that you may need to call LSRegisterURL() before SMLoginItemSetEnabled().

Dallas Brown reminds that you need to create a separate App ID in the Developer Portal for the helper application and that it should not have the same entitlements as your main application.

2 Comments RSS · Twitter

Last time, I had to deal with the MAS and a LoginItem, you had to register the helper tool via LSRegisterURL before invoking SMLoginItemSetEnabled. Maybe this has changed.

Also an inconvenient consequence of this API hiding the dependency is that it creates (*) issues when the application gets deleted by the user. The architecture will try to automatically launched a helper tool that has been removed (since it's in the app bundle).

Maybe this has been fixed since but it was a bit annoying that due to architecture flaws in this API, you could get angry feedback from users.

There was one big thing missing from Cory’s article though, which can cause serious headaches and app rejections (I was dealing with this just a couple weeks ago), so I posted a follow-up blog post on this topic.

Modern Login Items: Gotcha
http://kdbdallas.com/2015/01/24/modern-login-items-gotcha/

Leave a Comment