Overriding NSUserDefault preferences at build time
I would like to be able to set app preferences at build time in my iOS project. I know that I can create different targets in xcode, but I think that with the number of preferences I could end up with, I might end up with a nightmarish number of targets in my project.
A simple example is setting a default integer value for the default "amount". Currently, the "sum" is defined in a plist file in my application called "preferences.plist". I download this plist file and register the defaults with this plist on NSUserDefaults.
NSURL *preferencesFile = [[NSBundle mainBundle] URLForResource:@"preferences" withExtension:@"plist"];
NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfURL:defaultPreferencesFile];
[[NSUserDefaults standardUserDefaults] registerDefaults:preferences];
My guess is that I could write a script to modify the preferences.plist file before I build it and then create it. However, I think it can become a nightmare when I need to create a bunch of different preferences.
The end game is for jenkins to build my IPAs. I would like to easily create multiple jenkins builds that will point to the same code, but create my application with different settings.
Android has flavors and the ability to set resource values. Does iOS have something like this that I can use to create these different "flavors" of apps?
source to share
I am using Jenkins build action to inject the appropriate variables into plist before Xcode build:
plutil -replace MyBuildBranch -string ${BRANCH} MyProj/MyProj-Info.plist
Then I read this value at runtime using something like:
NSBundle * bundle = [NSBundle bundleForClass:[AppDelegate class]];
NSString * myBuildBranch = bundle.infoDictionary[@"MyBuildBranch"]
source to share
I am lacking experience with Android.
I would approach this with multiple plates. One for each scent.
And I will try any of the following options -
-
I would have Jenkins replace the plist based on the flavor I'm trying to build. the script will select the correct layer for the given flavor
-
I define compile-time MACROS for each flavor and load the corresponding plist .. something like this
#ifdef FLAVOUR1 NSURL *preferencesFile = [[NSBundle mainBundle] URLForResource:@"preferences-flavour1" withExtension:@"plist"]; NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfURL:defaultPreferencesFile]; [[NSUserDefaults standardUserDefaults] registerDefaults:preferences]; #endif #ifdef FLAVOUR2 NSURL *preferencesFile = [[NSBundle mainBundle] URLForResource:@"preferences-flavour2" withExtension:@"plist"]; NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfURL:defaultPreferencesFile]; [[NSUserDefaults standardUserDefaults] registerDefaults:preferences]; #endif #ifdef FLAVOUR2 NSURL *preferencesFile = [[NSBundle mainBundle] URLForResource:@"preferences-flavour3" withExtension:@"plist"]; NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfURL:defaultPreferencesFile]; [[NSUserDefaults standardUserDefaults] registerDefaults:preferences]; #endif
source to share