41

I define a path variable in Xcode source tree called "MY_SRC_DIR". I would like to get the value of this environment variable and put it in a NSString in the obj-c code. For example,

-(NSString*) getSourceDir

{

    return @"${MY_SRC_DIR}"; // not the right solution and this is the question

}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189

5 Answers5

66

From http://rosettacode.org/wiki/Environment_variables#Objective-C:

[[NSProcessInfo processInfo] environment] returns an NSDictionary of the current environment.

For example:

[[[NSProcessInfo processInfo] environment] objectForKey:@"MY_SRC_DIR"]
highlycaffeinated
  • 19,729
  • 9
  • 60
  • 91
  • 12
    BUZZZ: Wrong answer; this method will return the environment variables at runtime. The question is about accessing an environment variable that exist at (Xcode) build time. – geowar Feb 06 '13 at 20:11
  • 22
    Perhaps the wrong answer for the OP's question, but the right answer for me! Thanks!! – Chris Nolet Jun 30 '13 at 01:45
  • How can I view the values of those variables from Xcode? – vijayst Nov 10 '14 at 07:15
  • Here is a link to the Xcode Build Setting Reference. https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html – David H. Jan 22 '15 at 22:13
  • 1
    Vijay: easiest way to see the Xcode build environment variables is to add a run script build phase and check the "Show environment variables in build log" checkbox. – geowar Oct 14 '15 at 14:21
  • I think the question was about Runtime - not build-time. So this is probably the best answer. – Motti Shneor Jun 25 '19 at 04:31
31

Just expose the desired var into the Environment Variables list of your current Xcode's deployment Scheme and you'll be able to retrieve it at runtime like this:

NSString *buildConfiguration = [[NSProcessInfo processInfo] environment][@"BUILD_CONFIGURATION"];

It also applies to swift based projects.

Adding Xcode Build Setting Var to Environment var

Hope it helps!! :]

David H.
  • 2,762
  • 1
  • 24
  • 18
  • How secured this ProcessInfo's environment is ? Is is considerable to store ApiKeys in it ? – Ratul Sharker Jun 27 '18 at 09:23
  • Secure in what sense? you, or any other iOS user, cannot set up any environment variable for their apps. They don't use Xcode to launch their apps! And anyway, iOS apps should not use environment variables for configuration, whatsoever. Better save your "API Keys" or whatever sensitive configuration data in the KeyChain. This data is both secure, and persists across App sessions - and even when the app gets updated. – Motti Shneor Jun 25 '19 at 04:28
  • FWIW - I tried this with a React Native application and the values were not read correctly. It could be the case that we have something incorrectly setup in our project, but felt like leaving a note. I won't downvote though as this appears to be a very reasonable answer. – technoplato Jan 28 '21 at 15:34
14

Here is another way to do it:

.xcconfig file:

FIRST_PRESIDENT = '@"Washington, George"'
GCC_PREPROCESSOR_DEFINITIONS = MACRO_FIRST_PRESIDENT=$(FIRST_PRESIDENT)

objective C code:

#ifdef FIRST_PRESIDENT
    NSLog(@"FIRST_PRESIDENT is defined");
#else
    NSLog(@"FIRST_PRESIDENT is NOT defined");
#endif
#ifdef MACRO_FIRST_PRESIDENT
    NSLog(@"MACRO_FIRST_PRESIDENT is %@", MACRO_FIRST_PRESIDENT);
#else
    NSLog(@"MACRO_FIRST_PRESIDENT is undefined, sorry!");
#endif

Console output -- I've stripped out the garbage from NSLog:

FIRST_PRESIDENT is NOT defined
MACRO_FIRST_PRESIDENT is Washington, George
William Jockusch
  • 26,513
  • 49
  • 182
  • 323
  • This is incorrect - you refer to environment variables set at BUILD time - that are accessible to the COMPILER, not the program itself. The question was about RUNTIME environment variables. – Motti Shneor Jun 25 '19 at 04:24
8

The only way I've found to get a build time environment variable as a string is to put it in an dictionary element like this:

<key>Product Name</key>
<string>$PRODUCT_NAME</string>

and then retrieve it like this:

NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];
NSString* productName = infoDict[@"Product Name"];
NSLog(@"Product Name: %@", productName);
geowar
  • 4,397
  • 1
  • 28
  • 24
  • This is a correct answer. It would be ideal to find a way to do it without the info dictionary. But is that possible? – William Jockusch Apr 06 '13 at 16:39
  • This is still using the plist, but at least you can change it at build time. See http://stackoverflow.com/questions/15361202/add-date-to-xcode-xcconfig-file – Chris Prince Dec 29 '14 at 18:32
  • Handy tip. Allows you to use a string defined in an .xcconfig that is build config specific both at runtime as well as in build phase scripts/etc. – Ari Braginsky Oct 08 '15 at 21:36
  • This is NOT an environment variable. This is an Info.plist entry. It is, however, insecure, and not recommended for secret keys and other tokens. – Motti Shneor Jun 25 '19 at 04:30
  • This example puts an environment variable into the plist (at build time) and then uses the code provided to retrieve it (at run time).. – geowar Jun 26 '19 at 11:02
-4

The best answer to this question is the accepted answer on this question.

Constants in Objective-C

You'll get the most mileage, and won't need any special methods to get the value you're searching for as long as you import the file into whatever .h/.m file is going to consume said value.

Community
  • 1
  • 1
bobwaycott
  • 526
  • 2
  • 7