Home > Software engineering >  Storing Global/Environment Variables in iOS Swift Apps
Storing Global/Environment Variables in iOS Swift Apps

Time:10-08

I'm a JavaScript web app developer that has just inherited a legacy iOS app. The app is full of hardcoded URLs that point to our production API.

I'd like to factor out the Base URL into a constants file, or an environment variables file, or a config file, so that a different Base URL can be used in different environments (dev, staging, production).

What's the best practice in the land of the Swift? Is there something similar to a .env file I can use?

CodePudding user response:

Some recommend creating a config file (.xcconfig) for every environment and then you can set up your different base URL there.

Where I used to work, we used a constants file where we set up different values, urls,ports and so on depending on the environment like this:

#if DEBUG
let a = 2

#if PRODUCTION
let a = 4

I think this is the best thing to do.

CodePudding user response:

What I always do is probably a more flexible approach than checking constants in your code and littering different values of the same variable per environment everywhere.

It is not necessary to create .xcconfig files either.

Setting up the whole thing is a little more work but you will see that it is very easy to use afterwards.

In my example you see how I set different REST endpoints for production/UITest/development builds in my Info.plist Make sure to set its value to the name you chose, enclosed in $() (brackets, not braces!), in my case it's $(TS_WEBSERVICE_URL).

Build settings

In your build settings tab, add custom "user defined" build parameters, again with the same name:

build settings

You see that you can define values for Debug, UITests and Release. And that I use this mechanism for a whole lot of things that are different in the environments.

Adding more environments

If you need more environments, add them on your master project node's Info tab (like I probably did here with UITests): Add environments

Use the values in code

Now for the easy part: use your newly defined values in your code. It all boils down to getting an NSBundle instance and reading the value defined in your Info.plist which has been substituted automatically during build process.

Objective C:

NSString *webserviceURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"TS_WEBSERVICE_URL"];

Swift:

let webserviceURL = Bundle.main.object(forInfoDictionaryKey: "TS_WEBSERVICE_URL") as! String

Just one line of code per environment setting.

One thing I have not shown, but which is also fairly easy: just define a category to NSBundle and supply new methods called webserviceUrl and similar methods. They can then be called like this: Bundle.main.webserviceUrl() which even more simplifies the source code.

  • Related