5

In my development I wish to hit a development URL when im testing but when the app is run on my iPhone, I want it to run on production URL. How do I get about setting this in Xcode?

Almost seems like I need to be able to set environmental variables (which in this case are different URLs).

Where do I set these up? Please hand hold me on the answer as I am fairly new

Thanks

John Topley
  • 113,588
  • 46
  • 195
  • 237
Strong Like Bull
  • 11,155
  • 36
  • 98
  • 169
  • Here are a few different approaches: http://qualitycoding.org/production-url/ – Jon Reid Jul 20 '12 at 20:25
  • I generally set it in the build configuration. You can do additional things like changing the display name/bundle ID (this allows both "production" and "development" builds to be installed on the same phone, and means you can tell roughly what's installed without bringing up a settings view). – tc. Jul 21 '12 at 01:10

3 Answers3

13

There are lots of ways to do this. My preferred method is to create a file called Constants.h that looks like this:

//
//  Constants.h
//

#ifndef Constants_h
#define Constants_h

#pragma mark - Instances
#ifdef DEVELOPMENT
#define ROOT_URL @"http://127.0.0.1:8000"
#endif

#ifdef STAGING
#define ROOT_URL @"http://staging.example.com"
#endif

#ifdef PRODUCTION
#define ROOT_URL @"http://production.example.com"
#endif

Then, I just include it in my *-Prefix.pch file like this:

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import "Constants.h"
#endif

In your build settings, set DEVELOPMENT, or STAGING, or PRODUCTION = 1.

Now you can access things like ROOT_URL anywhere in your project.

Good luck!

Erik
  • 7,479
  • 8
  • 62
  • 99
  • recall (especially if you have a slow machine and/or a large project) that changes to the precompiled header will cause a recompile of everything. while the values of these URLs should be nicely encapsulated into one file (though the values of DEVELOPMENT/STAGING/PRODUCTION may not be). – bshirley Jan 15 '13 at 19:14
  • +1 for importing it in Prefix.pch. Works well when sharing code. – itslittlejohn Sep 23 '13 at 20:40
  • 2
    also how do you set up devleopment or staging equals to true,cannot seem to find the field in build setting – alexzg Feb 11 '14 at 02:46
2

I prefer the #define method as well. For those less familiar, those are pre-processor directives and are set even before the compiler gets hold of the code.

Environment variables are set at runtime of the program, and can be manipulated in the scheme editor of Xcode 4.x+. You could set up different schemes to hit different testing environments.

To access an environment variable at runtime from within your code, use the following:

NSString *url = @"http://standardurl.com";
NSDictionary *env = [[NSProcessInfo processInfo] environment];
NSString *overrideURL = [env valueForKey:@"url"];
if (overrideURL != nil)
  url = overrideURL;
bshirley
  • 8,217
  • 1
  • 37
  • 43
  • 1
    Here's a helpful macro that you can add to your Prefix.pch file: `#define ENVIRONMENT_VARIABLE_DEFINED(v) ([[[NSProcessInfo processInfo] environment] valueForKey:v] ? YES : NO)` This lets you add environment variables in Xcode's scheme editor, and toggle them on/off using the checkbox to change your code at runtime. To use this macro: `if (ENVIRONMENT_VARIABLE_DEFINED(@"ENV_VAR_NAME")) { ... }` – smileyborg Mar 30 '14 at 21:10
-1

You can also set the different URLs in your plist file by adding new String rows if you don't want to use a constants file.

(Not much to be gained here though I admit but depends on where you prefer to set up your urls)

In your myApp-plist file add new rows like this:

"DevelopmentEndpoint" "String" "http://development.endpoint.com"

"ProductionEndpoint" "String" "http://production.endpoint.com"

In your code:

// Get endpoint from main bundle
#ifdef DEVELOPMENT
    NSString *endpoint = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"DevelopmentEndpoint"];
#else
    NSString *endpoint = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"ProductionEndpoint"];
#endif

In your build settings add DEVELOPMENT under the "Preprocessor Macros" section for Debug or Release etc.

nuxibyte
  • 1,434
  • 1
  • 13
  • 16
  • 1
    @tc Very valid point. I wasn't considering security. I suggest others follow Erik's advice. – nuxibyte Jul 21 '12 at 17:22
  • At best it's a (security-through-)obscurity problem (dev URLs tend to be easily guessable); it mostly just seems untidy to embed dev data in a production build. – tc. Jul 23 '12 at 15:11