Property list clippings

plist
property_list
asobjc
foundation

(Shane Stanley) #1

I’ve been dealing with property list files a bit lately, so I finally got around to writing some clippings for the job. Unlike the existing plist clippings, these read/write binary format files, as well as reading non-binary format. They’re also better in terms of error handling.

This is the clipping for reading a property list file from disk and converting the result to an AppleScript value (usually a record or list):

[[*framework:Foundation]]set {theData, theError} to [[*class:NSData]]'s dataWithContentsOfFile:[[template:posixPath]] [[*piped:options]]:0 |error|:(reference)
if theData = missing value then error theError's localizedDescription() as text
set {[[linked-template:newValue]], theError} to [[*class:NSPropertyListSerialization]]'s propertyListWithData:theData options:[[*enum:2:NSPropertyListMutableContainersAndLeaves]] |format|:(missing value) |error|:(reference)
if [[linked-template:newValue]] = missing value then error theError's localizedDescription() as text
set [[template:newASValue]] to item 1 of (([[*class:NSArray]]'s arrayWithObject:[[linked-template:newValue]]) as list) -- converts newValue to AS class
[[selected-lines]]

This is for saving a suitable AppleScript (or ASObjC) object to a property list file:

[[*framework:Foundation]]set {theData, theError} to [[*class:NSPropertyListSerialization]]'s dataWithPropertyList:[[template:valueToSave]] |format|:[[*enum:200:NSPropertyListBinaryFormat_v1_0]] [[*piped:options]]:0 |error|:(reference)
if theData = missing value then error theError's localizedDescription() as text
set {theResult, theError} to theData's writeToFile:[[template:posixPath]] [[*piped:options]]:[[*enum:1:NSDataWritingAtomic]] |error|:(reference)
if not theResult as boolean then error theError's localizedDescription() as text
[[selected-lines]]

And this is for when you have a property list in text form, such as the result of call to do shell script:

[[*framework:Foundation]]set [[linked-template:theString]] to [[*class:NSString]]'s stringWithString:[[linked-template:theString]]
set theData to [[linked-template:theString]]'s dataUsingEncoding:[[*enum:4:NSUTF8StringEncoding]] -- convert to NSData
set {[[linked-template:newValue]], theError} to [[*class:NSPropertyListSerialization]]'s propertyListWithData:theData options:[[*enum:2:NSPropertyListMutableContainersAndLeaves]] |format|:(missing value) |error|:(reference)
if [[linked-template:newValue]] = missing value then error theError's localizedDescription() as text
set [[template:newASValue]] to item 1 of (([[*class:NSArray]]'s arrayWithObject:[[linked-template:newValue]]) as list) -- converts newValue to AS class
[[selected-lines]]

(Matt Strange) #2

Nice, and thanks much for providing these.

Any chance you could provide a clipping for reading a single property from a plist? Reading a large plist and Iterating through it seems less elegant somehow.


(Shane Stanley) #3

A property list file is just a way of taking something like a record, and serializing it to disk; reading one simply reverses the process. The structure of records can vary enormously, so there’s no one way reading a value from one.

The one useful shortcut is if you have cascading properties, where you can use valueforKeyPath:"prop1.prop2[. …]". But I’m not sure that’s worth a clipping.