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?

+3


source to share


2 answers


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"]

      

+1


source


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
    
          

+1


source







All Articles