(This solution is intended only for applications without a sandbox. The LSSharedFile functions used in this solution are available only for applications without a sandbox.)
You are using a list of shared Session Login Items files. This is the list that appears in System Preferences when you check the login items in your profile settings.
A typical application scenario is to check the application settings box, which allows the user to choose whether they want to run the application or not when they log in. If you intend to distribute through the app store, DO NOT install the application to start when you log in by default. You will be rejected :)
So, in this scenario, we will create a property, say in the App Delegate, with the name launchOnLogin, and we will associate the checkbox value with this property.
The getter method will check if our application package identifier is in the general list and will return true or false.
The setter method advertises or removes an item from the general list.
Here it is:
Appdelegate.h
@property (atomic, assign) BOOL launchOnLogin;
AppDelegate.m
- (BOOL)launchOnLogin { LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); CFArrayRef snapshotRef = LSSharedFileListCopySnapshot(loginItemsListRef, NULL); NSArray* loginItems = [NSMakeCollectable(snapshotRef) autorelease]; NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; for (id item in loginItems) { LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)item; CFURLRef itemURLRef; if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) { NSURL *itemURL = (NSURL *)[NSMakeCollectable(itemURLRef) autorelease]; if ([itemURL isEqual:bundleURL]) { return YES; } } } return NO; } - (void)setLaunchOnLogin:(BOOL)launchOnLogin { NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); if (launchOnLogin) { NSDictionary *properties; properties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"com.apple.loginitem.HideOnLaunch"]; LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsListRef, kLSSharedFileListItemLast, NULL, NULL, (CFURLRef)bundleURL, (CFDictionaryRef)properties,NULL); if (itemRef) { CFRelease(itemRef); } } else { LSSharedFileListRef loginItemsListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); CFArrayRef snapshotRef = LSSharedFileListCopySnapshot(loginItemsListRef, NULL); NSArray* loginItems = [NSMakeCollectable(snapshotRef) autorelease]; for (id item in loginItems) { LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)item; CFURLRef itemURLRef; if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) { NSURL *itemURL = (NSURL *)[NSMakeCollectable(itemURLRef) autorelease]; if ([itemURL isEqual:bundleURL]) { LSSharedFileListItemRemove(loginItemsListRef, itemRef); } } } } }
This is pretty much it. Now, if you make the binding and everything is correct, you will see how your application appears and disappears from the list of system settings in real time.
The part that actually launches the application at login
Please note that the code above is a save / release, but it's pretty simple to convert it to ARC if you need it.
Hope this helps.