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

3

8

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.

Argentina answered 22/3, 2013 at 14:36 Comment(1)
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... I cannot post this as an answer until 8 hours or 10 reputation, so I will comment it for now.Argentina
A
3

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... 
Argentina answered 23/3, 2013 at 3:1 Comment(2)
Have you looked at the import command in PlistBuddy? It sounds related, but adds the whole target file under the entry.Dovekie
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.Argentina
S
0

It may fix your problem but it is not the right way to implement in larger merging scripts. Check my ans below.

/usr/libexec/PlistBuddy -x -c "Print PreferenceSpecifiers" ${FROM_PLIST} > ${TO_PLIST}
Sibilate answered 6/8, 2013 at 7:24 Comment(0)
T
0

For something simple like an array of strings, here is code that will combine an arbitrary number of arrays. This example uses the UIAppFonts array common in iOS Info plists.

TMP_NAME=`basename $0`
TMP_DIR=`mktemp -d ${PROJECT_TEMP_DIR}/${TMP_NAME}.XXXXXX` || exit 1
FONTS_PLIST="${TMP_DIR}/Fonts.plist"

/usr/libexec/PlistBuddy -c "Add UIAppFonts array" "${FONTS_PLIST}"

# Iterate through each array, adding to the array entry in the temporary plist
index=0
for arg; do
  status=0
  inner_index=0
  while [ ${status} -eq 0 ]; do
    set +e
    # No easy way to get array length, so keep going until we go out of bounds
    entry=`/usr/libexec/PlistBuddy -c "Print UIAppFonts:${inner_index}" "${arg}" 2> /dev/null`
    status=${?}
    set -e
    if [ ${status} -eq 0 ]; then
      /usr/libexec/PlistBuddy -c "Add UIAppFonts:${index} string ${entry}" "${FONTS_PLIST}"
      index=`expr ${index} + 1`
      inner_index=`expr ${inner_index} + 1`
    fi
  done
done
Tiffa answered 5/9, 2017 at 4:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.