7

I'm trying to change a value in an array using plutil, but I get the error

Failed to insert value new value 2 at key path PARENT.0.KEY_IN_ARRAY with error -[__NSCFConstantString characterAtIndex:]: Range or index out of bounds

Here's a sample plist to illustrate the problem:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>SIMPLE</key>
  <string>value1</string>
  <key>PARENT</key>
  <array>
    <dict>
      <key>KEY_IN_ARRAY</key>
      <string>value2</string>
    </dict>
    <dict>
      <key>KEY_IN_ARRAY</key>
      <string>value3</string>
    </dict>
  </array>
</dict>
</plist>

Modifying the SIMPLE value is easy:

$ plutil -extract SIMPLE xml1 -o - sample.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>value1</string>
</plist>

$ plutil -replace SIMPLE -string "new value 1" sample.plist 

$ plutil -extract SIMPLE xml1 -o - sample.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>new value 1</string>
</plist>

Getting the array value works fine:

$ plutil -extract PARENT.0.KEY_IN_ARRAY xml1 -o - sample.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>value2</string>
</plist>

but I get the error when I try to modify this value:

$ plutil -replace PARENT.0.KEY_IN_ARRAY -string "new value 2" sample.plist 
sample.plist: Could not modify plist, error: Failed to insert value new 
value 2 at key path PARENT.0.KEY_IN_ARRAY with error -[__NSCFConstantString 
characterAtIndex:]: Range or index out of bounds
2
  • 1
    This does appear to be a bug. -extract works and -insert fails with the expected complaint of the key already existing; meanwhile -replace and -remove hit this weird string characterAtIndex: thing!
    – natevw
    Nov 30 '18 at 20:12
  • I think the question needs a little re-phrasing, since what you try to replace is NOT a "value in an Array" because the "value" in the "array" is actually a full Dictionary. You attempt to replace only the KEY in the dictionary that is stored in the array Jan 13 at 17:51
8

I think PlistBuddy is the recommended tool here:

/usr/libexec/PlistBuddy -c "Set :PARENT:0:KEY_IN_ARRAY valueX" sample.plist 

The command modifies the value of KEY_IN_ARRAY in the first dict of PARENT. The one in the second dict would be changed with:

/usr/libexec/PlistBuddy -c "Set :PARENT:1:KEY_IN_ARRAY valueY" sample.plist 

The -c switch executes the command directly. The file mustn't be a binary plist!

3
  • not the best of examples. should provide a value in plist file ... then show how that value is replaced with another value of my choice. value not meaning key.
    – mjs
    Nov 6 '19 at 20:31
  • @momomo In my example valueX replaces value2 and valueY value3 in th OP's sample.plist!
    – klanomath
    Nov 7 '19 at 0:17
  • I see, you refer to keys. Meaning you are not replacing anything. You are setting a value for the key.
    – mjs
    Nov 7 '19 at 13:30
2
plutil -replace CFBundleDisplayName -string TestFlightX.com Info.plist

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .