Простой способ объединить #define с ключом в [NSBundle mainBundle] - PullRequest
1 голос
/ 23 сентября 2011

В моем приложении для iOS у меня есть две цели с собственным файлом .plist: Production и Test .

Мое приложение использует несколько разных URL-адресов, которые находятся на рабочем или тестовом сервере. Следовательно, я добавил новый ключ к моим двум спискам, например:

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

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

Так что теперь в моем Const.h вместо определения конкретных URL #define IMAGEURL @"http://myapp.com/images/" и их изменения, когда я хочу переключить среду

Теперь я могу сделать это:

// 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];
....

Теоретически это будет работать, но для каждого доступа к константе осуществляется доступ к пакету, и синтаксически это также не очень красиво (из-за многословной конкатенации в OBJ-C).

Любые идеи и предложения приветствуются.

1 Ответ

5 голосов
/ 24 сентября 2011

extern ваш друг ... Постарайтесь узнать об этом.

По сути, вы объявляете глобальную переменную в своем заголовочном файле, используя модификатор extern, в основном это означает, что ее значение будет определено позже в другом исходном файле.

Так что вы можете иметь:

const.h

extern NSString * kAudioURL;

Это просто объявляет переменную как объект NSString. Все файлы, включая ваш const.h, смогут видеть эту переменную, даже если она на самом деле не определена.

Затем вы определили переменную в другом файле (реализации).

const.m

NSString * kAudioURL = @"foo";

Таким образом, определение будет скрыто, как это происходит в файле реализации, но другие файлы будут иметь доступ к вашей переменной, включая файл заголовка.

Таким образом, вы сможете назначить правильное значение один раз.

Конечно, в вашем примере вы используете вычисленные значения. Поскольку kAudioURL является глобальным, вы не сможете написать:

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

Но вы можете установить начальное значение равным nil и использовать функцию инициализации, которая может быть вызвана из делегата вашего приложения.

...