Skip to content

Instantly share code, notes, and snippets.

@plapier
Created May 23, 2015 23:45
Show Gist options
  • Save plapier/f8e1dde1b1624dfbb3e4 to your computer and use it in GitHub Desktop.
Save plapier/f8e1dde1b1624dfbb3e4 to your computer and use it in GitHub Desktop.
Add Login item using Launch Services (Shared List File) in Swift
//
// toggleLaunchAtStartup.swift
// Recents
//
// Created by Phil LaPier on 5/21/15.
// Copyright (c) 2015 Philip LaPier. All rights reserved.
//
// With help from: https://github.com/RamonGilabert/Prodam/blob/master/Prodam/Prodam/LaunchStarter.swift
import Foundation
func applicationIsInStartUpItems() -> Bool {
return (itemReferencesInLoginItems().existingReference != nil)
}
func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItemRef?, lastReference: LSSharedFileListItemRef?) {
if let appURL : NSURL = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
if let loginItemsRef = LSSharedFileListCreate(nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue() as LSSharedFileListRef? {
let loginItems: NSArray = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
let lastItemRef: LSSharedFileListItemRef = loginItems.lastObject as! LSSharedFileListItemRef
for (index, loginItem) in enumerate(loginItems) {
let currentItemRef: LSSharedFileListItemRef = loginItems.objectAtIndex(index) as! LSSharedFileListItemRef
if let itemURL = LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, nil) {
if (itemURL.takeRetainedValue() as NSURL).isEqual(appURL) {
return (currentItemRef, lastItemRef)
}
}
}
return (nil, lastItemRef)
}
}
return (nil, nil)
}
func toggleLaunchAtStartup() {
let itemReferences = itemReferencesInLoginItems()
let shouldBeToggled = (itemReferences.existingReference == nil)
if let loginItemsRef = LSSharedFileListCreate( nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue() as LSSharedFileListRef? {
if shouldBeToggled {
if let appUrl : CFURLRef = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
println("Add login item")
LSSharedFileListInsertItemURL(loginItemsRef, itemReferences.lastReference, nil, nil, appUrl, nil, nil)
}
} else {
if let itemRef = itemReferences.existingReference {
println("Remove login item")
LSSharedFileListItemRemove(loginItemsRef,itemRef);
}
}
}
}
@kmikiy
Copy link

kmikiy commented May 21, 2017

Updated to swift 3

import Foundation

func applicationIsInStartUpItems() -> Bool {
    return (itemReferencesInLoginItems().existingReference != nil)
}

func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItem?, lastReference: LSSharedFileListItem?) {
    if let appURL : NSURL = NSURL.fileURL(withPath: Bundle.main.bundlePath) as NSURL {
        if let loginItemsRef = LSSharedFileListCreate(nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue() as LSSharedFileList? {
            
            let loginItems: NSArray = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
            let lastItemRef: LSSharedFileListItem = loginItems.lastObject as! LSSharedFileListItem
            
            for (index, loginItem) in loginItems.enumerated() {
                let currentItemRef: LSSharedFileListItem = loginItems.object(at: index) as! LSSharedFileListItem
                if let itemURL = LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, nil) {
                    if (itemURL.takeRetainedValue() as NSURL).isEqual(appURL) {
                        return (currentItemRef, lastItemRef)
                    }
                }
            }
            
            return (nil, lastItemRef)
        }
    }
    
    return (nil, nil)
}

func toggleLaunchAtStartup() {
    let itemReferences = itemReferencesInLoginItems()
    let shouldBeToggled = (itemReferences.existingReference == nil)
    if let loginItemsRef = LSSharedFileListCreate( nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue() as LSSharedFileList? {
        if shouldBeToggled {
            if let appUrl : CFURL = NSURL.fileURL(withPath: Bundle.main.bundlePath) as CFURL {
                print("Add login item")
                LSSharedFileListInsertItemURL(loginItemsRef, itemReferences.lastReference, nil, nil, appUrl, nil, nil)
            }
        } else {
            if let itemRef = itemReferences.existingReference {
                print("Remove login item")
                LSSharedFileListItemRemove(loginItemsRef,itemRef);
            }
        }
    }
}

@chigkim
Copy link

chigkim commented Feb 20, 2018

Would you mind update to Swift 4?

@andrewcrook
Copy link

anyone know of a LSSharedFileListCreate replacement ?

@plapier
Copy link
Author

plapier commented Feb 12, 2025

@andrewcrook It appears LaunchServices now has a new API called SMAppService. More instructions here for similar functionality 👉 https://nilcoalescing.com/blog/LaunchAtLoginSetting/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment