Reading plist file from iOS project bundle - ios

I have a plist file customversion.plist which contains 2 properties max_ver (string) and min_ver (string) and are assigned the values 0 and 10 respectively.
Whenever XCode prepares the build, I want to read min_ver value and override Info.plist version using shell script.
I have written the following script:
CUSTOMVERPLIST = "customversion"
buildNumber=$(/usr/libexec/PlistBuddy -c "Print MAX_VER"
${BUILD_ROOT}/${CUSTOMVERPLIST.plist})
buildPlist=${INFOPLIST_FILE}
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $CONFIGURATION-$buildNumber" $buildPlist
My problem is that it seems that customversion.plist file is not being read and not getting the value of min_ver.
Can someone please suggest me about how to read the plist file from project bundle?
Thanks in advance.

${CUSTOMVERPLIST.plist} is not a valid statement. This worked for me:
CUSTOMVERPLIST="${PROJECT_DIR}/${PROJECT_NAME}/customversion.plist"
buildNumber=$(/usr/libexec/PlistBuddy -c "Print MAX_VER" ${CUSTOMVERPLIST})
buildPlist="${INFOPLIST_FILE}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $CONFIGURATION-$buildNumber" $buildPlist

Related

Settings.bundle version number is updating as $(MARKETING_VERSION)

