22

There seems to be a lot of variations of how to access the Build Settings variables (i.e. to define the base URL of a web service for different Debug vs. Release environments).

I created a User-Defined variable in Project -> Building Settings, one for each environment. Let's call it WEB_SERVICE_BASE_URL.

How do I access it in the code? I'm using XCode 6 and Swift.

I've tried this but it doesn't work

let api_key = ${WEB_SERVICE_BASE_URL}

I've also tried this and it also doesn't work

let api_key = NSUserDefaults.standardUserDefaults().stringForKey("WEB_SERVICE_BASE_URL")

Any suggestions? This seems to be a often needed solution, it's so easy in Rails, but not so in iOS development.

netwire
  • 7,108
  • 12
  • 52
  • 86
  • The Swift compiler does not include a preprocessor. Instead, it takes advantage of compile-time attributes, build configurations, and language features to accomplish the same functionality. For this reason, preprocessor directives are not imported in Swift. – netwire Jul 09 '14 at 10:42
  • 2
    Still preprocessors are supported in ObjC, why not expose them in ObjC class and make call in Swift. – vladof81 Jul 09 '14 at 14:22
  • Swift has "lite" support of accessing build settings, refer to [Interact with C APIs](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html). – vladof81 Jul 10 '14 at 03:01
  • Follow [this](http://code.tutsplus.com/tutorials/ios-quick-tip-managing-configurations-with-ease--mobile-18324) tutorial, though it uses objective c, it's pretty easy converting to swift. – Norly Canarias Oct 24 '14 at 02:44

1 Answers1

42

Here's how to set it up:

  1. Add a User-Defined setting to your target's Build Settings (which you did with WEB_SERVICE_BASE_URL)
  2. Add a new row to your target's Info.plist file with key: WEB_SERVICE_BASE_URL, type: String, value: ${WEB_SERVICE_BASE_URL}

Here's how get the value:

let api_key = Bundle.main.object(forInfoDictionaryKey: "WEB_SERVICE_BASE_URL") as? String

Note: These keys/values can be extracted from the package, so be sure to avoid storing sensitive data in there.

Dan Loewenherz
  • 10,879
  • 7
  • 50
  • 81
Albert Bori
  • 9,832
  • 10
  • 51
  • 78
  • 2
    Why do you need to add the entry to Info.plist? – Ian Warburton Oct 19 '15 at 17:18
  • 3
    Because the info.plist's `objectForInfoDictionaryKey()` method is how you grab the value that is determined at compile time (via build settings). If you don't add that entry to the .plist file, `objectForInfoDictionaryKey()` will return nil at runtime. There might be other ways to do this, but this way works just fine. – Albert Bori Oct 19 '15 at 21:16
  • Great. Please take a look at my question... http://stackoverflow.com/questions/33220964/cant-access-build-setting – Ian Warburton Oct 19 '15 at 22:10
  • 1
    It was what I was looking for! – Ramis Oct 28 '15 at 13:09
  • Here's a step by step guide (with images) for how to set this up in Xcode https://stackoverflow.com/a/74254208/4975772 – joshuakcockrell Nov 09 '22 at 04:55