Skip to content

Instantly share code, notes, and snippets.

@unnamedd
Forked from acrookston/README.md
Created June 14, 2017 17:15
Show Gist options
  • Save unnamedd/12b7482d4388c0b85e483c6d7c45476e to your computer and use it in GitHub Desktop.
Save unnamedd/12b7482d4388c0b85e483c6d7c45476e to your computer and use it in GitHub Desktop.
Xcode pre-action to build custom Info.plist

Automatic build versions from git in Xcode (and other goodies)

Installation procedure for pre-build actions to automatically populate Xcode Info.plist with dynamic data.

1. Xcode Scheme pre-action

Edit Xcode Scheme and add a pre-action script. Copy the contents of preaction.sh into the pre-action script box.

2. Copy processing file

  1. Copy build_environment.sh to config/environments/build_environment.sh.
  2. Modify it's variables or path to environment_preprocess.h as needed.

3. Edit Xcode Build Settings

  1. For the Project Build Settings add a new User-Defined variables called ENVIRONMENT, for each scheme set the appropriate name eg development or production.
  2. For each Target Build Settings set Preprocess Info.plist file to YES.
  3. Enter environment_preprocess.h (or the output file if you renamed it build_environment.sh) into Info.plist Preprocessor Prefix File

4. Install plist file

Copy development.plist file to config/environments/development.plist. DO NOT include this file in any Target Memberships.

If you have several schemes setup in the previous step (ENVIORMENT) you need to copy this file to each option if you use multiple build schemes and ENVIRONMENT variables.

5. Setup environment variables

This file development.plist (and others) is used to populate data in the build_environment.sh script. Modify contents as needed and don't forget to also modify the build_environment.sh accordingly.

This is really where the magic happens. The rest is just for running this script and processing the output.

TIP 1: You can run pretty much anything in the environment_preprocess.h script if you want to setup link to a local development server you can use the hostname command to get your current build computer's network name. TIP 2: You can use it to use git commit count as the build version/number.

(Both of these are included in the script already.)

6. Using environment variables

  1. Use those generated environment variables in your Info.plist.

7. Run Build!

This will generate the environment_preprocess.h file and make it available for inclusion in your Info.plist It's advisable to exclude the generated file from any version control system.

#!/bin/sh
# build_environment.sh
#
# Created by Andrew C on 7/27/15.
# Released under MIT LICENSE
# Copyright (c) 2015 Andrew Crookston.
cd "${PROJECT_DIR}"
dir=${PROJECT_DIR}/config/environments
echo "Starting environment ${ENVIRONMENT} configuration for ${PROJECT_NAME}/${PROJECT_FOLDER} with config in " $dir
echo "Host: " `hostname`
# environment variable from value passed in to xcodebuild.
# if not specified, we default to DEV
env=${ENVIRONMENT}
if [ -z "$env" ]
then
env="development"
fi
echo "Using $env environment"
# copy the environment-specific file
cp $dir/$env.plist $dir/environment.plist
# Date and time that we are running this build
buildDate=`date "+%F %H:%M:%S"`
todaysDay=`date "+%d"`
# app settings
appName=`/usr/libexec/PlistBuddy -c "Print :AppName" "$dir/environment.plist"`
appGroup=`/usr/libexec/PlistBuddy -c "Print :AppGroup" "$dir/environment.plist"`
version=`/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$dir/environment.plist"`
hostname=`/usr/libexec/PlistBuddy -c "Print :HostName" "$dir/environment.plist"`
hostscheme=`/usr/libexec/PlistBuddy -c "Print :HostScheme" "$dir/environment.plist"`
bundle=`git rev-list master |wc -l | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'`
if [ "$env" == "development" ]
then
hostname=`hostname`
# need to dynamically append today's day for non-prod
appName="$appName-$todaysDay"
# Last hash from the current branch
#version=`git log --pretty=format:"%h" -1`
fi
buildhost=`hostname`
# Build the preprocess file
cd "${PROJECT_DIR}"
preprocessFile="environment_preprocess.h"
echo "Creating header file ${PROJECT_DIR}/${preprocessFile}"
echo "//------------------------------------------" > $preprocessFile
echo "// Auto generated file. Don't edit manually." >> $preprocessFile
echo "// See build_environment script for details." >> $preprocessFile
echo "// Created $buildDate" >> $preprocessFile
echo "//------------------------------------------" >> $preprocessFile
echo "" >> $preprocessFile
echo "#define ENV $env" >> $preprocessFile
echo "#define ENV_APP_NAME $appName" >> $preprocessFile
echo "#define ENV_APP_GROUP $appGroup" >> $preprocessFile
echo "#define ENV_APP_VERSION $version" >> $preprocessFile
echo "#define ENV_HOST_NAME $hostname" >> $preprocessFile
echo "#define ENV_BUILD_HOST $buildhost" >> $preprocessFile
echo "#define ENV_BUNDLE_VERSION $bundle" >> $preprocessFile
echo "#define ENV_HOST_SCHEME $hostscheme" >> $preprocessFile
# dump out file to build log
cat $preprocessFile
# Force the system to process the plist file
echo "Touching all plists at: ${PROJECT_DIR}/**/Info.plist"
touch ${PROJECT_DIR}/**/Info.plist
# done
echo "Done."
<?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>README</key>
<string>Copy this file to config/environments/development.plist. DO NOT add it to the targets! It gets copied to environment.plist during build. See build_environment script for more.</string>
<key>AppGroup</key>
<string>your.app.group</string>
<key>HostName</key>
<string>localhost</string>
<key>AppName</key>
<string>Your app name</string>
<key>CFBundleShortVersionString</key>
<string>1.1</string>
<key>RandomKey</key>
<string>whatever you want</string>
</dict>
</plist>
#!/bin/sh
cd $PROJECT_DIR
exec > $PROJECT_DIR/pre_action.log 2>&1
source $PROJECT_DIR/config/environments/build_environment.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment