Normally NSUserDefaults are tied to a particular application: we call it using the ‘standardUserDefaults’ method, and it sets up a plist file using the app’s bundle id. However, I realized today that we can access the defaults mechanism from any script, without a bundle id, by using the ‘initWithSuiteName’ initializer. In a few ASOC handlers:
use framework "Foundation"
property ca : current application
property NSUserDefaults : class "NSUserDefaults"
property defaultsSuite : missing value
property suiteID : "user.script.defaultsTest"
on init()
set defaultsSuite to NSUserDefaults's alloc's initWithSuiteName:suiteID
end init
to setValueForKey(keyName, value)
if defaultsSuite = missing value then my init()
defaultsSuite's setObject:value forKey:keyName
end setValueForKey
to getValueForKey(keyName)
if defaultsSuite = missing value then my init()
return defaultsSuite's objectForKey:keyName
end getValueForKey
to setSuiteValues(keyValueRecord)
-- this will erase any previous data and create a new plist
NSUserDefaults's alloc's setPersistentDomain:keyValueRecord forName:suiteID
end setSuiteValues
to getSuiteValues()
return (NSUserDefaults's alloc's persistentDomainForName:suiteID)
end getSuiteValues
to coerceObjToAS(obj)
-- coercion handler to get things back to applescript-frienly values
return item 1 of (current application's NSArray's arrayWithObject:obj) as list
end coerceObjToAS
Call it like so:
setSuiteValues({alpha:{1, 2, 3}, beta:3.1415926})
setValueForKey("beta", 1.414213562373)
setValueForKey("gamma", true)
coerceObjToAS(getSuiteValues())
You can make a library script out of this, and use it for persistent storage whenever applescript’s built-in property persistence doesn’t work. You can even use it to share persistent data between different scripts, or to examine or modify the preference plists of applications.
Edit: Added in Shane’s ‘coerceObjToAS’ handler from his post below, because it’s much simpler than my original version.