So, this current app we’re working on has a Server-Client architecture. The server is being developed in parallel to the client. It breaks a lot. 🙂
There are however different states of the server, and we also release test versions to our testers. Client apps of course talk to the server with its own specific code revision. Developers try to develop against the “bleeding edge”.
It should be therefore possible to specify which server you are communicating with. We call this the environment. I recently synthesized a solution based on a few posts out there on the internet and thought I’d quickly share it. If for nobody else, then myself. 😀
This one sentence from NSHipster:
Any argument passed on launch will override the current value in
NSUserDefaultsfor the duration of execution.
Got me thinking. Well why don’t I just use
NSUserDefaults to set up environment variables? Then I thought “even better would be if I could just edit a .plist, so someone else doesn’t even need to dig into my code. Which brought me to this gem of a snippet, from arguably one of the Objective-C gods, Mr. Ole Begemann:
NSString *defaultPrefsFile = [[NSBundle mainBundle] pathForResource:@"defaultPrefs" ofType:@"plist"]; NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfFile:defaultPrefsFile]; [[NSUserDefaults standardUserDefaults] registerDefaults:defaultPreferences];
Or you can find the original answer at StackOverflow here.
So, armed with this knowledge, I use a .plist to set default “production” values, then register those defaults, expose the key names for those defaults in case a consumer of my code needs to override them, and of course, knowing that I can use Launch Arguments as well, I just duplicate my Xcode run scheme, and add my own environment variables, and name that scheme something like “development”, or “staging”, or whatever.