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? I get the following errors on console:
On initialisation:
On exit:
I’m stuck… 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…
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.”
So I guess it works now!
I’ve followed #4 and #12 to manage check boxes defaults
This is what I did:
--IBOutlets
property engine00 : missing value
property engine01 : missing value
-- Bindings
property theEngine00 : ""
property theEngine01 : ""
-- to set factory default at first open
on setDefaults()
set prefs to {theEngine00:true, theEngine01:true}
set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
userDefaults's registerDefaults_(prefs)
end setDefaults
-- to write defaults when quit
on writeDefaults()
tell NSUserDefaults
tell its standardUserDefaults()
its setBool_forKey_(theEngine00, "theEngine00")
its setBool_forKey_(theEngine01, "theEngine01")
end tell
end tell
end writeDefaults_
-- to read defaults next open
on readDefaults()
tell NSUserDefaults
tell its standardUserDefaults()
set theEngine00 to its boolForKey_("theEngine00")
my setTheEngine00_(theEngine00)
set theEngine01 to its boolForKey_("theEngine01")
my setTheEngine01_(theEngine01)
end tell
end tell
end readDefaults
-- to load defaults when app open
on awakeFromNib()
my setDefaults()
my readDefaults()
end awakeFromNib
-- to save defaults when app quit
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
my writeDefaults()
return true
end applicationShouldTerminate_
I wish a button that revert to factory defaults, I did
on revertDefaults_(sender)
setDefaults_(me)
readDefaults_(me)
writeDefaults_(me)
end revertDefault_
but nothing happen.
How can I set check box and its default to true/checked by code?
Edit: when I click on my revertDefault button I get: unrecognized selector sent to object
Make userDefaults a property, and change the two cases of “tell NSUserDefaults” – which you don’t define anywhere – to “tell userDefaults”.
I forget to write on my previous post that NSUserDefaults is defined at the beginning with:
property NSUserDefaults : class "NSUserDefaults" of current application
Sorry using tell userDefault didn’t work.
Easiest solution: NSUserDefaultsController
script myAppDelegate
property parent : class "NSObject"
property NSDictionary : class "NSDictionary"
property NSUserDefaults : class "NSUserDefaults"
property NSUserDefaultsController : class "NSUserDefaultsController"
--IBOutlets
property engine00 : missing value
property engine01 : missing value
on awakeFromNib()
set prefs to {theEngine00:true, theEngine01:false}
set userDefaults to NSUserDefaults's standardUserDefaults()
userDefaults's registerDefaults_(prefs)
set revertDictionary to NSDictionary's dictionaryWithDictionary_(prefs)
set sharedUserDefaultsController to NSUserDefaultsController's sharedUserDefaultsController()
sharedUserDefaultsController's setInitialValues_(revertDictionary)
end awakeFromNib
on revertDefaults_(sender)
set sharedUserDefaultsController to NSUserDefaultsController's sharedUserDefaultsController()
sharedUserDefaultsController's revertToInitialValues_(me)
end revertDefaults_
end script
In InterfaceBuilder bind the value of check box engine00 to key theEngine00 and check box engine01 to key theEngine01 of Shared User Defaults Controller.
In awakeFromNib() the initial values are defined in the controller
When you press the revert button, the initial values are reset.
Further reading, writing and synchronizing is not needed. NSUserDefaultsController does the rest
Thanks a lot StefanK, it works perfect.
I’ve also binded the Visible parameter of a Drawer object to retrive it state of opened or closed.