I’m working in Project builder, which means of course I can’t use “on” arguments. I need two scripts: one that sets a preference (which will stay in place AFTER the finished app quits) and one that checks that preference on launch to make a decision. Can anyone help me? please!
This seems like a good question.
I’m also new to this, and I’m having the same struggle. And man, is it hard to find the answer.
Did you ever get an answer?
Does anyone know the answer?
Check out the Archive Maker example
In the folder:
/Developer/Examples/AppleScript Studio/Archive Maker
In partiular look for the code that refers to the user defaults.
registerSettings - registers the settings, creates entries for them
readSettings - reads the settings into your application
writeSettings - writes the settings out.
The weakness of this approach compared to AppleScript applets and droplets and their property settings which are stored in the script file itself is that duplicate copies of the same AppleScript studio application all have the same default settings.
Kevin
Kevin,
Thank you!
That’s very straight forward - exactly what I needed. This is really a big help. I can’t thank you enough.
Good point about duplicate copies, too.
Thanks again.
- Charles
i tried adapting the example to my app, with miserable results
could someone please walk me through the preference process
i need a checkbox in a prefs window that will quit itunes on exit if checked (i already have that set up, but it doesn’t “stick” after the app quits"
thanks exactly 1,000,000
Here is a way I use, a sort of circular route. First, when the application is about to finish lunching, create the user default entry. What’s nice about the way this has been implemented, is that creating a new entry when an entry already exists, doesn’t matter. Applescript assumes you don’t want to alter a value that is already there and simply does nothing instead.
on will finish launching theObject
make new default entry at end of default entries of user defaults with properties {name:“iTunesPref”, contents:“”}
end will finish launching
Second, when the window containing the checkbox is about to close, retrieve the state of the checkbox and store it in its entry in user defaults. Don’t store this as a boolean. My understanding is it takes some shenanigans to make that work. Instead, you can just store “true” or “false” as a string, for example. In the same “will close” handler, after storing it, if its state is checked, then tell iTunes to quit.
on will close theObject
tell window “myWindow”
if state of button “myCheckbox” is equal to 1 then
set contents of default entry “iTunesPref” of user defaults to “true”
tell Application “iTunes” to quit
else
set contents of default entry “iTunesPref” of user defaults to “false”
end if
end tell
end will close
Third, when the check box is unpacked from the nib, retrieve the value of the default entry you created, and set the state of the checkbox accordingly. This is important, and it may be where you are having problems, because when the window is closed, it’s going to store the state of the checkbox and quit or not quit iTunes, and if it is not checked when it’s supposed to be, it won’t work.
on awake from nib theObject
if contents of default entry “iTunesPref” of user defaults is equal to “true” then
set state theObject to 1
else
set state of theObject to 0
end if
end awake from nib
Dan
That doesn’t work, when the prefs window is closed, there is an applescript error.
Well, the code is just untested “quasi-code”, I was just trying to step you through the process as you requested. Posting your code where you get the error would help to figure out where the error is coming in, but the process has always worked well for me.
Also, looking back at what you wrote, it seems you want iTunes to quit if the box is checked when the user closes the prefs window. Is that right? Doesn’t seem like that would be what you are after. In any case, the point is to check the state of the checkbox, quit iTunes if it is checked, whether it be when a window closes or the app quits, or whatever. Also, if a window, it may be better to do the last part in a “on should close” handler:
on should close theObject
tell window “myWindow”
set theTest to state of button “checker”
end tell
if theTest is equal to 1 then
set contents of default entry “iTunesPref” of user defaults to “true”
tell application “iTunes” to quit
else
set contents of default entry “iTunesPref” of user defaults to “false”
end if
return true
end should close
Also, if you check out the Archive Maker application in the examples folder, that users prefs with applescript. It helped me out tremendously.
Here’s what I’ve got, I need a bit of help on it, since there are some problems.
This creates the preferences entry, I haven’t found a way of finding out if there’s an error and if the entry has even been created or not, so any suggestions on how to check up on it would be appreciated.
on will finish launching theObject
make new default entry at end of default entries of user defaults with properties {name:"iMaintain_Preferences", contents:""}
end will finish launching
This updates the check box, depending on the contents of the preferences file, which I’m not sure exists. I’ve always had trouble with these “awake from nib” commands, can i change the object to a paremanent reference to a window? That might help.
on awake from nib theObject
if contents of default entry "iMaintain_Preferences" of user defaults is equal to "true" then
tell window "project"
set state of button "CreateLogCheck" to 1
end tell
else
tell window "project"
set state of button "CreateLogCheck" to 0
end tell
end if
end awake from nib
This one is the real problem. It says it cannot create the command. I’m not sure what’s wrong, any help would be appreciated.
on clicked theObject
tell window "preferences"
if state of button "CreateLogCheck" is equal to 1 then
set contents of default entry "iMaintain_Preferences" of user defaults to "true"
else
set contents of default entry "iMaintain_Preferences" of user defaults to "false"
end if
end tell
close panel (window of theObject)
end clicked
Thanks for any help you can give me!
Greetings.
You can check to see if your preferences file is being saved by looking in the plist file for your app. First, if you don’t already know it, you need to find out what your app’s identifier is, so you know what to look for. Click on the “Target” tab, and then on “Basic Information” under ‘info.plist Entries’. In the “Identifier” field is the ID which your plist file is saved as. For example if you use “com.MyApp” as your identifier, the plist file will be saved as “com.MyApp.plist”. You can find the plist file in “HD/Users/-YOURNAME-/Library/Preferences/com.MyApp.plist”. The file is saved as an xml document and is pretty easy to read and find out if what you’re doing is working. If there is an error setting the plist record, AS should tell you. Otherwise it will evaluate as best it can and dump it in there.
The following code will get the state of your button and then set a plist entry for the state, using the name you used in your example…
tell window "preferences"
if state of button "CreateLogCheck" is equal to 1 then
set currentState to "true"
else
set currentState to "false"
end if
end tell
tell user defaults
-- Set the name of the record to modify or create
set currentEntry to "iMaintain_Preferences"
if default entry currentEntry exists then
set contents of default entry currentEntry to currentState
else
make new default entry at end of default entries with properties {name:currentEntry, contents:currentState}
end if
end tell
You can use any number of events to set the data… on launched, will open, awake from nib. I use on will open a lot, as it updates the info whenever the window opens, not just when the app launches. I recommend doing it before the page is displayed so the user doesn’t see the info change. Make sure the object is attached to the event and script, as missing one will not perform the actions. To set your button state I might use something like…
on will open theObject
set currentState to contents of default entry named iMaintain_Preferences of user defaults
tell window "project"
if currentState is "true" then
set state of button "CreateLogCheck" to 1
else
set state of button "CreateLogCheck" to 0
end if
end tell
end will open
If your third bit of code does not work, try…
on clicked theObject
if state of button "CreateLogCheck" of window "preferences" is equal to 1 then
set contents of default entry "iMaintain_Preferences" of user defaults to "true"
else
set contents of default entry "iMaintain_Preferences" of user defaults to "false"
end if
close panel (window of theObject)
end clicked
There’s a lot more I could write here but I thought I’d give you some snippets that might be applicable before I go into great lengths. I took my bits of code my code from my own apps, so I know they work, if applied correctly. If you still can’t figure it from these bits, let me know. I’d be happy to help you get your plist stuff working.
Good luck…
j
For some reason, one of my preferences keeps getting stored as a number, with it’s quite obviously a string.
I can’t make a bit of sense of why it’s doing this, and it’s driving me quite bonkers.
Philn…post some code. :?
j
on awake from nib theObject
set currentStateLogCheck to contents of default entry named "iMaintain_Create Log" of user defaults
tell window "project"
if currentStateLogCheck is "true" then
set state of button "CreateLogCheck" to 1
else
set state of button "CreateLogCheck" to 0
end if
end tell
end awake from nib
This is my code to update the check box based on the contents of the user defaults. It gives me an error number 4. Can i make the reference to theObject permanent? The name of the .nib file is “PreferencesPanel” and the window’s applescript name is “preferences”. Thanks for any hely you can give me!
Make sure that the following code actually has access to a default entry named “iMaintain_Create Log”
set currentStateLogCheck to contents of default entry named "iMaintain_Create Log" of user defaults
Look in the plist file and see if there is an entry with that exact name. Perhaps you should use a try statement in your code to make sure that you don’t see an error, say if the plist was erased or the name you query does not match any of the records.
try
set currentStateLogCheck to contents of default entry named "iMaintain_Create Log" of user defaults
on error
set currentStateLogCheck to "false"
--add code to write the default entry here --
end try
In the on error statement set currentStateLogCheck to the value you use to define the button’s state by default (false), so it returns a value rather than nothing. You could also write a bit more code to write the user default to prefs if it wasn’t found (see location in code above, and examples further up in this thread).
Make sure too that you have named your window (“project”) and your button (“CreateLogCheck”) correctly. You mention at the end of your comments that the window’s name is “preferences”, so if I understand you correctly you should probably replace ‘projects’ in your tell statement with ‘preferences’.
Thus, your final code might look like…
on awake from nib theObject
try
set currentStateLogCheck to contents of default entry named "iMaintain_Create Log" of user defaults
on error
set currentStateLogCheck to "false"
--add code to write the default entry here --
end try
tell window "preferences"
if currentStateLogCheck is "true" then
set state of button "CreateLogCheck" to 1
else
set state of button "CreateLogCheck" to 0
end if
end tell
end awake from nib
As far as making theObject permanent, the event is triggered by the window, so making sure to connect the window’s ‘awake from nib’ event is about as simple and permanent as it gets.
j
The problem I’m having is storing and getting the value of a popup button from user prefs. All my other prefs work fine, but this one is probving troublesome.
Basically, I am trying to get the setting of the popup button, which is generated as such:
set menuTitles to {"1", "2", "3", "4", "5", "6", "7", "8", "9"}
delete every menu item of menu of popup button "quality pulldown"
repeat with i in menuTitles
make new menu item at the end of menu items of menu of popup button "quality pulldown" with properties {title:i, enabled:true}
end repeat
And then store it in the user prefs, e.g.:
set compressionQuality to (current menu item of popup button "quality pulldown") as string
or
set compressionQuality to (current menu item of popup button "quality pulldown") as number
Neither of these seem to work, I get errors when storing the data saying that it cannont be turned into that type (number or string).
Any ideas?
I noticed that none of your code had the window referenced. Are you using ‘tell window “XYZ”’ statements around your code to state which window you’re trying to control? I added the ‘of window’ code where necessary to your code under the assumption that you are not, so remove if necessary.
For your list, make sure to reference the window, other than that I had no problems running the code you provided…
set menuTitles to {"1", "2", "3", "4", "5", "6", "7", "8", "9"}
delete every menu item of menu of popup button "quality pulldown" of window "XYZ"
repeat with i in menuTitles
make new menu item at the end of menu items of menu of popup button "quality pulldown" of window "XYZ" with properties {title:i, enabled:true}
end repeat
You have to reference the title of a popup, not it’s name to get the current value. You should use…
set compressionQuality to title of popup button "quality pulldown" of window "XYZ"
j
I just wrap a tell around the setting things in the UI, e.g.
tell drawer "settings" of window "main"
set state of button "quitdone" to quitWhenDone
set state of button "compress" to compressArchive
set current menu item of popup button "quality pulldown" to compressionQuality
set state of button "autoconvert" to autoConvert
end tell
Is this the wrong way to go about it?
I don’t see any reason why it would be wrong. Is is working?
The only thing I see wrong is…
set current menu item of popup button "quality pulldown" to compressionQuality
…should be…
set current menu item of popup button "quality pulldown" to menu item compressionQuality
Otherwise, the only other way to write the whole thing would be…
set state of button "quitdone" of drawer "settings" of window "main" to quitWhenDone
set state of button "compress" of drawer "settings" of window "main" to compressArchive
set state of button "autoconvert" of drawer "settings" of window "main" to autoConvert
set current menu item of popup button "quality pulldown" of drawer "settings" of window "main" to menu item compressionQuality of popup button "quality pulldown" of drawer "settings" of window "main"
…a bit more verbose, but functional and sometimes more reliable (in my opinion).
j
I got that to work just fine.
But now for some reason, my droplet crashes when I drag anything onto the icon in the dock.
I even removed the on open function entirely, and it still crashed and burned. Sigh.
Then I tried taking out all the applescript in the application. And it still crashed when I dropped something onto the icon.
Here’s an interesting thing, if I create a new applescript project in xcode, and just click on build right away, it crashes in the same way… without my modifying the code or anything in any way. Does anyone have an idea as to what the problem might be?