user defaults

If I’m understanding you correctly, you want some way to set the factory defaults that will be used in the absence of defaults saved to a file when the app last ran. If so, you need something like (untested):

		set prefs to {theFrequency:"100", theAge:"45"}
		set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
		userDefaults's registerDefaults_(prefs)

Such prefs are not saved to disk, and are overridden by an app-domain defaults read from disk.

Thank you Shane, that worked perfectly. It started the app with the defaults, and when I changed the first value the file was written to the preferences folder. I only used the set, get calls above and the initialization method in your post. As I said above I was overcomplicating things a bit, but using only the 2 properties above let me get my head wrapped around all the automation that bindings and the NSuserdefaults class offers.

My app is done! All in ASOC, and the only non-applescript code was getting the url’s from the path controls and this preference code. Just preparing an icon, and it’s ready for prime time!

Thanks for your assistance once again.

Hi All,

I have a few problems with writing to user defaults:
what do I have to write exactly into the “setObject_forKey_” and the “objectForKey_” parts?

In my application I’m using some text fields and I want to save their values as string.

Example:

property thistextinput_field : missing value //this is connected to a textfield in the IB

//for working with the value I have this two lines:

set usertext to thistextinput_field’s stringValue()
set theusertext to usertext as string

//now the user has to write some text into the text field and after relaunching the application the text should still be in the text field

→ so the question:

What do I have to write in the parts I marked with the questions marks???

//for writing the user defaults

tell NSUserDefaults
tell its standardUserDefaults()
its setObject_forKey_(???, ???)
end tell
end tell

//for reading the user defaults

tell NSUserDefaults
tell its standardUserDefaults()
set ??? to its objectForKey_(“???”)
my setFlipit_(flipit) //don’t unterstand that line???
end tell
end tell

Thanks!

Hi Borhahn,

You might be better of using capitals to delineate variable names instead of underscores since the mthods use underscores.

so:

set usertext to thistextinput_field’s stringValue()

could be

set usertext to thisTextInputFeld’s stringValue()

then to read in:

on awakeFromNib()
		tell NSUserDefaults
			tell its standardUserDefaults()
				set thisTextInputFeld to its stringForKey_("thisTextInputFeld")
				my setThisTextInputFeld_(thisTextInputFeld)   --this sets your text field's value
			end tell
		end tell
end awakeFromNib

the line

my setThisTextInputFeld_(thisTextInputFeld)

is an accessor method that is built in for your property declared at the top (it simple adds “set” to variable name)

so the “getter” would be

thisTextInputFeld’s stringValue()

and the “setter” would be

setThisTextInputFeld_(thisTextInputFeld) --note the capitalized “This” in your variable name.

then to write out…

on writeToFile()
		tell NSUserDefaults
			tell its standardUserDefaults()
				its setObject_forKey_(thisTextInputFeld, "thisTextInputFeld")
			end tell
		end tell
end writeToFile

You can use the setObject_forKey_ form for writing but should be more specific about reading in with

stringForKey_(“thisTextInputFeld”)

The defaults use standard key value pairs so you have the value followed by the key

(thisTextInputFeld, “thisTextInputFeld”)

you could use different names for the key of course

(thisTextInputFeld, “textFieldKey”)

Hope that helps.

Rob

Thanks! That helped a lot! :slight_smile:

Ok I need help understanding these new defaults. I have a property I want to save which is “thepass” and thepass is set to whatever the user set the password as when he first opened the application. Now I need to save this password and be able to reload the pass on startup next time. I really do not under stand any of the other stuff in this post, could someone show me how this would be written?

Really, everything you need is in this thread; it’s pointless for someone to type it all in again. Re-read – the code you need is covered in message #4.

Hi,

I’m (very) new to ASOC and currently struggling trying to implement the code described above to work with my application. I did quite some trial-and-error but I just can’t get the script to save or read the user defaults. I’m guessing my problem is probably a misconception… Or I overlooked something. Either way, I would be very glad if someone here could point me into the right direction.

Here’s the relevant parts of my script. Everything except for the preferences part works as expected. Basically, there’s just 4 text fields containint strings in my app’s window which I’d like to include in the preferences file.

My understanding: Load the preferences on initialisation, save the preferences on exit.



script drupdaterAppDelegate
	
	property NSUserDefaults : class "NSUserDefaults" of current application
	
	property statusLogWindow : missing value
	property testServer : missing value
	property modulesOnly : missing value
	property safeUpdate : missing value
	property yftpBookmarkFolder : missing value
	property localDrupalFolder : missing value
	property localBackupFolder : missing value
	property tokenString : missing value
	
	global statusLog, currentDate, curlBrowserString
	
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened 		
				
		-- set defaults
		set prefs to {tokenString:"blabla", localBackupFolder:"blablabla"}
		set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
		userDefaults's registerDefaults_(prefs)
		
		-- read prefs
		tell NSUserDefaults
			tell its standardUserDefaults()
				set yftpBookmarkFolder to its objectForKey_("yftpBookmarkFolder")
				my setYftpBookmarkFolder_(yftpBookmarkFolder)
				set localDrupalFolder to its objectForKey_("localDrupalFolder")
				my setLocalDrupalFolder_(localDrupalFolder)
				set localBackupFolder to its objectForKey_("localBackupFolder")
				my setLocalBackupFolder_(localBackupFolder)
				set tokenString to its objectForKey_("tokenString")
				my setTokenString_(tokenString)
			end tell
		end tell
		
	end applicationWillFinishLaunching_

