Write array to pList in Mavericks

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:


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"}}

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
			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

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?

Many thanks.

There are two issues here.

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:

Shane, thanks for this.

I’m not quite up to speed in ASObjC… though I have a batch of ASS apps that I’m sure would benefit from rewriting from scratch.

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.

See macscripter.net/viewtopic.php?id=41638

Hello Shane

Just a suggestion.

When you post here a library, it would be fine to give it a name.
This way we may hope that it would become a standard helping us to share scripts.

Yvan KOENIG (VALLAURIS, France) samedi 14 décembre 2013 11:48:39

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).