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

We can write a shortcut subroutine that behaves nearly the same as getPlistObject. However, this one treats the last two parameters differently. It takes the second to last parameter and uses it as the key or index to set. It takes the last parameter and uses it for the object to set.



If we are adding an object to an array and the index we specify is higher than the number of elements in the array, the subroutine will just add the object to the end of the array.

Here is the subroutine and an example changing the same setting as above.

#!/usr/bin/perl

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

sub setPlistObject {
  my ( $plistContainer, @keyesIndexesValue ) = ( @_ );
  my $objectToSet = pop ( @keyesIndexesValue );
  my $keyIndex = pop ( @keyesIndexesValue );
  my $parentContainer = getPlistObject ( $plistContainer, 
                                         @keyesIndexesValue );
  if ( $parentContainer and $$parentContainer ) {
    if ( $parentContainer->isKindOfClass_( NSArray->class ) ) {
      if ( $keyIndex > $parentContainer->count -1 ) {
        $parentContainer->addObject_( $objectToSet );
      } else {
        $parentContainer->replaceObjectAtIndex_withObject_( $keyIndex, 
                                                            $objectToSet );
      }
    } elsif ( $parentContainer->isKindOfClass_( NSDictionary->class ) ) {
      $parentContainer->setObject_forKey_( $objectToSet, $keyIndex );
    } else {
      print STDERR "Unknown parent container type.\n";
    }
  } else {
    print STDERR "Could not get value specified by @keyesIndexesValue.\n";
  }
}

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

if ( $plist and $$plist) {

  # set the object.
  setPlistObject( $plist, "Sets", "0", "Network", "Global", 
                  "IPv4", "ServiceOrder", 0, "1234" );

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

} else {
  die "Error loading file.\n";
}

If you change the second to last value, 0, to some other value, you can see that the index of "1234" changes in the array. And if you make it larger than the original array, it will be just added to the end.

Saving a Plist File

Once we have changed our Plist, we can save it. Just add this line to save it:

$plist->writeToFile_atomically_( "/tmp/preferences.plist", "0" );

If you want to save to the desktop and you don't want to use the full path, you can use the relative path with the stringByExpandingTildeInPath() method:


my $relativePath = NSString->stringWithFormat_( "~/Desktop/preferences.plist" );
my $file = $relativePath->stringByExpandingTildeInPath();
$plist->writeToFile_atomically_( $file, "0" );

Now we can read and change Plist files. There are two more tasks. We can scan an entire Plist file, and we can create one from scratch.

Scanning a Plist File

At some point you may want to loop through every value of an array or hash. In Perl, you can scan arrays and hashes using foreach or while loops like these examples:


@array = (1,2,3);

foreach $i ( @array ) {
  print "$i\n";
}

%hash = ( key=>"value", key2=>"value2");

while ( my ( $key, $value ) = each( %hash ) ) {
  print "Key: " . $key . "\n";
  print "Value: " . $value . "\n";
}

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

Next Pagearrow