Reputation: 4199
Suppose that you need to have a series of complex configuration for a series of different Objects. This configuration can be NSString like service's server address, NSNumber like timeout time and so on. I want to impose the following constraint:
My question is: what's the best way to achieve this? Have you ever faced a problem like this? how did you solve it?
Upvotes: 1
Views: 736
Reputation: 3092
Require that for the first time use, an internet connection is present and download via HTTPS your config and keep it in memory (encrypted if you want).
Then take advantage of the keychain in iOS, and store your config as a string there (essentially serialize it).
NSString *serializedConfig = ...;
[keychain setObject:serializedConfig forKey@"MyConfig"];
On subsequent use, retrieve the config stored in the keychain:
NSString *serializedConfig = [keychain objectForKey:@"MyConfig"];
You can find the keychain wrapper and documentation on the Apple Docs site.
Upvotes: 0
Reputation: 19641
Take advantage of Xcode build system. You can have Xcode configuration files for any build configuration (Debug, Release, etc) and target combination.
These files support inheritance to simplify sharing configuration. There is no a single way to define the options. A simple one is to use GCC_PREPROCESSOR_DEFINITIONS
or CFLAGS
or whatever your compiler will take.
TargetX.xcconfig
:
GCC_PREPROCESSOR_DEFINITIONS = STAGE=2 SERVER_URL='www.wuonm.com'
With configured values is fairly trivial to build the required NSString
or NSNumber
objects. Tip: you will require some kind of stringification.
It's quite similar to using #define
but IMHO it's much cleaner and structured if you invest some time understanding how xcconfig
files work.
Upvotes: 2
Reputation: 454
Your static library should provide some interface to set current configuration that will be set in runtime.
SetCurrentConfiguration(Configuration config);
Then "client" can configure it with needed configuration in runtime. Second step is load configuration from specified source, let's say xml file and inject it to static library via method above.
If you don't want users to modify configuration files you can use some sort of encryption and then decrypt on the fly.
Upvotes: 0
Reputation: 318
I faced this same issue with server URLs used in different classes and constant numbers like colors, sizes and pretty much any configuration needed to be easily changed. The best solution I found was creating a header file like Constants.h, the content of this header file was:
#define MAX_DIST 1000
#define MIN_DIST 300
#define ANIMATION_DURATION 0.010
#define PIXEL_MOVES 7
#define SENSITIVITY 14
#define VIEW_ANGLE 30 //Range of vision divided by 2
#define RAD_POS_X 415
#define RAD_POS_Y 15
#define BUTTON_VIEW_WIDTH PIXEL_MOVES*360
#define SCREEN_HEIGHT 480
#define BUTTON_WIDTH_CLOSE 180
#define BUTTON_HEIGHT_CLOSE 100
#define BUTTON_WIDTH_MEDIUM 100
#define BUTTON_HEIGHT_MEDIUM 60
#define BUTTON_WIDTH_FAR 60
#define BUTTON_HEIGHT_FAR 40
#define BUTTON_Y_POSITION_CLOSE 200
#define BUTTON_Y_POSITION_MEDIUM 135
#define BUTTON_Y_POSITION_FAR 90
#define SERVICE_URL @"http://my.server.com/SoapServer/SoapServiceWS"//
you can even define common functions like
#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
This way i have been able to configure every aspect of my app from one single file and you can use #ifdef like you said to manage different compilations. Of course, you must import the file Constants.h in any class that will need to access any of these constants.
Upvotes: 0
Reputation: 7085
There are many questions that arise with this post:
Upvotes: 0
Reputation: 2396
If these values are constant for each build configuration, why not put them in your code as constants? I don't really see why you need to externalize these settings if they are constants that vary by config. Your ifdef selection of the settings would be just as effective (and faster) with these constants declared in a private header.
If these settings somehow change during the running of the app (not from build to build but within the confines of running a single build of the app) then externalizing these settings would be appropriate.
Upvotes: 0