Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Login Item - cocoa

Tags:

swift

cocoa

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).

like image 883
mdmb Avatar asked Dec 06 '25 14:12

mdmb


1 Answers

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.

like image 152
vadian Avatar answered Dec 11 '25 07:12

vadian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!