Since updating to Mavericks, I have an issue writing an array to pList.
Scripts that were working OK in Mountain Lion now render the pList blank. Writing strings are ok. Writing lists are not.
I’ve got as far as this:
--"test"
global prefsFile
property path2home : (path to home folder)
property prefsFolder : ((path2home as text) & "Library:Preferences:") as alias
property prefsName : "com.dewshi.test"
property defaultPrefsRecord : {|Pairs|:{"one", "two"}}
--VERIFY PLIST
on verifyplist()
tell application "Finder"
if not (exists file (prefsName & ".plist") of folder prefsFolder) then
set posixPath to quoted form of (POSIX path of prefsFolder)
do shell script "defaults write " & posixPath & prefsName & " x y" -- creates the new property list file with dummy value
tell application "Finder"
set NewprefsFile to (file (prefsName & ".plist") of prefsFolder) as alias
end tell
tell application "System Events"
NewprefsFile as text
set value of property list file the result to defaultPrefsRecord
end tell
--define prefs file
set prefsFile to NewprefsFile
set first_run_status to true
else
set prefsFile to (file (prefsName & ".plist") of prefsFolder) as alias
set first_run_status to false
end if
end tell
end verifyplist
my verifyplist() --write the pList if it doesn't exist
--TRY TO UPDATE...
tell application "System Events"
tell property list file (prefsFile as text)
tell property list item "Pairs"
(*
set value to "nine" -- WORKS
set value to {"three", "four"} --DOESN'T WORK: LEAVES PLIST BLANK
*)
repeat with this_value in {"three", "four"}
make new property list item with properties {kind:list, value:this_value} --ADDS NEW ENTRIES BUT DOESN'T DELETE EXISTING!!!
end repeat
end tell
end tell
end tell
Make new property list item instead of setting value works, but how can I delete/overwrite the existing entry?
If you’re planning to update application’s preferences like this, you can forget it in Mavericks. The preferences daemon writes the values to disk much less frequently, and the general advice from the engineers is that you shouldn’t attempt it other than through the CLI tool defaults or using NSUserDefaults.
The second point is that if you want to read and write .plist files in Mavericks despite this, an ASObjC-based library solution can make it a lot easier:
use framework "Foundation"
on saveRecord:theRecord toPlistAt:posixPath
set theDict to current application's NSDictionary's dictionaryWithDictionary:theRecord
set thePath to current application's NSString's stringWithString:posixPath
set thePath to thePath's stringByExpandingTildeInPath()
theDict's writeToFile:thePath atomically:true
end saveRecord:toPlistAt:
on readPlistAt:posixPath
set thePath to current application's NSString's stringWithString:posixPath
set thePath to thePath's stringByExpandingTildeInPath()
set theDict to current application's NSDictionary's dictionaryWithContentsOfFile:thePath
return theDict as record
end readPlistAt:
Using it in a library is pretty simple. Open a script window, paste in the above, save to ~/Library/Script Libraries/ as a .scptd file, click the Bundle Contents button and check the AppleScript/Objective0bjC Library checkbox, and save again.
Using it is then just a matter of adding a “use” statement, and calling the handler.
That’s an interesting suggestion, Yvan. However, I wonder whether lots of separate libraries is a a bit messy. For a lot of people, I think, just copying handlers into a single library might make sense. And for those who use more, I still think there’s something to be said for grouping stuff.
For example, I have one library called General Lib.scptd, and I put lots of stuff I’m likely to want regularly in there. It saves me remembering library names (though I still have to remember handler names).