macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Using Perl to Manage Plist Files, Part 2
Pages: 1, 2, 3, 4, 5, 6

Changing a Nested Value

To create a key-object pair inside of a nested dictionary, we first have to get the location of the nested dictionary we want to change. We can get it using the shortcut getPlistObject subroutine. If we wanted to change the ComputerName, the following is a reduction of the Plist structure showing the dictionary that we want to grab. It is nested in two other dictionaries.




<dict>
	<key>System</key>
	<dict>
		<key>System</key>
		<dict>
			<key>ComputerName</key>
			<string>Your computer name</string>
			<key>ComputerNameEncoding</key>
			<integer>0</integer>
		</dict>
	</dict>
</dict>

Using the subroutine getPlistObject, we can grab the correct dictionary with this syntax:

getPlistObject( $plist, "System", "System" )

The next example will show the entire process, grabbing the dictionary and changing the computer name.

#!/usr/bin/perl

use Foundation;
use lib "/Users/yourname/Desktop/";
require "perlplist.pl"; # for perlValue and getPlistObject

$file = "/Library/Preferences/SystemConfiguration/preferences.plist";
$plist = NSMutableDictionary->dictionaryWithContentsOfFile_( $file );

if ( $plist and $$plist) {

  # this returns the dict that contains ComputerName
  $computerNameParent = getPlistObject( $plist, "System", "System" );

  if ( $computerNameParent and $$computerNameParent ) {

    print "Original dictionary: " . perlValue( $computerNameParent ) . "\n";

    # set the key ComputerName
    $computerNameParent->setObject_forKey_("New name", "ComputerName");

    print "Changed dictionary: " . perlValue( $computerNameParent ) . "\n";

    # optionally print the whole thing:
    #print perlValue( $plist ) . "\n";

  } else {
    die "Could not find the value.\n";
  }
} else {
  die "Error loading file.\n";
}

The code will print the contents of ComputerName's dictionary. I get:


Original value: {ComputerName = "Firebolt"; ComputerNameEncoding = 0; }
Changed value: {ComputerName = "New name"; ComputerNameEncoding = 0; }

When replacing the object for the key "ComputerName," the change is also visible inside of $plist also. If you uncomment the optional print statement you can see the changed value at the bottom of the long printout:

...snip...



        System = {ComputerName = "New name"; ComputerNameEncoding = 0; }; 
    }; 
}

Now, what if you wanted to change the value in an array? You would use replaceObjectAtIndex_withObject_. Here is the path of the preferences Plist that we will traverse.


<dict>
	<key>Sets</key>
	<dict>
		<key>0</key>
		<dict>
			<key>Network</key>
			<dict>
				<key>Global</key>
				<dict>
					<key>IPv4</key>
					<dict>
						<key>ServiceOrder</key>
						<array>
							<!-- snip -->
						</array>
					</dict>
				</dict>
			</dict>
		</dict>
	</dict>
</dict>

Here is the code that will traverse the Plist and set the first array element.


#!/usr/bin/perl

use Foundation;
use lib "/Users/yourname/Desktop/";
require "perlplist.pl"; # for perlValue and getPlistObject

$file = "/Library/Preferences/SystemConfiguration/preferences.plist";
$plist = NSMutableDictionary->dictionaryWithContentsOfFile_( $file );

if ( $plist and $$plist) {

  $array = 
  getPlistObject( $plist, "Sets", "0", "Network", "Global", "IPv4", 
                  "ServiceOrder" );

  if ( $array and $$array ) {

    print "Original array: " . perlValue( $array ) . "\n";

    $array->replaceObjectAtIndex_withObject_(0, "New value");

    print "Changed array: " . perlValue( $array ) . "\n";

  } else {
    die "Could not find the value.\n";
  }
} else {
  die "Error loading file.\n";
}

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow