Showing posts with label xcode. Show all posts
Showing posts with label xcode. Show all posts

Monday, April 4, 2011

iOS Dev, Beta & Production builds installed side-by-side

A development and testing pattern I adopted early on for my iOS projects was to configure projects such that development, ad hoc test and release builds could all be installed on my device at the same time. This allows for side-by-side testing and easy comparison of the builds, each being at different states of completion at any point in time.


For example, this iPhone screen snapshot demonstrates dev, beta & release builds of my hobby project River Level installed side-by-side.


Dev, beta & release builds of River Level installed side-by-side
iOS differentiates apps by their Bundle Identifiers (CFBundleIdentifier) which are defined in the Project-Info.plist.  A Bundle Identifier looks like a reverse DNS address, e.g. "com.apple.safari". What I like to do is to set the Bundle Identifier to different values for each build configuration, thus allowing each to be installed separately. I don't do this manually, though, as I'll explain below.


Note that some iOS features – like Push Notifications, Game Center and In-App Purchase – require the Bundle Identifier to match the value configured in iTunes Connect so you can test these features. In those cases this technique won't be effective, unless you set up multiple app instances in iTunes Connect for each build configuration.


The other parameter I customise per build configuration is the Bundle Display Name (CFBundleDisplayName). This is the app name as displayed on the home screen. iOS doesn't require these names to be unique, so if you changed the Bundle Identifiers without changing the Display Names you would end up with multiple instances of your app all with the same name and icon, making it difficult to work out which build is which.


My convention is to append "∆" to dev builds and "ß" to ad hoc builds.


To customise the Bundle Identifier and Bundle Display Name per build the process is:

  • Append ${BUNDLE_ID_SUFFIX} to the "Bundle identifier" in Project-Info.plist.
  • Append ${BUNDLE_DISPLAY_NAME_SUFFIX} to the "Bundle display name" in Project-Info.plist.
Custom variables appended to Bundle Display Name and Bundle Identifier values



Note that with no other changes these variables will be expanded to empty strings and so will have no effect. This is how I handle Release builds, so they are submitted to the App Store with standard values.


The next step is to define the custom values for each build configuration.  My convention is:


Development (Debug) builds:
  BUNDLE_DISPLAY_NAME_SUFFIX=∆
  BUNDLE_ID_SUFFIX=.dev


Ad Hoc builds:
  BUNDLE_DISPLAY_NAME_SUFFIX=ß
  BUNDLE_ID_SUFFIX=.adhoc

Release builds:
  Neither of these settings is defined.


The place to put these settings is in each relevant Build Configuration of the Project. Note: some people edit the build configuration for their Target, but I recommend only doing this if you need a setting specifically for a build target.  If you only have one target, edit the build settings for the whole Project.  That way, if you add Targets later they will inherit the Project build settings.


To add custom settings to build configurations, in Xcode 3:

  • Select menu "Project" / "Edit Project Settings"
  • Select "Build" tab
  • Select a build configuration in the Configuration list (e.g. "Debug")
  • Select "Add User-Defined Setting" from the command list (bottom left corner pulldown)
  • Add a user-defined setting for each of "BUNDLE_DISPLAY_NAME_SUFFIX" and "BUNDLE_ID_SUFFIX" with the values you choose.
  • Repeat this for each build configuration that you want to install separately to the others.

User-defined settings for a Debug build configuration
In Xcode 4, the process is similar, although the UI has changed.  Select your project; select the "Build Settings" tab, then select "Add Build Setting"/"Add User-Defined Setting". You can set the values for Debug and Ad Hoc at the same time with the new UI.


To see any user-defined settings, scroll the build settings table to the bottom; or use the "Show" list to filter only "User-Defined Settings" (Xcode 3).


To delete a user-defined setting, highlight the setting and hit the delete key.


That's it. Now re-build and install and the app should appear separately to the other builds. Feel free to install as many different builds as you feel like.