Problem: I have a preferences dialogue that allows me to enter preferences, which are stored as long as the application is running, however, they are lost as soon as I quit the application. the code is as follows:
on clicked theObject
tell window of theObject
set nUsername to the contents of text field "Username" as string
set nPassword to the contents of text field "Password" as string
set nServerAddress to the contents of text field "ServerAddress" as string
call method "setDefaultObject:forKey:" with parameters {nUsername, "Username"}
call method "setDefaultObject:forKey:" with parameters {nPassword, "Password"}
call method "setDefaultObject:forKey:" with parameters {nServerAddress, "ServerAddress"}
-- Set the properties
set nUsername to (nUsername as string)
set nPassword to (nPassword as string)
set nServerAddress to (nServerAddress as string)
close
end tell
How can I write and store these values to/in a preferences file?
AppleScript Studio has its own commands for registering, writing, and reading using the user-defaults system–no need to invoke a call method. This has been covered many times on this forum and you can do a search for “defaults” which should yield some helpful threads. Also take a look at the AppleScript Studio example applications provided with the Developer’s tools installation. I know “Archive Maker” demonstrates using the user-defaults system.
Did you look at the “Archive Maker” example? These are the basic routines I use (adjust the items in the “assign_settings” and “get_settings” handlers to match your preferences, the values used here are just for demonstration purposes):
property first_run : true
property property_1 : "some text"
property property_2 : {1, 2, 3}
on will finish launching the_object
my register_settings()
my read_settings()
end will finish launching
on launched the_object
if first_run then
--do something
set first_run to false
my write_settings()
end if
end launched
on will quit the_object
my write_settings()
end will quit
on register_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
make new default entry at end of default entries with properties {name:(item i of the_settings_names), contents:(item i of the_settings)}
end try
end repeat
register
end tell
end register_settings
on read_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
set item i of the_settings to contents of default entry (item i of the_settings_names)
end try
end repeat
end tell
my assign_settings(the_settings)
end read_settings
on write_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
set contents of default entry (item i of the_settings_names) to (item i of the_settings)
end try
end repeat
end tell
end write_settings
on assign_settings(the_settings)
set {first_run, property_1, property_2} to the_settings
end assign_settings
on get_settings()
set the_settings to {first_run, property_1, property_2}
set the_settings_names to {"first_run", "property_1", "property_2"}
return {the_settings, the_settings_names}
end get_settings
OK, recoded to this, but it still doesn’t behave as expected:
--Property settings
property firstOpened : true
property nUsername : ""
property nPassword : ""
property nServerAddress : ""
readSettings()
--Event Handlers
--Application Handlers
on clicked theObject
tell user defaults
set myUser to the contents of every default entry as string
end tell
if name of theObject is "PrintButton" then
--script
display dialog myUser
else if name of theObject is "Cancel" then
tell window of theObject
close
end tell
else if name of theObject is "OpenPrinterButton" then
tell application "Print Center"
activate
end tell
else if name of theObject is "Use" then
if firstOpened = true then
getSettingsFromUI()
registerSettings()
else if firstOpened = false then
getSettingsFromUI()
writeSettings()
end if
tell window of theObject
close
end tell
end if
end clicked
on choose menu item theObject
if name of theObject is "Preferences" then
show window "Preferences"
setSettingsInUI()
else if name of theObject is "About" then
show window "About"
end if
end choose menu item
on getSettingsFromUI()
tell window "Preferences"
set nUsername to contents of text field "nUsername" as string
set nPassword to contents of text field "nPassword" as string
set nServerAddress to contents of text field "nServerAddress" as string
end tell
end getSettingsFromUI
on setSettingsInUI()
tell window "Preferences"
set contents of text field "nUsername" to nUsername
set contents of text field "nPassword" to nPassword
set contents of text field "nServerAddress" to nServerAddress
end tell
end setSettingsInUI
on registerSettings()
tell user defaults
make new default entry at end of default entries with properties {name:"firstOpened", contents:false}
make new default entry at end of default entries with properties {name:"nUsername", contents:nUsername}
make new default entry at end of default entries with properties {name:"nPassword", contents:nPassword}
make new default entry at end of default entries with properties {name:"nServerAddress", contents:nServerAddress}
register
end tell
end registerSettings
on readSettings()
tell user defaults
set firstOpened to contents of default entry "firstOpened" as boolean
set nUsername to contents of default entry "nUsername" as string
set nPassword to contents of default entry "nPassword" as string
set nServerAddress to contents of default entry "nServerAddress" as string
end tell
end readSettings
on writeSettings()
tell user defaults
set contents of default entry "firstOpened" to firstOpened
set contents of default entry "nUsername" to nUsername
set contents of default entry "nPassword" to nPassword
set contents of default entry "nServerAddress" to nServerAddress
end tell
end writeSettings
Are you kidding? Did you not look at what I posted at all? Here, add this to your script, then in Interface Builder, make sure you connect the “will finish launching” & “launched” events to your application (File’s Owner) and the “awake from nib” event to your preferences window all in the AppleScript pane of the Get Info palette. If you can’t take it from here, I’m afraid there’s nothing more to say.
property firstOpened : true
property nUsername : ""
property nPassword : ""
property nServerAddress : ""
on will finish launching the_object
my register_settings()
my read_settings()
end will finish launching
on awake from nib the_object
set object_name to name of the_object
if object_name = "Preferences" then
my setSettingsInUI()
end if
end awake from nib
on launched the_object
if firstOpened then
show window "Preferences"
set firstOpened to false
my write_settings()
end if
end launched
on clicked the_object
set object_name to name of the_object
if object_name = "PrintButton" then
--script
display dialog nUsername --myUser what is myUser?
else if object_name = "Cancel" then
tell window of the_object to close
else if object_name = "OpenPrinterButton" then
tell application "Printer Setup Utility" to activate
else if object_name = "Use" then
my getSettingsFromUI()
my write_settings()
tell window of the_object to close
end if
end clicked
on choose menu item the_object
set object_name to name of the_object
if object_name = "Preferences" then
show window "Preferences"
else if object_name = "About" then
show window "About"
end if
end choose menu item
on getSettingsFromUI()
tell window "Preferences"
set nUsername to contents of text field "nUsername" as Unicode text
set nPassword to contents of text field "nPassword" as Unicode text
set nServerAddress to contents of text field "nServerAddress" as Unicode text
end tell
end getSettingsFromUI
on setSettingsInUI()
tell window "Preferences"
set contents of text field "nUsername" to nUsername
set contents of text field "nPassword" to nPassword
set contents of text field "nServerAddress" to nServerAddress
end tell
end setSettingsInUI
on register_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
make new default entry at end of default entries with properties {name:(item i of the_settings_names), contents:(item i of the_settings)}
end try
end repeat
register
end tell
end register_settings
on read_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
set item i of the_settings to contents of default entry (item i of the_settings_names)
end try
end repeat
end tell
my assign_settings(the_settings)
end read_settings
on write_settings()
set {the_settings, the_settings_names} to my get_settings()
tell user defaults
repeat with i from 1 to (count the_settings_names)
try
set contents of default entry (item i of the_settings_names) to (item i of the_settings)
end try
end repeat
end tell
end write_settings
on assign_settings(the_settings)
set {firstOpened, nUsername, nPassword, nServerAddress} to the_settings
end assign_settings
on get_settings()
set the_settings to {firstOpened, nUsername, nPassword, nServerAddress}
set the_settings_names to {"firstOpened", "nUsername", "nPassword", "nServerAddress"}
return {the_settings, the_settings_names}
end get_settings
I have followed Jon’s example almost exactly as shown. My difference is that since I only have two preference items (a defaultFilePath, and a firstRun), I didn’t use an array.
Mine produces the error NSReceiverEvaluationScriptError:4(1) when it gets to the writeSettings() part example code below:
on writeSettings()
tell user defaults
set contents of default entry "DefaultFliePath" to defaultFilePath
set contents of default entry "FirstRun" to firstRun
end tell
end writeSettings
everything else seems to work except writing the defaults to the plist.
I would guess that defaultFilePath and firstRun aren’t defined in that handler (in Jon’s example, there are values coming from the get_settings handlers).
Although they were not in the example I provided, they are defined earlier in the script and can be updated by the user, Except for the “firstRun” that is set as the example script in the "will finish launching part.
I know that if I comment out the lines that set the default entries the error is not produced.