How can I use PListBuddy to copy an entry from one file to another?
Asked Answered
S

1

4

I have been a long-time viewer on StackOverflow, always finding my solution as necessary, but I have found a question with no solution after a very dedicated week of researching.

What I am trying to do is expand upon this guy's research: http://mrox.net/blog/2008/11/16/adding-debug-only-preferences-in-iphone-applications/

I want to have the Debug Menu appear as part of the main Plist file, not as a Sub-Pane.

So far, I have about 95% of the Plist Types working with minor issues. In a nut shell, I am basically iterating through the "Debug" Plist and then portraying them onto the Destination Plist.

Now, for some reason, Multiple Values will not work in this form as Titles/Values do not seem to be set appropriately (No idea why - Code added below for perusing).

One solution that I have found that DOES work is to use PlistBuddy's COPY command and copy the Entry over, but this is limited to the same file, which is not what I need.

So, in summary: I want to copy an Entry from Plist File A to Plist File B using PlistBuddy through an XCode Build Script, using Bash/Shell.

Code as mentioned above: (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}
${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Values array $preferenceValues" ${DEST_PLIST}
${PLISTBUDDY} -c "Add PreferenceSpecifiers:$DEST_INDEX:Titles array $preferenceTitles" ${DEST_PLIST}

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.

EDIT: After some more investigation, the Entry is being populated successfully, except for the Arrays. Please see Code/Output below for details.

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 { }
#########

Edit #2: I have discovered that I can properly add the arrays by breaking them up and adding the individual elements as such:

${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 am still hoping that there is a better solution out there.

Snyder answered 22/3, 2013 at 4:50 Comment(1)
Well, after 500 lines of script and a crude "Array Copy Mechanism", I have this working now. I will not officially "Answer" this question until I have a "cleaner" solution, something that I am hoping someone is able to respond and assist with.Snyder
M
0

Here's what you need to do to copy an array from one plist to another:

# Print the array to a temporary file.
/usr/libexec/PlistBuddy -x -c "Print arrayKey" source.plist > temporary.plist

# Add an entry for this array in the destination file. You can use any key.
/usr/libexec/PlistBuddy -c "Add newArrayKey array" destination.plist

# Merge the temporary file (generated in the first step) into the destination file
/usr/libexec/PlistBuddy -c "Merge temporary.plist newArrayKey" destination.plist

# (Optional) Delete temporary file
rm temporary.plist
Marilou answered 7/6 at 13:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.