Question

What is the best way in Cocoa (and Mac OS X) to schedule a program to be run:

  • when the user logs in.
  • at certain times of the day (for example: 12:00 noon).
  • at certain time intervals (for example: every two hours).

Besides scheduling, it should also be easy to un-schedule the program and not cause errors should the user delete the application.

Essentially the program is a satellite command-line executable placed next to the main application's file within the same .app bundle. The program's purpose is to do some background data updates in the user's home directory (within ~/Library/Application Support/MyApp.)

Is crontab a good candidate for this? The man page for crontab said that the functionality has been absorbed to launchctl, but I can't seem to find how to schedule specific times to run the utility.

Thanks.

Was it helpful?

Solution

launchd is the proper way to do this (crontab is deprecated on the Mac in favor of launchd). You'd create a plist file with the information about your program (executable name, arguments, etc), and part of it would be (warning typed in a browser and untested):

<key>StartCalendarInterval</key>
<dictionary>
  <key>Hour</key>
  <integer>12</integer>
</dictionary>

<key>StartInterval</key>
<integer>7200</integer>

<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>RunAtLoad</key>
<true/>
  • The StartCalendarInterval should run your program at the top of the 12th hour (so noon).
  • The StartInterval should run your program every 2 hours (= 7200 seconds)
  • The LimitLoadToSessionType only loads your program when an Aqua session begins (the user actually logs in to the window server (so this would prevent loading if the user ssh's in)
  • The RunAtLoad tells the executable to run when the plist is loaded. This, combined with the LimitLoadToSessionType, should start the executable when the user logs in.

It's possible that StartInterval and StartCalendarInterval are mutually exclusive. If that's the case, you can take out the StartInterval key and change the StartCalendarInterval stuff to:

<key>StartCalendarInterval</key>
<array>
  <dictionary>
    <key>Hour</key>
    <integer>0</integer>
  </dictionary>
  <dictionary>
    <key>Hour</key>
    <integer>2</integer>
  </dictionary>
  <dictionary>
    <key>Hour</key>
    <integer>4</integer>
  </dictionary>
  <dictionary>
    <key>Hour</key>
    <integer>6</integer>
  </dictionary>
  ...
  <dictionary>
    <key>Hour</key>
    <integer>12</integer>
  </dictionary>
  ...
  <dictionary>
    <key>Hour</key>
    <integer>22</integer>
  </dictionary>
</array>

For more information, see man launchd.plist.

OTHER TIPS

There is a nice GUI app called Lingon which helps with editing launchd configuration files. You can download it here > Lingon

On Mac OS X you can run "crontab -e" in the Terminal to start the crontab editor (Vi by default). When you quit the editor, the job is scheduled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top