.plist tutorial

Discussion in 'Mac Programming' started by john903, Apr 24, 2008.

  1. john903 macrumors member

    Joined:
    Apr 11, 2008
    #1
    Is there a tutorial anywhere that shows you how to work with preference (.plist) files in Carbon?
     
  2. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #2
    What do you want to do? Read/write values? Use CoreFoundation:

    Code:
    CFStringRef	appName = CFSTR("com.mycoolco.MyColorApp");
    CFStringRef	colorAlphaKey = CFSTR("colorAlpha");
    CFStringRef	colorStructCustomNameKey = CFSTR("colorStructCustomName");
    CFStringRef	alphaPreviewCustomKey = CFSTR("alphaPreviewCustom");
    Boolean		keyExists;
    CFNumberRef		inVal;
     
        
            inVal = CFPreferencesCopyAppValue(colorAlphaKey, appName);
    
            if (inVal) {
            
             if (!CFNumberGetValue(inVal, kCFNumberFloat32Type, &displayColor[3])) displayColor[3] = 1.0;
            
             CFRelease(inVal); // Any CoreFoundation function with Copy in the name must be released explicitly
    
            }
    
            gAlphaPreviewImageCustom = CFPreferencesGetAppBooleanValue(alphaPreviewCustomKey, appName, &keyExists);
     
  3. john903 thread starter macrumors member

    Joined:
    Apr 11, 2008
    #3
    Thanks for the sample code!

    CFPreferencesCopyAppValue seems to return a CFPropertyListRef. If I try to set it to CFNumberRef it won't compile.

    Do you have any sample code on working with CFPropertyListRef?

    I looked at the documentation but I don't understand how to get data out of this value.
     
  4. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #4
    It returns a "abstract" type because the value returned could be anything e.g. a number, a string or a boolean.

    You could try casting to the type you want:

    Code:
        CFNumberRef		inVal;
        
        inVal = (CFNumberRef)CFPreferencesCopyAppValue(colorRedKey, appName); 
     
  5. john903 thread starter macrumors member

    Joined:
    Apr 11, 2008
    #5
    Thanks! I didn't realize it was that simple.

    I have a question on setting values with CFPreferencesSetAppValue. How do you properly create a CFPropertyListRef with a value such as number or a string to use with this function?
     
  6. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #6
    You do the same thing as above basically. The abstract type is just that, abstract, it can be any valid CF type. You don't tell the API what type it is you are passing in, it figures it out because the CoreFoundation types are really structs with other pieces of info that describe the contents (type).

    Code:
         CFStringRef      colorRedKey = CFSTR("colorRed");
         CFStringRef      alphaPreviewCustomKey = CFSTR("alphaPreviewCustom");
         CFNumberRef      outVal;
    
        // Here we tell CoreFoundation what type of number this is
        outVal = CFNumberCreate(NULL, kCFNumberFloat32Type, &displayColor[0]);
    
        CFPreferencesSetAppValue(colorRedKey, outVal, appName);
    
        CFRelease(outVal);
    
        if (gAlphaPreviewImageCustom) {
        
            CFPreferencesSetAppValue(alphaPreviewCustomKey, kCFBooleanTrue, appName);
        
        } else {
        
            CFPreferencesSetAppValue(alphaPreviewCustomKey, kCFBooleanFalse, appName); 
              
        }
    
        // Force the changes to be saved to disk immediately
        (void)CFPreferencesAppSynchronize(appName);
    You may also want to Get Info on the target and see if "Treat all warnings as errors" is turned on in in the Build tab. This may have been why you had to cast the return value to a concrete return value from the CF api above - it was most likely just a warning of a type-mismatch treated as an error.
     
  7. john903 thread starter macrumors member

    Joined:
    Apr 11, 2008

Share This Page