(*

all the other stuff

*)


	on applicationShouldTerminateAfterLastWindowClosed_(sender)
		return true
	end applicationShouldTerminateAfterLastWindowClosed_

	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		tell NSUserDefaults
			tell its standardUserDefaults()
				its setObject_forKey_(yftpBookmarkFolder, "yftpBookmarkFolder")
				its setObject_forKey_(localDrupalFolder, "localDrupalFolder")
				its setObject_forKey_(localBackupFolder, "localBackupFolder")
				its setObject_forKey_(tokenString, "tokenString")
			end tell
		end tell
		return my NSTerminateNow
	end applicationShouldTerminate_
	
end script


What am I missing? :frowning: I get the following errors on console:

On initialisation:

On exit:


I’m stuck… :stuck_out_tongue: Thanks for any inputs!

Regards,

Oliver

Could it be that the variables you’re trying to save are references to text fields, rather than containing the text in the fields?

Thanks for the reply!

Yes, in fact I was messing up the syntax and tried to save the text field’s reference object instead of the values. It now saves everything as supposed to during applicationShouldTerminate. Thanks for pointing me there… I probably got a little confused because of the following:

One thing left me puzzled tho and it turns out that this is actually not a bug in my script but rather a bug in ASOC itself: http://lists.apple.com/archives/AppleScript-Studio/2009/Sep/msg00022.html That’s why my script failed to save to prefs even tho variables, values and everything was properly assigned. Argh… :stuck_out_tongue:

As suggested from the post on Apple’s mailing list, I replaced

return my NSTerminateNow

with

return 1

Without this workaround, nothing will be written on closing the application anyways, even if everything’s supposed to be working correctly.

(Edit: It’s not really a bug in ASOC, it’s more like a bug in the ASOC template file xCode provides.)

This probably isn’t causing this problem but the class property should be above the script declaration. You declare

class “NSUserDefaults” of current application

down below though so that should work. Perhaps Shane is right - or are those text fields bound to your variables or connected as outlets?

Rob

Has anyone made this work? I figured out to write some code in ASOC that mimics this ObjC code but it seems not to work:


tell NSUserDefaults
	tell its standardUserDefaults()
		its registerDefaults_(prefQuitIllustrator)
		its registerDefaults_(prefRunFontCacheCleanStartup)
		its registerDefaults_(prefCleanMSOfficeFontCaches)
		its registerDefaults_(theLogDataSource)
	end tell
end tell

Anyone has had any success?

Model: MacBookPro2,2
Browser: Safari 531.9
Operating System: Mac OS X (10.6)

You have to pass registerDefaults_ a record – see the example in message #12 in this topic.

Really? It only accepts records? Can’t set booleans and integers or strings?

Then I guess I would need to read back this record and figure out which one is which and if it can be used to fill an empty variable.

Also, does it mean that it only registers defaults if none was read at startup and will only be saved once we save them at quit time?

Or, it means that we are passing a record of as many properties we need defined as default in one shot to the registerDefaults_(record), and the compiler will know to separate them as properties, using them as default values if none have been read from the plist?

Thanks for the response, i’m starting to get a good hold on ASOC’s principles. And sorry if I sound a bit off, it’s a bit too late for me to be still awake…

Defaults consist of key-value pairs – the key is how you identify a particular default, and the value is, well, the value. registerDefaults_ wants them as a dictionary, and the AS equivalent is a record. You can pass them all in one go.

But registerDefaults_ values aren’t saved anywhere: it’s what you use to establish default values if the user hasn’t set any.

Well… I’m having a problem and I can’t figure it out. Here is my application. It is suppost to automaticly save your user information as you type it. The problem is that there are errors with the reading and writing of the username and password via NSUserDefaults that causes me to be confused. Can someone help?

It’s giving me these errors:



Hmmm. Maybe you need to coerce them to string? I know that you need to do that more in ASOC than ASS ever needed. Not much help am I :/…

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

After looking at your code, I noticed this:

on recoversettings()
		tell class "NSUserDefaults"
			tell its standardUserDefaults()
				set username to its stringForKey_("username")
				theusername's setStringValue_(username)
			end tell
		end tell
		beep
	end recoversettings

And my routine (that saves and retrieves strings fine) is a bit different:

on writeDefaults()
		tell NSUserDefaults
			tell its standardUserDefaults()
				its setObject_forKey_(theLogDataSource, "theLogDataSource")
				its setObject_forKey_(prefDefaultAppLang, "prefDefaultAppLang")
			end tell
		end tell
	end writeDefaults
on readDefaults()
		tell NSUserDefaults
			tell its standardUserDefaults()
				set theLogDataSource to its objectForKey_("theLogDataSource")
				set prefDefaultAppLang to its objectForKey_("prefDefaultAppLang")
			end tell
		end tell
	end readDefaults

NSUserDefaults has been defined at the top of the app delegate like this:

property NSUserDefaults : class "NSUserDefaults" of current application

Helps?

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

DUHHHHH… I forgot to put “of current application.”

:stuck_out_tongue:

So I guess it works now! :wink: