How can I add an Array to a Plist using PlistBuddy?

12,134

There may be a better way to do this, but I have solved this problem by counting the elements in the source array and then copying them over individually.

${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Titles array" ${DEST_PLIST}    
${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Titles:0 string 'TITLE_1'" 
${DEST_PLIST} ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Titles:1 string 'TITLE_2'" ${DEST_PLIST} 
etc... 
Share:
12,134
jhthorp
Author by

jhthorp

Updated on June 07, 2022

Comments

  • jhthorp
    jhthorp about 2 years

    This question is a Sub-Question/Alternative Way to approach what I am trying to do via this question: How can I use PListBuddy to copy an entry from one file to another?

    I want to copy an Entry from Plist File A to Plist File B using PlistBuddy through an XCode Build Script, using Bash/Shell. By doing this, I cannot use PlistBuddy's "Copy" function. I must copy each individual entry over with all of it's elements, since you cannot add/set dictionaries, but must interact with PlistBuddy via "Entries".

    What I am trying to do is take Plist File A and store its Titles/Values Arrays for a "PSMultiValueSpecifier" element. I am able to grab the elements in the arrays and print them to the screen, but when I go to add them into the destination Plist file B, the arrays are still empty.

    Code: (Code to Grab the Entry for Adding)

    # Configure the Entry
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX dict" ${DEST_PLIST}
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Type string 'PSMultiValueSpecifier'" ${DEST_PLIST}
    
    # Retrieve the Additional Field Value
    preferenceTitle=`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Title" $SOURCE_PLIST 2>&1`
    preferenceKey=`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Key" $SOURCE_PLIST 2>&1`
    preferenceDefaultValue=`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:DefaultValue" $SOURCE_PLIST 2>&1`
    preferenceValues=`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Values" $SOURCE_PLIST 2>&1`
    preferenceTitles=`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Titles" $SOURCE_PLIST 2>&1`
    

    Code to Add the new Entry:

    # Set the Additional Field Values
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Title string $preferenceTitle" ${DEST_PLIST}
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Key string $preferenceKey" ${DEST_PLIST}
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:DefaultValue integer $preferenceDefaultValue" ${DEST_PLIST}
    ####BORKEN####
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Values array $preferenceValues" ${DEST_PLIST}
    ${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Titles array $preferenceTitles" ${DEST_PLIST}
    ####BORKEN####
    

    Here is a snippet of Code that produces the below data:

    echo "#########"
    echo "[$THIS] adding $preference: $preferenceDict"
    echo "#########"
    echo "Source: "`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Values" $SOURCE_PLIST`
    echo "Source: "`$PLISTBUDDY -c "Print PreferenceSpecifiers:$SOURCE_INDEX:Titles" $SOURCE_PLIST`
    echo "#########"
    echo "Destination: "`$PLISTBUDDY -c "Print PreferenceSpecifiers:$DEST_INDEX:Values" $DEST_PLIST`
    echo "Destination: "`$PLISTBUDDY -c "Print PreferenceSpecifiers:$DEST_INDEX:Titles" $DEST_PLIST`
    echo "#########"
    

    Here is the data provided proving that the proper fields are being transported

    #########
    [addDebugSettingsMenu.bash] adding : Dict {
        Titles = Array {
            Meters
            Feet
        }
        DefaultValue = 1
        Values = Array {
            1
            2
        }
        Key = UserPreferences_UnitsKey
        Type = PSMultiValueSpecifier
        Title = Units
    }
    #########
    Source: Array {     1     2 }
    Source: Array {     Meters     Feet }
    #########
    Destination: Array { }
    Destination: Array { }
    #########
    

    Please help if you have any knowledge regarding undocumented features of PlistBuddy. The MAN pages are super slim and examples are far and between.

    I would like to thank you for reading this and for lending your brains to help me solve this major pain in my neck.

  • Richard
    Richard almost 11 years
    Have you looked at the import command in PlistBuddy? It sounds related, but adds the whole target file under the entry.
  • jhthorp
    jhthorp almost 11 years
    Yeah, I looked over the import command. It seems to overwrite the Target Entry. What I needed was to append/modify the Target Entry. Essentially what I did was inject the contents of one plist into a subset of the contents of another plist to create a hybrid plist file. This is all done by compile-time build scripts for enhanced debugging settings, etc.