10
votes

I have installed the Pre-Release version of Mac OSX Mavericks(10.9). My application contains

  NSUserDefaults *preferences = [[NSUserDefaults standardUserDefaults] retain];
    [preferences setInteger:[_lblSetValue integerValue] forKey:@"execute"];
[defaults synchronize];

As NSUserDefauls Store its value in the Plist File at Library -> Preferences -> appbundlename.plist .. If I changed the value in the Plist File.. and again starts the application and access the value by:

id abc = [preferences valueForKey:@"execute"];

then It gives me the previous value not the finally changed value. As I check it again in the Plist file the changes value is saved.

Example:

Like Initially I have set the value 1234 for key execute and then stopes the application and changed the value in the Plist file at it Path Library -> Preferences -> appbundlename.plist to 1000, and starts the application again and access its value by

 id abc = [preferences valueForKey:@"execute"];

it gives me 1234 not 1000. Then.. The Question is.. From where the value is accessed if the changed value is not taken by the method valueForKey.?

I need to get the changed value of the Plist. As it give me right value in Loin/Mountain Loin but not in mavericks.

Please help.

5

5 Answers

12
votes

My work-around for this problem is to kill the 'cfprefsd' daemon processes after making a change to the .plist file:

ps auwx | grep cfprefsd | grep -v grep | awk '{print $2}' | xargs sudo kill -9

The daemons will be restarted after the next access of the .plist file and will then have the new value for the key that was changed.

It is unfortunate that this work-around is necessary but at least it works reliably.

5
votes

This one made me feel like I was using a completely different OS (i.e. not Apple).

What may be happening is that Mavericks changed the way user defaults are stored. So, if you go and delete the plist file you'll mess up the user defaults for that app.

The proper way to delete a container (that contains your plist file) is to use 'defaults' from Terminal. I haven't checked to see if simply deleting using 'defaults' will work properly.

To 'fix' my issue I had to (gulp) restart Mavericks. This will clear the NSUserDefaults cache and only then, will NSUserDefaults function correctly. Note: I've read that a logout/login may also work.

Hope that helps. Kevin

4
votes

On Mavericks apps have Containers, where the settings are stored in there instead, OSX copies the preferences from the app's container into the ~/Library/Preferences/com.example.myapp.plist if it's not found.

but your issue is that precedence will always go to the .plist file in the app's container, and eventually the ~/Library/Preferences/*.plist will be either ignored or overwritten.

to do things properly always use the terminal tool defaults

open up your terminal and try this:

defaults read com.example.myapp

It'll shoot out the correct defaults, the tool is also used for editing and creating plist files, you can just

defaults usage

to learn how it works.

if you're still curious where the app container is, just CD into :

~/Library/Containers/com.example.myapp/Data/Library/Preferences/

You'll find it there, but you don't really need to edit that manually, and always remember that it'll overwrite/get precedence over the plist in ~/Library/Preferences.

you may read more about it in my blog post

2
votes

not sure if it's still of interest to anyone, but running killall -SIGTERM cfprefsd in the Terminal helped me resolve the issue. (not sure if the customers experiencing "preferences not saving" issue have to do the same).. Here are some apple dev forum links to support my claim :)

https://devforums.apple.com/message/909771#909771

https://devforums.apple.com/message/906841#906841

Hope it helps.

0
votes

Are you calling [defaults synchronize]; after setting the key

Generally, preferences are persisted for you at the opportune time, but if you are setting it and then accessing it soon after you may need to do this to force the save.

But if you are doing it that quickly, I'm starting to doubt that you are using it to save a preference. If you are doing this to pass state around your program, then there are better ways that using NSUserDefaults.