fastlane: Persisting plist updating keys using symbols not working, while string constants work fine
I’m using update_info_plist
action like so:
update_info_plist(plist_path: INFO_PLIST, xcodeproj: XCODEPROJ_PATH, block: lambda { |plist|
plist['working'] = 'foo'
plist[:not_working] = 'bar'
}
First change is being persisted to the file, second change is not.
It appears there is a bug in Xcodeproj::Plist.write_to_path
.
I’m using rvm with ruby 2.2.2 Please let me know if I can provide any more information to solve this.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 15 (12 by maintainers)
Using your project I was able to reproduce the problem. Thank you! 👍
Using a symbol as the key will work, but only if that key is not present in the Plist at the time it is read. So, effectively, it will only work the first time 😫 All the reasons are exactly as @frisocki said above.
Because this problem has a simple work-around, I think I’m going to leave this here.
If we wanted to provide a little more safety, instead of passing the hash to the block directly, we could pass something that proxied for the hash and called
to_s
on all provided keys before updating the hash. If you’re interested in making such a PR, I’d be happy to review it!Thanks!
Thanks for the example project, that’s 💯 ! I will probably get to have a look tomorrow.
Oh yes we fixed the issue by replacing everything with strings. But I don’t mind to experiment to get to the bottom of this. Will try to do it shortly On Wed, Aug 31, 2016 at 9:36 PM, Michael Furtak notifications@github.com wrote:
@zats
When the existing plist file with the key CFBundleDisplayName is read, it is stored in the hash as the string literal
CFBundleDisplayName
. When you attempt to update that value with the symbol:CFBundleDisplayName
, 2 entries are created in the hash:Then when the plist file is written, it attempts to write out both keys and values. Each symbol must be converted to a string, at which point there are basically duplicate keys in the hash.
The underlying implementation ultimately calls (in projects outside of fastlane)
RubyHashToCFDictionary
CFDictionaryAddValue
The 1st
CFDictionaryAddValue
will work, subject to howhash.each
decides to enumerate the keys and values. The 2nd will silently fail.Any reason why you are using a symbol as the hash key and not the string literal? Using a string literal should solve your issue.
The reason it works the 1st time around is there is no collision in the hash key naming.