I have an app which was setting versions automatically when I incremented from
XCode > General > Version.
But recently I have updated XCode to 11.0 and seems the script is not working as expected:
version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $SRCROOT/MyApp/Info.plist`
version+=" ("
version+=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $SRCROOT/MyApp/Info.plist`
version+=")"
/usr/libexec/PlistBuddy "$SRCROOT/MyApp/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:1:DefaultValue $version"
Above script suppose to automatically update version and would have been visible in Settings > App.
But the question is there any change need to be done for this script to make automatically update version number from XCode?
Currently it is being replaced by scripts as $(MARKETING_VERSION) when version is incremented from XCode > General > Version which is not correct.
The version string $MARKETING_VERSION as well as build number $CURRENT_PROJECT_VERSION are now exposed as environment variable during the build process as they are now persisted in the .pbxproj configuration.
You should be able to achieve what you want like this:
version="$MARKETING_VERSION ($CURRENT_PROJECT_VERSION)"
/usr/libexec/PlistBuddy "$SRCROOT/MyApp/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:1:DefaultValue $version"
It worked by displaying MARKETING_VERSION itself: Thanks #dgimb and #Mojtaba Hosseini for your answers.
version="$MARKETING_VERSION"
version+=" ("
version+=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $SRCROOT/MyApp/Info.plist`
version+=")"
/usr/libexec/PlistBuddy "$SRCROOT/MyApp/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:1:DefaultValue $version"

How to enable 3D touch(static quick actions) only in debug mode?

Our team is developing an app, and I'd like to add some home screen quick actions just for debug purposes. Also, I want it to be enabled immediately after a fresh install, which means dynamic quick actions would not be an option. However, I have no idea if we can enable static quick actions only in debug mode. Is there any way to achieve this?
You have two major options for this:
- The GENERAL option for any kind of file:
The cleanest way is to have separate files for each configuration. Then:
You can set the path for each configuration in project build settings like this:
Or you can use run script for this or any file you need to change during the build process:
Create two different info.plist files, one for the debug and another for production
Head to the project build settings and create new run script phase
Use the following script:
sourceFilePath="$PROJECT_DIR/$PROJECT_NAME/"
debugFileName="Debug-Info.plist"
releaseFileName="Release-Info.plist"
if [ "$CONFIGURATION" == "Debug" ]; then
cp $sourceFilePath/$debugFileName "$INFOPLIST_FILE"
else
cp $sourceFilePath/$releaseFileName "$INFOPLIST_FILE"
fi
Note that in this example:
I use Debug-Info.plist for debug mode file.
I use Release-Info.plist for release mode file.
I copied all files in same directory as the original info.plist file.
But I made all variables and you can change them to whatever you want.
- The More SPECIFIC option for any plist file:
Since Info.plist is a property list, you can use PlistBuddy to edit any value of of it directly. Here is the example script to add a shortcut item if it is in debug mode only:
/usr/libexec/PlistBuddy -c "Delete :UIApplicationShortcutItems" "$INFOPLIST_FILE"
if [ "$CONFIGURATION" != "Debug" ]; then
exit
fi
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems array" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "delete :UIApplicationShortcutItems" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems array" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0 dict" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemIconType string UIApplicationShortcutIconTypePlay" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemTitle string Play" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemSubtitle string Start playback" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemType string PlayMusic" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemUserInfo dict" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "add :UIApplicationShortcutItems:0:UIApplicationShortcutItemUserInfo:firstShortcutKey1 string firstShortcutKeyValue1" "$INFOPLIST_FILE"
Remember to run this script sometime before Copy Bundle Resources.
I recommend you to always put script codes inside a separate file and call just call it in the build phase.
Obviously the problem is that you are asking an entry in the Info.plist to be present for the debug configuration but not for the release configuration. The contents of the Info.plist don't come and go automatically depending on the configuration. But what file is used as the Info.plist is something that can change depending on the configuration, because it's just a build setting. So one way to solve this would be a special configuration and a special Info.plist to go with it.

Add New Run Script Action for 300+ schemes in Xcode

I have an Xcode project which has over 300 schemes/targets and I have a custom script that I need to run before the app starts building. I've figured out how to do this by editing desired scheme, select Build->Pre-actions->New Run Script Action->Provide Build Settings From and then pasting this script (which dynamically changes version info and bundle id in my notification extension's plist file):
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${SRCROOT}/NotificationService/Info.plist"
buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $buildVersion" "${SRCROOT}/NotificationService/Info.plist"
buildID=${PRODUCT_BUNDLE_IDENTIFIER}
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $buildID.NotificationService" "${SRCROOT}/NotificationService/Info.plist"
The issue is I have to do this for over 300 of my schemes and is a tedious timely effort. Is there some way to apply this to all of my schemes/targets?
Ended up solving issue by creating a fastlane script which basically adds this pre-action run script inside each of the xcscheme files in the appropriate spot in the XML.

Set: Cannot Perform Set On Containers

I am trying to update CFBundleName & CFBundleDisplayName in Info.plist using PlistBuddy
/usr/libexec/PlistBuddy -c "Set : CFBundleName test" info.plist
/usr/libexec/PlistBuddy -c "Set : CFBundleDisplayName test" info.plist
It works perfectly when the file is outside of the Xcode Project But when the file is inside the project It throws "Set: Cannot Perform Set On Containers"
Why it happens and how about solving this without moving the file outside of the project.
Space between colon(:) and key name is the reason why it was throwing the error and now it works as expected
/usr/libexec/PlistBuddy -c "Set :CFBundleName test" info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName test" info.plist

Setting UIPrerenderedIcon from a configuration file in Xcode

It seems I am not able to set UIPrerenderedIcon in my Info.plist, because it is ignored as of iPhone OS 2.1. You can't provide a String value of YES, this is no longer supported.
Is there any other way to do this without necessarly creating a separate Info.plist (e.g., using a preā€“build run script)?
I figured this out. You will have to add a "Run Script" build phase, before "Compile Sources":
#!/usr/bin/env sh
set -o errexit set -o nounset
/usr/libexec/PlistBuddy -c "Set UIPrerenderedIcon ${YOUR_CONFIG_KEY}"
"${PROJECT_DIR}/*-Info.plist"
If you want to set value dynamically using command from shell script or terminal, you can do that as below:
/usr/libexec/PlistBuddy -c "Set :UIPrerenderedIcon YES" YOUR_PLIST_FILE_PATH
/usr/libexec/PlistBuddy -c "Set :CFBundleIcons:CFBundlePrimaryIcon:UIPrerenderedIcon YES" YOUR_PLIST_FILE_PATH

Resources