Detecting Debug and Release Builds in iOS and Android

In some situations, your code may need to distinguish between development mode and final production mode. A common use case for this is to hit different backend service URLs during development and production. Both iOS and Android do a debug build during development and release build when the application package is exported.

The Basics

An iOS or Android application is built in debug mode when you run the application from Xcode or Eclipse, either in a device or an emulator.

The application is built in release mode when you export the application’s package. For iOS, that will be building and exporting the application archive from Xcode. For Android, that will be exporting the APK from Eclipse.

The iOS Story

In iOS, in debug mode, the DEBUG preprocessor directive is defined. That makes it very simple to distinguish a debug build from release. For example:

//For archive build use production servers.
#ifndef DEBUG
#define BASE_SERVICE_URL @""

//For developer build, use QA servers
#ifdef DEBUG
#define BASE_SERVICE_URL @""

The Android Story

During a debug build, the build system automatically adds the android:debuggable=”true” attribute to <application> element of the manifest file. (You should never manually set this flag). During a release build, this attribute is removed. Your code will need to detect the existence of the flag to distinguish a debug build from release.

android.content.Context ctx = ...;
String BASE_SERVICE_URL = null;

try {
    if ((ctx.getPackageManager().getPackageInfo(
        ctx.getPackageName(), 0).applicationInfo.flags & 
        ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
        //Debug and development mode
        BASE_SERVICE_URL = "";
    } else {
        //Release mode
        BASE_SERVICE_URL = "";
} catch (NameNotFoundException e) {
    throw new IllegalStateException(e);

Caveat in Android

There is another way to distinguish a debug build from release in Android. The build system generates a class called BuildConfig. It has a public static boolean field called DEBUG. This is set to true during a debug build and false during a release build. It is easier to use this system:

if (BuildConfig.DEBUG) {
    //Debug build
} else {
    //Release build

However, there is a nasty bug in ADT. If the project depends upon an Android library project, the variable is never set to false during a release build. A workaround is to do a clean and rebuild before exporting the APK. But, that is not very convenient. At the time of this writing, I will recommend you against using this scheme.

3 thoughts on “Detecting Debug and Release Builds in iOS and Android

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s