This is a gist which should provide a modular way of adding Environment settings to your iOS or Mac application like described in the excellent article from the guys at CarbonFive.
This Framework maps different Xcode configurations, Debug
and Release
being the default, to different sets of settings or Environments like development, staging1, staging2, production and so on.
All the different settings are stored in the Environments.plist
file as dictionaries with the given environment as the key.
Check out the gist
Execute the following script to install (Please change the variables accordingly):
# Only customization
export YOUR_TARGET=ADD_NAME_HERE
# Folders
export VENDOR_FOLDER=$YOUR_TARGET/Vendor/Environment
export PERSONAL_FOLDER=$YOUR_TARGET/Environment
# Clone the file
git clone [email protected]:2782045.git $VENDOR_FOLDER
# Add the git module
echo "
[submodule \"Environment\"]
path = ${VENDOR_FOLDER}
url = git://gist.github.com/2782045.git
" >> .gitmodules
# Create the initial files
mkdir -p $PERSONAL_FOLDER
cp $VENDOR_FOLDER/Environments.template.plist $PERSONAL_FOLDER/Environments.plist
echo "" > $PERSONAL_FOLDER/Environment+$YOUR_TARGET.h
echo "" > $PERSONAL_FOLDER/Environment+$YOUR_TARGET.m
echo "Don't forget to add the files to Xcode
$PERSONAL_FOLDER
$VENDOR_FOLDER
"
-
In your project settings on the Info tab add any new categories such as
Preview
-
Add the
.h
,.m
and.plist
file in theEnvironmentGist
directory to Xcode -
Add a new key to your app's
-Info.plist
file:<key>Environment</key> <string>${CONFIGURATION}</string>
-
Update the
Environments.plist
file with your desired environments which should be top-level dictionaries. They need to correspond with the environments, that you have configured in your project (Step 1). -
Add a category for
Environment.h
which contains the properties that you need:#import <Foundation/Foundation.h> #import "Environment.h" @interface Environment(YourApp) ENVIRONMENT_PROPERTY(myApiURL) @end
The implementation
#import "Environment+YourApp.h" @implementation Environment(YourApp) ENVIRONMENT_GETTER(myApiURL) @end
-
Update the projects
.pch
file and add the created category:#import "Environment+YourApp.h"
-
Add different bundle identifiers for the different configurations:
- For your target in Build Settings add a
User Build Setting
ENVIRONMENT_SUFFIX
and set it to${CONFIGURATION}
for all but theRelease
configuration. - Change the
Bundle Identifier
in yourInfo.plist
file to `com.domain.yourapp${ENVIRONMENT_SUFFIX}.
This will result in
com.domain.yourapp-Debug
for example. Please note that all changes require a Clean to take effect. - For your target in Build Settings add a
-
And your icon files
CFBundleIcons
.<?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>CFBundlePrimaryIcon</key> <dict> <key>CFBundleIconFiles</key> <array> <string>Icon${ICON_SUFFIX}.png</string> <string>Icon${ICON_SUFFIX}-72.png</string> <string>Icon${ICON_SUFFIX}@2x.png</string> </array> <key>UIPrerenderedIcon</key> <true/> </dict> </dict> </plist>
-
Optionally, also add the same kind of suffix to the
CFBundleDisplayName
When reading a value use the following syntax to return a given value from the Environments.
[Environment sharedInstance].myApiURL
Please note that all newly defined properties should be added to your category. However, values can also be accessed like so:
[[Environment sharedInstance] valueForKey:@"myKey"]
It is possible to define an Environment as a master by adding the key _isMaster = YES
as a subkey in the Environments.plist
file.
Example:
Assume that there are two Configurations defined: Release
and Preview
. The Release
Environment has the _isMaster
key set.
Even if the current Envrionment is set to Preview
, any values that don't exist there will be looked up in the Release
Environment.
-
The Environment.plist ends up in the App bundle and is not encrypted
-
Nested substitutions of values would be cool:
baseURL = http://domain.com/api contactsURL = {baseURL}/contacts