Search code examples
objective-claunchd

launchd to run and hide an application


So I have an application 'myApp', and I have a preference to load 'myApp' at login. I have this all running fine via launchd:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
      <string>com.myAppDomain.myApp</string>
    <key>ProgramArguments</key>
      <array>
        <string>/Applications/myApp.app/Contents/MacOS/myApp</string>
      </array>
    <key>RunAtLoad</key>
      <true/>
  </dict>
</plist>

I would also like to give the user the option of also hiding 'myApp'

I tried creating a bash script, and adding to the ProgramArguments array in my lauchd plist:

#!/bin/sh

osascript=/usr/bin/osascript

$osascript -e 'tell application "System Events" to set visible of process "'myApp'" to false'

exit 0

but this either fails to run, or it more likely runs before my app has had a chance to initialise.

Is there an easier way to do this that I am simply overlooking? thanks in advance.


Solution

  • You can just set a bool in your preference plist by calling

    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HideOnLaunch"];
    

    when the user chooses to hide your app on launch.

    Then, when your app is launched via launchd, your app itself can check the HideOnLaunch setting in applicationDidFinishLaunching:, and hide itself accordingly:

    if([[NSUserDefaults standardUserDefaults] boolForKey:@"HideOnLaunch"]){
         [[NSApplication sharedApplication] hide:nil];
    }
    

    Don't let launchd to hide your app!

    Another approach would be the following: You can easily pass an argument to a Cocoa program. As described in this NSUserDefaults document, if you launch a Cocoa app like this:

    AnApp.app/Contents/MacOS/AnApp -FuBar YES
    

    Then you can get the value YES via [[NSUserDefaults standardUserDefaults] boolForKey:@"FuBar"].

    So, depending on the user's preference, you can write a launchd plist setting an argument -HideOnLaunch YES or -HideOnLaunch NO.

    So, in your app delegate, presumably in applicationDidFinishLaunching:, hide your app depending on whether the program argument
    HideOnLaunch is set.