Is there a way to check if the login item already exists (with bundleIdentifier of the app?) I want to be able to see if there is a login item and if it is enable. I was trying to check my checkbox in applicationDidFinishLuanching when the login item is enabled using this:
if (SMLoginItemSetEnabled(("bundleIDOfMyApp" as CFStringRef), true)) {
self.startAtLoginButton.state = 1
} else {
self.startAtLoginButton.state = 0
}
It does its thing, but it also launches my helper application.
Another thing is this:
@IBAction func startAtLoginButtonChecked(sender: NSButton) {
var enabled = false
if sender.state == 0 { enabled = false }
if sender.state == 1 { enabled = true }
if !SMLoginItemSetEnabled(("bundleIDOfMyApp" as CFStringRef), enabled) {
print("Login was not successful")
}
}
As far as I am concerned this is the way you implement checkbox to enable/disable login item.
What it does in my app is every time I check the box it launches the helper app (which launches my app again).
Although the method SMCopyAllJobDictionaries() is deprecated this is the usual way to check if the job is enabled, SMLoginItemSetEnabled is only be used to set the value
import ServiceManagement
let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as NSArray as! [[String:AnyObject]]
let label = "bundleIDOfMyApp"
let jobEnabled = jobDicts.filter { $0["Label"] as! String == label }.isEmpty == false
The double casting is needed to cast CFArray to NSArray and then to Array<String,AnyObject>
Also usually the checkbox is bound to a property via KVC. The lines above are the getter and SMLoginItemSetEnabled is the setter for example
let helperBundleIdentifier = "bundleIDOfMyApp"
@available(OSX, deprecated=10.10) // this line suppresses the 'deprecated' warning
dynamic var startAtLogin : Bool {
get {
guard let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as NSArray as? [[String:AnyObject]] else { return false }
return jobDicts.filter { $0["Label"] as! String == helperBundleIdentifier }.isEmpty == false
} set {
if !SMLoginItemSetEnabled(helperBundleIdentifier, newValue) {
print("SMLoginItemSetEnabled failed.")
}
}
}
Swift 3:
@available(OSX, deprecated: 10.10)
dynamic var startAtLogin : Bool {
get {
guard let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as? [[String:Any]] else { return false }
return jobDicts.first(where: { $0["Label"] as! String == helperBundleIdentifier }) != nil
} set {
if !SMLoginItemSetEnabled(helperBundleIdentifier as CFString, newValue) {
print("SMLoginItemSetEnabled failed.")
}
}
}
Side note: A launchd job requires the key Label so it's 100% safe to unwrap the optional in the filter function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With