= Editing Plist Files == Editing In this example, we will be editing a Launchd plist file. When we wish to perform an edit operation on a plist object, we (almost always) are calling an accessor method on the Plist Object. We may call the method directly on the object, like this launchd_plist.watch_paths ["/path1", "/path2", ...] However it gets a bit repetitive when there are many such plist keys to set launchd_plist.label "com.mydomain.myapp" launchd_plist.program "/path/to/myapp" launchd_plist.launch_only_once true # etc... launchd_plist.save === plist.edit do So instead we can invoke an convenience edit block on our plist object, which will just instance_eval(&blk) the block. launchd_plist.edit do label "com.mydomain.myapp" program "/path/to/myapp" launch_only_once true # etc... save end === plist.<< do The << operator can alternatively be used, interchangeably. Its just another way of writing plist.edit. launchd_plist.<< do label "com.mydomain.myapp" program "/path/to/myapp" launch_only_once true end launchd_plist.save == Editing operations Certain kinds of edit operation are available on the plist keys. These are useful when we want to treat the plist keys like we would an Array object or a Hash object. Methods like {Plist4r::Plist#select}, {Plist4r::Plist#map}, {Plist4r::Plist#delete_if}, {Plist4r::Plist#clear} and similar. Such methods are all documented in {Plist4r::Plist}. == Plist Data (CFData / NSData) A plist file supports key-value pairs in several types, including Base64 encoded binary data. For example, a plist key that stores binary data might look something like this PEKBpYGlmYFCPA== When its decoded, this is a byte stream (8-bit bytes), of some finite length. In Ruby we have no dedicated class to represent this, but instead can use a ruby +String+ as a binary string. In Plist4r, we extend {String} with 2 methods, {String#blob=} and {String#blob?}. This allows us to identify and differentiate a binary string from a regular string object. So to store binary data into a plist data key... @plist = Plist4r.new bstr = "my_binary_data" bstr.blob = true # mark as a binary string @plist.store "MyData", bstr ...and to read or inspect the binary data in Ruby from a {Plist4r::Plist} object @plist.my_data => "my_binary_data" @plist.my_data.blob? => true If we forget the +blob?+ and +blob=+ methods, then we simple are storing and reading our data as a regular textual +String+. So heh, just remember to set +blob=+ true at some point. If we want to perform byte stream IO operations on our binary string... # wrap it in a StringIO object stream = StringIO.new(@plist.my_data) next_byte = stream.getc # or stream.putc(int) to write a byte See http://www.ruby-doc.org/core/classes/IO.html and http://www.ruby-doc.org/core/classes/StringIO.html for more information about the IO object classes. == Plist Types The class {Plist4r::PlistType} allows you to save those more complex data structures to specific plist keys in a plist file. For example the method {Plist4r::PlistType::Launchd#socket} will construct a Socket entry for a launchd plist file. If you are developing a custom application, and intend to exchange data in a custom plist file format, it may be worth writing a custom Plist Type. In which case please see the {file:DeveloperGuide} for more info.