如何使用 PlistBuddy 将数组添加到 Plist?

Posted

技术标签:

【中文标题】如何使用 PlistBuddy 将数组添加到 Plist?【英文标题】:How can I add an Array to a Plist using PlistBuddy? 【发布时间】:2013-03-22 14:36:19 【问题描述】:

这个问题是一个子问题/替代方法来解决我通过这个问题尝试做的事情:How can I use PListBuddy to copy an entry from one file to another?

我想使用 Bash/Shell 通过 XCode 构建脚本使用 PlistBuddy 将条目从 Plist 文件 A 复制到 Plist 文件 B。通过这样做,我无法使用 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####

这是一个生成以下数据的代码的 sn-p:

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 页面非常纤薄,示例也很多。

我要感谢您阅读本文并感谢您的智慧来帮助我解决我脖子上的主要疼痛。

【问题讨论】:

可能有更好的方法来做到这一点,但我已经通过计算源数组中的元素然后单独复制它们来解决这个问题。 $PLISTBUDDY -c "添加 PreferenceSpecifiers:$DEST_INDEX:Titles 数组" $DEST_PLIST $PLISTBUDDY -c "添加 PreferenceSpecifiers:$DEST_INDEX:Titles:0 字符串 'TITLE_1'" $DEST_PLIST $PLISTBUDDY - c "Add PreferenceSpecifiers:$DEST_INDEX:Titles:1 string 'TITLE_2'" $DEST_PLIST 等...我不能将此作为答案发布,直到 8 小时或 10 名声望,所以我现在会评论它。 【参考方案1】:

可能有更好的方法来做到这一点,但我已经通过计算源数组中的元素然后单独复制它们来解决这个问题。

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

【讨论】:

你看过 PlistBuddy 中的import command 吗?听起来很相关,但在entry 下添加了整个目标文件。 是的,我查看了导入命令。它似乎覆盖了目标条目。我需要的是附加/修改目标条目。基本上我所做的是将一个 plist 的内容注入另一个 plist 内容的子集,以创建一个混合 plist 文件。这一切都是通过用于增强调试设置等的编译时构建脚本完成的。【参考方案2】:

它可能会解决您的问题,但它不是在更大的合并脚本中实现的正确方法。在下面检查我的答案。

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

【讨论】:

【参考方案3】:

对于像字符串数组这样简单的东西,这里的代码可以组合任意数量的数组。本示例使用 ios Info plist 中常见的 UIAppFonts 数组。

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

【讨论】:

以上是关于如何使用 PlistBuddy 将数组添加到 Plist?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PlistBuddy 添加设置而不覆盖现有设置?

Xcode - 无法在脚本中使用 PlistBuddy 修改 plist

使用 plistBuddy 获取值数组

Windows 上的 PlistBuddy

如何将游标添加到 PL/SQL 块中的过程中?

我将默认命令迁移到 PlistBuddy,它输出完全相同的 plist,但无法正常工作