Core Foundation Property List Services Tasks

The examples in this section demonstrate how to create and work with property lists. The error checking code has been removed for clarity. In practice, it is vital that you check for errors because passing bad parameters into Core Foundation routines can cause your application to crash.

Listing 1 shows you how to create a very simple property list from an array of CFStrings.

Listing 1 Creating a simple property list from an array

#include <CoreFoundation.h> #define kNumFamilyMembers 5 #define kAllocatorDefault NULL void main () { CFStringRef names[kNumFamilyMembers]; CFArrayRef array; CFDataRef xmlData; // Define the family members. names[0] = CFSTR("Marge"); names[1] = CFSTR("Homer"); names[2] = CFSTR("Bart"); names[3] = CFSTR("Lisa"); names[4] = CFSTR("Maggie"); // Create a property list using the string array of names. array = CFArrayCreate( kAllocatorDefault, (const void **)names, kNumFamilyMembers, &kCFTypeArrayCallBacks ); // Convert the plist into XML data. xmlData = CFPropertyListCreateXMLData( kAllocatorDefault, array ); // Clean up CF types. CFRelease( array ); CFRelease( xmlData ); }

Listing 2 shows how the contents of xmlData , created in Listing 1, would look if printed to the screen.

Listing 2 XML created by the program in Listing 1

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> <plist version="0.9"> <array> <string>Marge</string> <string>Homer</string> <string>Bart</string> <string>Lisa</string> <string>Maggie</string> </array> </plist>

Listing 3 shows you how to create a more complex property list, convert it to XML, write it to disk, and then re-create the original data structure using the saved XML. For more information about using CFDictionaries see chapter "Core Foundation Collection Services". The Core Foundation URL access functions are documented in chapter "Core Foundation URL Services".

Listing 3 Saving and restoring property list data

#include <CoreFoundation.h> #define kNumKids 2 #define kNumBytesInPic 10 #define kAllocatorDefault NULL void main () { Boolean status; SInt32 errorCode; CFURLRef fileURL; CFStringRef errorString; CFDataRef resourceData; CFPropertyListRef propertyList; CFMutableDictionaryRef dict; CFNumberRef num; CFArrayRef array; CFDataRef data; CFDataRef xmlData; int yearOfBirth; CFStringRef kidsNames[kNumKids]; // Fake data to stand in for a picture of John Doe. const unsigned char pic[kNumBytesInPic] = {0x3c, 0x42, 0x81, 0xa5, 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c}; // Define some data. kidsNames[0] = CFSTR("John"); kidsNames[1] = CFSTR("Kyra"); yearOfBirth = 1965; // Create a dictionary that will hold the data. dict = CFDictionaryCreateMutable( kAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); // Put the various items into the dictionary. // Because the values are retained as they are copied into the // dictionary, we can release them here. CFDictionarySetValue( dict, CFSTR("Name"), CFSTR("John Doe") ); CFDictionarySetValue( dict, CFSTR("City of Birth"), CFSTR("Springfield") ); num = CFNumberCreate( kAllocatorDefault, kCFNumberIntType, &yearOfBirth ); CFDictionarySetValue( dict, CFSTR("Year Of Birth"), num ); CFRelease( num ); array = CFArrayCreate( kAllocatorDefault, (const void **)kidsNames, kNumKids, &kCFTypeArrayCallBacks ); CFDictionarySetValue( dict, CFSTR("Kids Names"), array ); CFRelease( array ); array = CFArrayCreate( kAllocatorDefault, NULL, 0, &kCFTypeArrayCallBacks ); CFDictionarySetValue( dict, CFSTR("Pets Names"), array ); CFRelease( array); data = CFDataCreate( kAllocatorDefault, pic, kNumBytesInPic ); CFDictionarySetValue( dict, CFSTR("Picture"), data ); CFRelease( data ); // Convert the plist into XML data. xmlData = CFPropertyListCreateXMLData( kAllocatorDefault, dict ); // Create a URL that specifies the file we will create to // hold the XML data. fileURL = CFURLCreateWithFileSystemPath( kAllocatorDefault, CFSTR("test.txt"), // file path name kCFURLHFSPathStyle, false ); // is it a directory? // Write the XML data to the file. status = CFURLWriteDataAndPropertiesToResource ( fileURL, // URL to use xmlData, // data to write NULL, &errorCode); // Read the XML file. status = CFURLCreateDataAndPropertiesFromResource( kAllocatorDefault, fileURL, &resourceData, // place to put file data NULL, NULL, &errorCode); // Reconstitute the dictionary using the XML data. propertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, resourceData, kCFPropertyListImmutable, &errorString); // Release all of the CF objects we're responsible for. CFRelease( fileURL ); CFRelease( dict ); CFRelease( xmlData ); CFRelease( resourceData ); CFRelease( propertyList ); }

Listing 4 shows how the contents of xmlData , created in Listing 3, would look if printed to the screen.

Listing 4 XML created by the program in Listing 3

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"><plist version="0.9"> <dict> <key>Year Of Birth</key> <integer>1965</integer> <key>Pets Names</key> <array/> <key>Picture</key> <data> PEKBpYGlmYFCPA== </data> <key>City of Birth</key> <string>Springfield</string> <key>Name</key> <string>John Doe</string> <key>Kids Names</key> <array> <string>John</string> <string>Kyra</string> </array> </dict> </plist>

© 1999 Apple Computer, Inc. (Last Updated 02 November 99)