{"id":10564,"date":"2015-01-23T14:04:38","date_gmt":"2015-01-23T19:04:38","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=10564"},"modified":"2015-01-27T10:42:20","modified_gmt":"2015-01-27T15:42:20","slug":"modern-login-items","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2015\/01\/23\/modern-login-items\/","title":{"rendered":"Modern Login Items"},"content":{"rendered":"<p><a href=\"http:\/\/martiancraft.com\/blog\/2015\/01\/login-items\/\">Cory Bohon<\/a>:<\/p>\n<blockquote cite=\"http:\/\/martiancraft.com\/blog\/2015\/01\/login-items\/\">\n<p>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&rsquo;ll walk you through setting it up in your own projects.<\/p>\n<p>[&#8230;]<\/p>\n<p>In order to launch our application at login, we&rsquo;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.<\/p>\n<p>[&#8230;]<\/p>\n<p>This code uses the <code>ServiceManagement<\/code> framework&rsquo;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 <code>BOOL<\/code> indicating whether the Helper should launch at login or not.<\/p>\n<\/blockquote>\n<p>The helper app is required because <a href=\"https:\/\/developer.apple.com\/library\/mac\/documentation\/ServiceManagement\/Reference\/SMLoginItem_header_reference\/index.html#\/\/apple_ref\/c\/func\/SMLoginItemSetEnabled\">SMLoginItemSetEnabled()<\/a> only works with paths inside of the app&rsquo;s <tt>Contents\/Library\/LoginItems<\/tt> folder.<\/p>\n<p><a href=\"http:\/\/blog.timschroeder.net\/2013\/04\/21\/smloginitemsetenabled-demystified\/\">Tim Schr&ouml;der<\/a>:<\/p>\n<blockquote cite=\"http:\/\/blog.timschroeder.net\/2013\/04\/21\/smloginitemsetenabled-demystified\/\"><p>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. <\/p>\n<p>It is then sensible to provide launch at login functionality no longer via SMLoginItemSetEnabled (and a helper app), but <a href=\"http:\/\/rhult.github.io\/preference-to-launch-on-login.html\">via a shared file list<\/a> 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 (<a href=\"http:\/\/stackoverflow.com\/questions\/14811425\/using-smloginitemsetenabled-app-does-not-show-under-login-items\">which is not the case with the launch at login functionality providing via SMLoginItemSetEnabled<\/a>).<\/p>\n<\/blockquote>\n<p>Update (2015-01-27): <a href=\"http:\/\/mjtsai.com\/blog\/2015\/01\/23\/modern-login-items\/#comment-2355304\">Stephane Sudre<\/a> says that you may need to call <code>LSRegisterURL()<\/code> before <code>SMLoginItemSetEnabled()<\/code>.<\/p>\n<p><a href=\"http:\/\/kdbdallas.com\/2015\/01\/24\/modern-login-items-gotcha\/\">Dallas Brown<\/a> reminds that you need to create a separate App ID in the Developer Portal for the helper application and that it should <em>not<\/em> have the same entitlements as your main application.<\/p>","protected":false},"excerpt":{"rendered":"<p>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&rsquo;ll walk you through setting it up in your own projects. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[30,39,71,53],"class_list":["post-10564","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-mac","tag-macappstore","tag-programming","tag-sandboxing"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/10564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=10564"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/10564\/revisions"}],"predecessor-version":[{"id":10606,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/10564\/revisions\/10606"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=10564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=10564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=10564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}