# Storing app preferences / data for all users

**URL:** <https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434>\
**Category:** macOS\
**Created:** [May 8, 2019, 3:29pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434 "2019-05-08T15:29:02Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 8, 2019, 3:29pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/1 "2019-05-08T15:29:02Z")

</div>

I have a non-MAS, non-sandboxed mac app. The app needs to be able to read a small configuration string that is global to all users on the machine. The app is installed by an installer which will run with admin permissions.

In the old days, people may have modified a file inside the app bundle itself, but we know that’s not a good idea due to code-signing issues.

What’s the current best practices way do do this?

- Adding a plist file to /Library/Application Support/MyApp
- using the defaults command with globalDoman?

```auto
 defaults write -globalDomain MyAppSpecialKey foobar
```

- something else?

---

<div class="post-metadata">

**Author:** ![Tim\_Parnell](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_parnell/32/161_2.png) [@Tim\_Parnell](https://forum.xojo.com/u/Tim_Parnell)\
**Post date:** [May 8, 2019, 4:04pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/2 "2019-05-08T16:04:06Z")

</div>

It looks like `SpecialFolder.SharedDocuments` will get you to `/User/Shared/` on macOS. You should be able to treat that like Application Support, make a subfolder for yourself and work within that.

---

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 10, 2019, 3:08pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/3 "2019-05-10T15:08:42Z")

</div>

Thanks Tim.

I’d really like to use the CFPreferences system if possible (because my app already does that).

If I poke around on my system, I notice that other apps seem to do this, for example BBEdit has a plist file in two places:

```auto
/Users/username/Library/Preferences/com.barebones.bbedit.plist 
and
/Library/Preferences/com.barebones.bbedit.plist 
```

It looks like you can access plists using the ‘defaults’ command by providing a specific path name (although there is a warning about this changing ‘in an upcoming major release’):

```auto
     filepath Domains may also be specified as a path to an arbitrary plist file, with or without the '.plist' extension. For
               example:

                     defaults read ~/Library/Containers/com.apple.TextEdit/Data/Library/Preferences/com.apple.TextEdit.plist

               normally gives the same result as the two previous examples. In the following example:

                     defaults write ~/Desktop/TestFile foo bar

               will write the key 'foo' with the value 'bar' into the plist file 'TestFile.plist' that is on the user's desk-
               top. If the file does not exist, it will be created. If it does exist, the key-value pair will be added, over-
               writing the value of 'foo' if it already existed.

               WARNING: The defaults command will be changed in an upcoming major release to only operate on preferences
               domains. General plist manipulation utilities will be folded into a different command-line program.
```

So I think the solution for now is to do something like this:

```auto
  dim sh as new shell
  dim cmd as string = "/usr/bin/defaults read /Library/Preferences/com.mycompany.myapp " + key
  dim value = sh.execute(cmd)
```

---

<div class="post-metadata">

**Author:** ![Norman\_Palardy](https://forum.xojo.com/user_avatar/forum.xojo.com/norman_palardy/32/169_2.png) [@Norman\_Palardy](https://forum.xojo.com/u/Norman_Palardy)\
**Post date:** [May 10, 2019, 4:19pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/4 "2019-05-10T16:19:54Z")

</div>

you should use the DOMAIN parameter instead of a path name

and you might use PlistBuddy instead of defaults as things have changed with defaults in ways that nay affect this

---

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 10, 2019, 7:04pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/5 "2019-05-10T19:04:48Z")

</div>

[quote=435801:@Norman Palardy]you should use the DOMAIN parameter instead of a path name

and you might use PlistBuddy instead of defaults as things have changed with defaults in ways that nay affect this[/quote]

Say more? I can’t see a way to use the domain parameter to distinguish between the two locations (/Library/Preferences vs. /Users/[username]/Library/Preferences )

---

<div class="post-metadata">

**Author:** ![Norman\_Palardy](https://forum.xojo.com/user_avatar/forum.xojo.com/norman_palardy/32/169_2.png) [@Norman\_Palardy](https://forum.xojo.com/u/Norman_Palardy)\
**Post date:** [May 11, 2019, 12:57am UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/6 "2019-05-11T00:57:15Z")

</div>

user domain means user specific so it goes in ~/Library/Preferences/etc etc etc  
global domain means all users /Library/Preferences/etc etc etc

---

<div class="post-metadata">

**Author:** ![Beatrix\_Willius](https://forum.xojo.com/user_avatar/forum.xojo.com/beatrix_willius/32/282_2.png) [@Beatrix\_Willius](https://forum.xojo.com/u/Beatrix_Willius)\
**Post date:** [May 11, 2019, 5:40am UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/7 "2019-05-11T05:40:43Z")

</div>

Why are you mucking around with the defaults command? There are several better ways around (macoslib, MBS, etc).

---

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 11, 2019, 3:28pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/8 "2019-05-11T15:28:54Z")

</div>

[quote=435837:@Norman Palardy]user domain means user specific so it goes in ~/Library/Preferences/etc etc etc  
global domain means all users /Library/Preferences/etc etc etc[/quote]

I thought this was the case, too - but it doesn’t work, which is why I wrote this question.

If you don’t believe me, try it:

```auto
# this creates ~/Library/Preferences/com.foobar.plist and sets the key foo=bar
defaults write com.foobar foo bar

# you would expect this to do the same in /Library/Preferences/com.foobar.plist
# but it fails with an error
sudo defaults write -g com.foobar foo bar
```

It turns out the global domain is actualy Global Global - e.g. it’s a single plist that applies system-wide (e.g. it’s not a global domain that works for a single com.myapp domain)

---

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 11, 2019, 3:32pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/9 "2019-05-11T15:32:27Z")

</div>

> [@435853:@Beatrix Willius](#):
>
> Why are you mucking around with the defaults command? There are several better ways around (macoslib, MBS, etc).

One reason: an Installer app which needs to set preferences in two locations - the “all users” location requires administration permissions, which is easy to do using the command line with the AuthorizationMBS tool.

Another reason: I simply want to find out how it all works so it can be documented, so that people can use CFPreferences or ‘defaults’ as needed.

---

<div class="post-metadata">

**Author:** ![Mike\_D](https://forum.xojo.com/user_avatar/forum.xojo.com/mike_d/32/266_2.png) [@Mike\_D](https://forum.xojo.com/u/Mike_D)\
**Post date:** [May 11, 2019, 3:49pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/10 "2019-05-11T15:49:01Z")

</div>

After more research, here’s what I’ve found.

On macOS there are actually several different locations, and the terminology is confusing/inconsistent.

When using the /usr/bin/defaults tool:

```auto

# to save data for the current user
defaults write com.foobar foo bar # writes to ~/Library/Preferences/com.foobar.plist 

# to save data for all users (requires authentication)
sudo defaults write /Library/Preferences/com.foobar foo bar # writes to /Library/Preferences/com.foobar.plist 

# to save data available for the current user only on the current host (e.g. the current physical machine)
defaults -currentHost write com.foobar foo bar # writes to ~/Library/Preferences/ByHost/com.foobar.[GUID].plist where [GUID] is a guid of the current mac

# to save data in a truly global namespace (note: be careful, as you risk key collisions with other apps, you probably should NOT do this!!!
sudo defaults write -globalHost foo bar # writes foo=bar to /Library/Preferences/GlobalPreferences.plist (which is a hidden file)

```

If you are reading/writing these keys using CFPreferences, the following combinations work:

```auto
    // this is Swift code but could be adopted to whatever declare/plugin you are using in Xojo
    // bundleID should be in the com.mycompany.myapp format
       # reads data for a single user from ~/Library/Preferences/bundleID.plist
        let val = CFPreferencesCopyAppValue(key as CFString, bundleID as CFString)
        
       # reads data for all users from /Library/Preferences/bundleID.plist
        let val = CFPreferencesCopyValue(key as CFString, bundleID as CFString, kCFPreferencesAnyUser, kCFPreferencesAnyHost)

       # reads data for a single user and single machine from ~/Library/Preferences/ByHost/bundleID.[GUID].plist
        let val = CFPreferencesCopyValue(key as CFString, bundleID as CFString, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)

```

Additional notes:

- Do not try to set keys by writing the plist files as text files - this sometimes works, but often fails, becuase the plist files are really just shadow copies of the OS’s internal database system.
- to set keys in /Library/Preferences you need to authenticate, but to read these keys an app doesn’t need any special permissions.

---

<div class="post-metadata">

**Author:** ![Sam\_Rowlands](https://forum.xojo.com/user_avatar/forum.xojo.com/sam_rowlands/32/265_2.png) [@Sam\_Rowlands](https://forum.xojo.com/u/Sam_Rowlands)\
**Post date:** [May 13, 2019, 12:43am UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/11 "2019-05-13T00:43:24Z")

</div>

> [@435898:@Michael Diehr](#):
>
> Do not try to set keys by writing the plist files as text files - this sometimes works, but often fails, becuase the plist files are really just shadow copies of the OS’s internal database system.

Since macOS 10.9; Apple have advised against manually editing preference files (even if the application doesn’t use NSUserDefaults/CFPrefs).

Even deleting a preferences file to “reset” an apps preferences now causes problems. I’ve personally experienced the prefs getting frozen, can’t be changed via API or manual editing. Killing the daemon doesn’t help, only solution is to restart the machine.

---

<div class="post-metadata">

**Author:** ![system](https://forum.xojo.com/uploads/default/original/1X/455b4dcc0e61630e9f81940004ddffa49c432a46.png) [@system](https://forum.xojo.com/u/system)\
**Post date:** [April 29, 2021, 3:55pm UTC](https://forum.xojo.com/t/storing-app-preferences-data-for-all-users/48434/12 "2021-04-29T15:55:59Z")

</div>


