Setting/Writing/Reading user defaults.

Hi! I’m trying to expand my use of ‘user defaults’ and I’m having some problems… I want to register an array that will eventually consist of other arrays. That is… i.e. an array called “People” that will have an element “Person” with properties {Name, Age, Address, etc} resulting in something like {{“Joe”, 25, “Neptune”},{“Jack”,56,“Mars”},{…},etc}. This array will be empty the first time the app is run so I can’t register them all at once… I’ll need to add them according to user needs (even delete them… how can I do that?). I’ve been using these handlers with previous apps but I’m having problems on how to do all this now. I’m absolutely confused! :smiley:


property TheArray : {"People"}

on will open theObject -- window "Main"
       RegisterDefaults(TheArray)
       .... -- code
end will open

on RegisterDefaults(AllDefaults)
	-- AllDefaults is {}
	tell user defaults
		repeat with i from 1 to (count of AllDefaults) -- or is it TheArray??
			make new default entry at end of default entries with properties {name:(item i of AllDefaults), contents:(item i of AllDefaults)} -- or is it AllDefaults??
		end repeat
		register
	end tell
end RegisterDefaults

on ReadDefaults()
	set AllDefaults to {}
	tell user defaults
		repeat with i from 1 to (count of TheArray) -- or is it AllDefaults??
			set end of AllDefaults to contents of default entry (item i of TheArray) -- or is it AllDefaults??
		end repeat
	end tell
	return AllDefaults
end ReadDefaults

on WriteDefaults(AllDefaults)
	-- AllDefaults is {}
	tell user defaults
		repeat with i from 1 to (count of TheArray)
			set contents of default entry (item i of AllDefaults) to (item i of TheArray)
		end repeat
	end tell
end WriteDefaults

Any help will be apreciated! Thanks a lot!

AppleScript: XCode 1.1
Browser: Firefox 1.5.0.2
Operating System: Mac OS X (10.3.9)

Nikel,

can’t you simply save your array as a single default entry? User defaults can hold nested arrays - I think this could save you a lot of code …

D.

Meaning? How would that look like? The thing is I will eventually be adding items to the array, change them or delete them. If you mean saving all those “repeats” and stuff then yes… I agree, since I will (so far) only have one user default (consisting of various nested arrays), and will not need all that. I got that code from another post some years ago and so far it had help me ok, I just don’t know how to bend it to my needs this time…

Thanks for the reply.

Hmm - i am not sure if I fully understood. My idea was to load the whole array at program start or when opening a window or whenever you need it the first time from the user defaults …


..
try
	set theArray to default entry "people" of user defaults
on error -- this value doesn't exist (since the application is run for the first time)
	set theArray to {} -- or to a default value you defined in your script (property defaultArray: {....})
end try

… and save it after modifying/using it (at window closing or program quit …). Any changes, additions, deletions to the array you made meanwhile will be saved this way:


try
	set default entry "people" of user defaults to theArray
on error -- there is no existing entry:
		make new default entry at end of default entries of user defaults with properties {name:"people", contents:theArray}
end

Well yes… that works pretty much ok… with a few fixes (you missed some “contents of” when refering to default entries) and one exception… I can’t get to read an entry…

-- neither this
set theArray to default entry "People" of user defaults
-- nor this
set theArray to contents of default entry "People" of user defaults
-- seem to work...

This of course with existing entries… The prefs folder has a .plist file with the stored info… it’s when trying to retrieve it that it fails…

“People” right now would be… (in the prefs file)

And I would like to get something like {{“Joe”},{“Jack”},{“John”}} back… when reading the entry, if posible…

Oops, sorry for my mistake - I should have noticed that I typed in the script here without having error checked it before … forgive me.

This time i have tried it before. This test is working for me (reading AND writing the defaults):


property defaultArray : {{"person 1", 1968, "John", 1.45}, {"person 2", 1963, "Paul", 1.22}, {"person 3", 1923, "George", 1.24}, {"person 3", 1943, "Ringo", 1.24}}

on awake from nib theObject
	try
		set theArray to contents of default entry "people" of user defaults
		log "read from user defaults:"
		log theArray
	on error
		set theArray to defaultArray
		make new default entry at end of default entries of user defaults with properties {name:"people", contents:theArray}
		log "set default value:"
		log theArray
	end try
end awake from nib

here the results:
first time running:

[Session started at 2006-06-13 22:51:32 +0200.]
2006-06-13 22:51:35.208 defaults2[6822] “set default value:”
2006-06-13 22:51:35.221 defaults2[6822] {{“person 1”, 1968, “John”, 1.45}, {“person 2”, 1963, “Paul”, 1.22}, {“person 3”, 1923, “George”, 1.24}, {“person 3”, 1943, “Ringo”, 1.24}}
defaults2 has exited with status 0.

second time running:
[Session started at 2006-06-13 22:52:44 +0200.]
2006-06-13 22:52:47.505 defaults2[6827] “read from user defaults:”
2006-06-13 22:52:47.535 defaults2[6827] {{“person 1”, 1968.0, “John”, 1.45}, {“person 2”, 1963.0, “Paul”, 1.22}, {“person 3”, 1923.0, “George”, 1.24}, {“person 3”, 1943.0, “Ringo”, 1.24}}

defaults2 has exited with status 0.

Great, thanks Dominik… it would have worked before… that last post was extra work for you, I’m sorry… I just hadn’t realized that I was trying to read the defaults inside a “tell window “main”” block. That’s why I had trouble only with reading… for some reason even with a ‘tell user defaults’ it didn’t work. Either that or I had the incredible misfortune that when I tried that combo something else crashed the ‘try’ hehe…

Anyway, problem solved… thanks a lot.

I cannot READ my user defaults back into a variable “serversDataSource”. Does anyone know what I am doing wrong here? The plist file exists and my data is there.


on readSettings() --in will finish launching
	set serversDataSource to contents of default entry "dataRows" of user defaults  --not working, what am I doing wrong?
end readSettings

on writeSettings(serversDataSource) --in will quit	
	set allData to contents of every data row of serversDataSource
	set allDataRows to "dataRows"
	make new default entry at end of default entries of user defaults with properties {name:allDataRows, contents:allData}
	set contents of default entry allDataRows of user defaults to (items of allData)
end writeSettings

Any help is much appreciated!
Thanks!