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

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.

Related

Change bundle id and name depending on dart-define argument

The general goal is to have two copies of the application installed at the same time, but with different names.
One for the production environment, the other for the test environment.
The environment is NOT determined by the build type (release/debug/profile), but by the value of the -dart-define=myEnv="production/test" variable. And all builds making with --release mode in the ci/cd system and go on a Testflight.
If I understand correctly, this requires changing the App ID.
I have two info.plist files:
ios/Runner/Info.plist:
<key>CFBundleIdentifier</key>
<string>com.testcomp.testapp</string>
ios/Runner/GoogleService-Info.plist
<key>BUNDLE_ID</key>
<string>com.testcomp.testapp</string>
and also the application identifier is specified in the file:
ios/Runner.xcodeproj/project.pbxproj
as:
PRODUCT_BUNDLE_IDENTIFIER = com.testcomp.testapp;
How can I change the Bundle id and Bundle name of the application based on the --dart-define variable?
What I have tried:
Although this script is based on the release/debug parameter, I still tried to add this script to the Build phases:
if [ "${CONFIGURATION}" = "Debug" ]; then
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.testcomp.testapp.test" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName testapp-beta" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName testapp-beta" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :BUNDLE_ID com.testcomp.testapp.test" "$PROJECT_DIR/Runner/GoogleService-Info.plist"
echo "Changed bundle id and name for Debug"
else
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.testcomp.testapp" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName testapp" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName testapp" "$PROJECT_DIR/Runner/Info.plist"
/usr/libexec/PlistBuddy -c "Set :BUNDLE_ID com.testcomp.testapp" "$PROJECT_DIR/Runner/GoogleService-Info.plist"
echo "Changed bundle id and name for PRODUCTION"
fi
but the behaviour was strange:
the first attempt to build after a complete cleanup occurs without error. But the installed application has the old ID and name. The second attempt to build installs the second app with a changed ID and name and a second shortcut appears on the device, but then the Xcode crashes with the following message:
I think that this is due to the fact that the script is editing info.plist files, but flutter store the identifier directly into the ios/Runner.xcodeproj/project.pbxproj file, and I could not change it with the script.
I also moved this script to the very top of the Build phases, and also moved it to the Product->Scheme->Edit Scheme...->Build->Pre-actions. This did not resolve the error.
But again, I need to change Bundle ID and name not depending on the build mode (--release or debug), but from the value of a dart-define variable.
Flutter version: 1.22

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.

How do you change App Transport Security Settings based on the build configuration?

I have an app with multiple build configurations. If the selected configuration is Debug, I want NSAllowsArbitraryLoads key in the Info.plist file to be set as YES, else I want it to be set as NO.
How do I go about achieving this?
The solution I found requires the use of PlistBuddy:
In your project settings, select Build Phase > click + to add a new run script build phase.
Name the phase "App Transport Security".
Paste the following script:
if [ "${CONFIGURATION}" = "Release" ];
then
/usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads false" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
else
/usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads true" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
fi

Can you modify NSExceptionMinimumTLSVersion in the iPhone App Info.plist programmatically?

I use Charles to debug my app requests and responses and it doesn't use the latest version of TLS (which iOS 9 does). Is there a way to update this programmatically so that I can enable it for only local builds done through Xcode? I have a Jenkins build server that still needs to use the new version of TLS.
It is a little messy, but you can use the command line tool PlistBuddy in a Run Script step to accomplish that. Messy because it leaves the actual info.plist changed, so you'll see it in a git history.
The script below will add the exception only on DEBUG builds, and remove any ATS exceptions otherwise. You could edit it to be more specific, or just always add/remove the blanket NSAllowsArbitraryLoads flag.
# Remove exception for all builds
/usr/libexec/PlistBuddy -c "Delete :NSAppTransportSecurity" ${INFOPLIST_FILE} 2>/dev/null
exitCode=$? #Supresses failure if key doesn't exist
# Add exception for Debug builds
if [ "${CONFIGURATION}" == "Debug" ]
then
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity dict" ${INFOPLIST_FILE}
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains dict" ${INFOPLIST_FILE}
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains:<host> dict" ${INFOPLIST_FILE}
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains:<host>:NSIncludesSubdomains bool true" ${INFOPLIST_FILE}
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains:<host>:NSTemporaryExceptionAllowsInsecureHTTPLoads bool true" ${INFOPLIST_FILE}
fi
More info http://product.reverb.com/2015/06/29/ios-9-and-charles-proxy/

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