Как добавить массив в Plist с помощью PlistBuddy?

этот вопрос Является под-вопросом / альтернативным способом подойти к тому, что я пытаюсь сделать с помощью этого вопроса:как я могу использовать PListBuddy для копирования записи из одного файла в другой?

Я хочу скопировать запись из файла Plist A в файл Plist B с помощью PlistBuddy через скрипт сборки XCode, используя Bash / Shell. Делая это, я не могу использовать функцию "Копировать" PlistBuddy. Я должен скопировать каждую отдельную запись со всеми ее элементами, так как вы не можете добавить/установить словари, но должны взаимодействовать с PlistBuddy через "записи".

то, что я пытаюсь сделать, это взять файл Plist A и сохранить его массивы заголовков/значений для элемента "PSMultiValueSpecifier". Я могу захватить элементы в массивах и распечатать их на экране, но когда я иду, чтобы добавить их в целевой файл Plist B, массивы все еще пусты.

код: (код, чтобы захватить запись для добавления)

# 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`

код для добавления нового Запись:

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

вот фрагмент кода, который производит следующие данные:

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 "#########"

вот данные, представленные, доказывающие, что соответствующие поля транспортируются

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

пожалуйста, помогите, если у вас есть какие-либо знания о недокументированных функций PlistBuddy. MAN-страницы супер тонкие, а примеры далеко и между ними.

Я хотел бы поблагодарить вас за чтение этого и за предоставление ваших мозгов, чтобы помочь мне решить эту главную боль в моей шея.

3 ответов


может быть лучший способ сделать это, но я решил эту проблему, подсчитав элементы в исходном массиве, а затем скопировав их по отдельности.

${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... 

это может исправить вашу проблему, но это не правильный способ реализации в больших сценариях слияния. Проверить мой ответ ниже.

/usr/libexec/PlistBuddy -x -c "Print PreferenceSpecifiers" ${FROM_PLIST} > ${TO_PLIST}

для чего-то простого, как массив строк, вот код, который будет объединять произвольное количество массивов. В этом примере используется массив UIAppFonts, общий для информационных списков iOS.

TMP_NAME=`basename `
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