When I develop UI application for OSX I store user's preferences and application config to ~/Library/Preferences/AppName.plist (using NSUserDefaults).

But when I create global background daemon that will be running using launchd on behalf of root - what is the better place to store daemon's config?

On Linux I would put it to the /etc/ directory, but I'm not sure I can do the same on Mac.


Dynamic Paths

On macOS, a process asks the operating system where to save specific types of files using the NSWorkspace method URLForDirectory:inDomain:appropriateForURL:create:error:. There is a CoreFoundation C equivalent function for this method.

This approach mimics the goals of the XDG Base Directory Specification on other platforms.

Typically /Library, however…

Before macOS 10.15, computer wide processes, such as daemons, used the /Library folder structure:

  • For preferences: /Library/Preferences/
  • For cached files: /Library/Cache/
  • For general support and runtime files: /Library/Application Support/

See What is the purpose of each folder under /Library and /System in Mac OS X? for a good overview of the various folders and their intended purpose.

However, macOS 10.15 changes the file structure and limits large parts of the core system read-only. Shipping with fixed file paths and assuming those paths to have read-write access is risky.

| improve this answer | |
  • Great answer, but since I’m not sure how Catalina is going to set up the firm links - I’m going to suggest they use /usr/local/etc which is called out as explicitly going to be in the read/write portion of the read only file system that is coming soon to planet macOS. – bmike Jul 12 '19 at 12:00
  • That is a good point. A good process asks macOS for the appropriate folder and uses the supplied URL. I will extend my answer. – Graham Miln Jul 12 '19 at 12:06
  • 1
    This is even better with the API calls - super useful. – bmike Jul 12 '19 at 12:13

For a very safe option, I would write into /usr/local/etc if you wanted to sandbox / persist a configuration file for your daemon.

Also, it’s totally expected that the daemon would simply have the ability to accept command line arguments when launched and you would then store all of these in the preference list that invokes the system. Then relaunch the daemon when the launchd task gets reloaded allows you to change things up on the system as it’s running.

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .