Oscar Franco

Dynamic iOS icons (build-time)

September 2020

When you have multiple environments it is hard to track which application you might have installed in your phone, in the not so important scenarios it is annoying, your team might be confused and report bugs on WIP builds, but on more serious scenerios you might publish a development build to production and that is a lot more serious.

This is what happened to us at BodyFast this week and here is just one quick way to prevent it: give your app a different icon based on the configuration, now in the past I’ve done this via app flavors for Android and build configurations for iOS, but that process is technically convoluted and also does not work for our use case, so I needed simpler this time around.

So we are going to highjack the build process of iOS to replace the icons based on some configuration file.

1. Get your icons ready

Create all the icons you need, usually to do this I would only change the background or icon color and slap a big “Staging” or “debug” text in front to get rid of all ambiguity, you only need to create a 1024x1024 version and there are many scripts out there that do the resizing for you

2. Add a run script

Go to xcode -> select your project -> select “Build Phases” -> Add a new “run script”

Here is the content of the script:

IFS=$'\n'

CONFIG=production

function generateIcon () {
  BASE_IMAGE_NAME=$1
  
  SOURCE_PATH="${SRCROOT}/../storage/app_icons/${CONFIG}/${BASE_IMAGE_NAME}"
  TARGET_PATH=$(find "${SRCROOT}/BodyFast/Images.xcassets" -name $BASE_IMAGE_NAME)
  echo "Copying ${SOURCE_PATH} into: ${TARGET_PATH}"
  cp $SOURCE_PATH $TARGET_PATH
}

if grep -q development ../.env; then
  echo "Found debug config"
  CONFIG=debug
fi

if grep -q staging ../.env; then
echo "Found staging config"
  CONFIG=staging
fi

echo "Replacing app icons based on configuration"

generateIcon "AppIcon20x20@2x.png"
generateIcon "AppIcon20x20@2x~ipad.png"
generateIcon "AppIcon20x20@3x.png"
generateIcon "AppIcon20x20~ipad.png"
generateIcon "AppIcon29x29.png"
generateIcon "AppIcon29x29@2x.png"
generateIcon "AppIcon29x29@2x~ipad.png"
generateIcon "AppIcon29x29@3x.png"
generateIcon "AppIcon29x29~ipad.png"
generateIcon "AppIcon40x40@2x.png"
generateIcon "AppIcon40x40@2x~ipad.png"
generateIcon "AppIcon40x40@3x.png"
generateIcon "AppIcon40x40~ipad.png"
generateIcon "AppIcon50x50@2x~ipad.png"
generateIcon "AppIcon50x50~ipad.png"
generateIcon "AppIcon57x57.png"
generateIcon "AppIcon57x57@2x.png"
generateIcon "AppIcon60x60@2x.png"
generateIcon "AppIcon60x60@3x.png"
generateIcon "AppIcon72x72@2x~ipad.png"
generateIcon "AppIcon72x72~ipad.png"
generateIcon "AppIcon76x76@2x~ipad.png"
generateIcon "AppIcon76x76~ipad.png"
generateIcon "AppIcon83.5x83.5@2x~ipad.png"

let’s break it down:

and there you have it, you should be able to easily tell your different app environments now, if you couple this with your CI/CD it is even more convenient.

Cheers