Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode using schemes to determine dev/staging/production server URLs

I wish to use Xcode's schemes to determine what server to run my app against. I have an app that fetches its information from a server. Like most people I have a development server, a staging server and a production server.

I wish to create a scheme for each of these where Xcode will inject the correct URL. Do I duplicate the run scheme and add environmental variables? Is this the best way to do things, I don't particularly wish to have #ifdef's in my server class and setting it in code each time I change server. Can anyone point me in the right direction please?

FYI: I'm using Xcode 5.0.2 iOS7 SDK.

[EDIT] Everyone gave some great suggestions but I feel @redent84 answer best suits my needs. Though I found it interesting that none actually suggested using different schemes. [/EDIT]

like image 579
bennythemink Avatar asked Dec 31 '13 21:12

bennythemink


People also ask

What are Xcode schemes?

An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute. You can have as many schemes as you want, but only one can be active at a time.

How do I edit schemes in Xcode?

To view your project's current schemes, click the scheme name in the toolbar of your project window. Xcode displays a pop-up menu with a list of current schemes at the top, and commands to edit, create, and manage schemes at the bottom. To view and modify your project's current schemes, select Manage Schemes.


2 Answers

I recommend you to create different XCode Targets for each environment. I recommend you to change the App Identifier of the Apps, for example, the production app would be com.mycompany.App and the DEVEL version would be com.mycompany.App-DEVEL. This way you can track the Apps separately in HockeyApp or TestFlight, and you can have both applications in the same device at the same time.

Then, add Preprocessor Macros that define the environment for every target. DEVEL for development, for example.

If the URL is hardcoded, simply add a #ifdef instruction to choose the URL:

#ifdef DEVEL
#define ENDPOINT_URL @"http://develserver:8080/EndPoint"
#elif defined(STAGING)
#define ENDPOINT_URL @"http://stagingserver:8080/EndPoint"
#else
#define ENDPOINT_URL @"http://app.mycompany.com/EndPoint"
#endif

This way is less error-prone to distribute a development version, easier to maintain and allows you to add custom code to different versions. For example, you may want to include the version number in the login screen or show alert dialogs for development, but not for distribution version.

like image 185
redent84 Avatar answered Oct 13 '22 13:10

redent84


Use a key in the plist (for each schema, eg: URL_TO_USE), use define to create a 'shortcut' to get the value.

  #define MyURL [[NSBundle mainBundle] objectForInfoDictionaryKey:@"URL_TO_USE"]

EDIT

You must have multiple targets. Each target should point to a different .plist file. See: How to configure independent sets of runtime settings in XCode

like image 36
rufo Avatar answered Oct 13 '22 12:10

rufo