NSUser Defaults Sync

Hi guys, I’m having a weird problem with NSUserDefaults. It works fine except on the initial launch it won’t save any preferences. (After that its fine)

Im wondering if this is the correct way to call the “synchronize” command in applescript syntax?

    tell NSUserDefaults
        tell its standardUserDefaults()
            its synchronize()
        end tell
    end tell

Thanks folks. :smiley:

I have the property declared at the top of the file.

    property NSUserDefaults : class "NSUserDefaults" of current application

You should never have to use the synchronize() method. What are you trying to do?

Im using it to store the user preferences for an app that automatically sends save commands to Logic Pro.

Previously I had just been writing the users defined time to a text file but I figured NSUserDefaults would be a bit more solid in the long run.

This is the code to save the user defined time between saves.

    on buttonClicked_(sender)

        set timeSet to text_field's integerValue() * 60 -- converts minutes to seconds for the script
        if timeSet is greater than or equal to 60 then

tell NSUserDefaults
    tell its standardUserDefaults()
        its setInteger_forKey_(timeSet, "userTimeBetweenSaves")
    end tell
end tell

        display dialog "Times less then 1 minute are not reccomended." with icon 2 buttons {"Ok"} default button 1
            		Close access prefs_file
        end if
    end buttonClicked_

Here is the code to retrieve it. Also it checks if the prefs file exists and if not creates one.

on awakeFromNib()
   ----------------------RETRIEVE VALUE FROM PREFS AND CHECK IF THEY EXIST--------------

tell NSUserDefaults
    tell its standardUserDefaults()
        set timetoSave to its integerForKey_("userTimeBetweenSaves")
    end tell
end tell

if timetoSave is less than 60 then
    log "creating initial prefs file"
    set prefFile to open for access (path to preferences as text) & "com.davidmckeitchsoundservices.autosaveforlogicpro.plist"
    close access prefFile

    tell NSBundle--get plist file location and bundle identifier
        tell its mainBundle()
            set preffile to (its pathForResource_ofType_("defaults", "plist")) as string --gets text file containing default prefs
        end tell
    end tell
    set userDefaults to NSUserDefaults's standardUserDefaults()
    userDefaults's registerDefaults_(NSDictionary's dictionaryWithContentsOfFile_(preffile))
    tell text_field to setIntegerValue_(5)


tell text_field to setIntegerValue_(timetoSave / 60)

end if

The problem i was having was that when nothing existed the app would see the timetoSave value as “0” and would just constantly save. At the moment with the above code this problem is solved but now it does not save the values the user enters on the first launch of the app.

Ive read that NSUserDefaults does not need a plist file to save too…but I couldnt get it working without one hence why I create one.

Any advice here appreciated! Cheers.

I’m afraid you’re misunderstanding how they work. The steps are: (a) you set defaults, using registerDefaults_, (b) you read values using a key, and (c) you write values using a key. User defaults does the rest.

So you start of registering defaults as soon as you launch; these will only be used if you’ve never changed them:

set defaults to current application's NSUserDefaults's standardUserDefaults()
defaults's registerDefaults_({userTimeBetweenSaves:60})

Then you get the value to use, which will be either the default or the last value stored:

set timeToSave to defaults's objectForKey_("userTimeBetweenSaves")

And you store any new values like this:

defaults's setObject_forKey_(newValue, "userTimeBetweenSaves")

Cheers Stanley that clarifies things. Must cleaner code as well. :smiley:

Will give it a shot and see how it goes.

It seems to be storing the defaults while the app is running but forgets them after the app is closed. Is there something I should be doing to write them to the disk perhaps?

on awakeFromNib()
   ----------------------RETRIEVE VALUE FROM PREFS AND CHECK IF THEY EXIST--------------

set defaults to current application's NSUserDefaults's standardUserDefaults()
defaults's registerDefaults_({userTimeBetweenSaves:300, userHideInactiveMenuButton:0, userPausePrefs:0})
set timeToSave to defaults's integerForKey_("userTimeBetweenSaves")
tell text_field to setIntegerValue_(timeToSave / 60)

set userHideInactiveMenuButtonPrefs to defaults's integerForKey_("userHideInactiveMenuButton")
tell hideInactiveMenuButton to setState_(userHideInactiveMenuButtonPrefs)
defaults's setObject_forKey_(0, "userPausePrefs")

     -------------------END RETRIEVE VALUE FROM PREFS AND CHECK IF THEY EXIST--------------

No, that happens automatically. How do you know they are not being saved?

When I quit and reopened the app it would forget the settings.

It seems to have been a problem related to sandboxing. I tried the app unsandboxed and it works fine.

Could maybe be a permission problem preventing the app from saving the file, will look into it. I think it may be getting prevented from creating the plist file. (Hence why i had to force it before)

May just remove the sandboxing all together, had set it up incase I ever wanted to submit to the app store but I don’t think this particular app will ever fit in apples rules anyway!

Thanks again for your help shane!

Sandboxing shouldn’t affect that; it just gets saved to a different file. (The app doesn’t save the .plist file – it’s done by a separate daemon.)

Yeah the only difference seems to be that it saves to the default preferences folder rather then a container. Not sure why it seems to be making a difference. Will keep looking into it.