简体   繁体   中英

Simple way to combine #define with key in [NSBundle mainBundle]

In my iOS application I have two targets with their own .plist file: Production and Test .

My app uses a bunch of different URLs which are either on the production or the test server. Hence, I have added a new key to my two plists like so:

<!-- MyAppTest-Info.plist -->
...
<key>MAServerURL</key>
<string>http://test.myap.com</string>
...

<!-- MyApp-Info.plist -->
...
<key>MAServerURL</key>
<string>http://myapp.com</string>
...

So now in my Const.h instead of defining the specific urls #define IMAGEURL @"http://myapp.com/images/" and changing them when I want to switch the environment

I now can do this:

// Const.h
#define SERVER_URL [[[NSBundle mainBundle] infoDictionary] objectForKey:@"MAServerURL"];

#define IMAGE_URL [NSString stringWithFormat:@"%@/images", SERVER_URL];
#define AUDIO_URL [NSString stringWithFormat:@"%@/audio", SERVER_URL];
#define FEEDBACK_URL [NSString stringWithFormat:@"%@/mail/feedback", SERVER_URL];
....

Theoretically this would work but for every access of the constant the bundle is accessed and syntactically it is also not really a beauty (due to the verbose concatenation in OBJ-C).

Any ideas and suggestions are very welcome.

extern is your friend... Try to learn about it.

Basically, you declare a global variable in your header file, using the extern modifier, basically meaning it's value will be defined later, in another source file.

So you can have:

const.h

extern NSString * kAudioURL;

This just declares the variable, as a NSString object. All files including your const.h file will be able to see this variable, even if it's not actually defined.

Then, you'll defined the variable in another (implementation) file.

const.m

NSString * kAudioURL = @"foo";

This way, the definition will be hidden, as it happens in an implementation file, but other files will have access to your variable, by including the header file.

So you'll be able to assign the correct value once.

Of course, in your example, you are using computed values. As the kAudioURL is global, you won't be able to write:

NSString * kAudioURL = [ NSString stringWithFormat: @"%@/images", SERVER_URL ];

But you may set the initial value to nil, and use an initialization function, maybe called from your application's delegate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM