Где хранить глобальные константы в приложении для iOS? - PullRequest
109 голосов
/ 19 августа 2011

Большинство моделей в моем приложении для iOS запрашивают веб-сервер. Я хотел бы иметь файл конфигурации, хранящий базовый URL-адрес сервера. Это будет выглядеть примерно так:

// production
// static NSString* const baseUrl = "http://website.com/"

// testing
static NSString* const baseUrl = "http://192.168.0.123/"

Комментируя одну или другую строку, я могу мгновенно изменить сервер, на который указывают мои модели. У меня вопрос: как лучше хранить глобальные константы в iOS? В программировании на Android у нас есть встроенный файл ресурсов strings . В любой Activity (эквивалент UIViewController ) мы можем получить эти строковые константы с помощью:

String string = this.getString(R.string.someConstant);

Мне было интересно, есть ли в iOS SDK аналогичное место для хранения констант. Если нет, то как лучше всего это делать в Objective-C?

Ответы [ 11 ]

167 голосов
/ 13 августа 2012

Ну, вы хотите, чтобы объявление было локальным для интерфейсов, к которым оно относится - файл констант для всего приложения не очень хорошая вещь.

Кроме того, предпочтительно просто объявить символ extern NSString* const, а не использовать #define:


SomeFile.h

extern NSString* const MONAppsBaseUrl;

SomeFile.m

#import "SomeFile.h"

#ifdef DEBUG
NSString* const MONAppsBaseUrl = @"http://192.168.0.123/";
#else
NSString* const MONAppsBaseUrl = @"http://website.com/";
#endif

Помимо пропуска декларации Extern, совместимой с C ++, это то, что вы обычно будете видеть в каркасах Apple Obj-C.

Если константа должна быть видна только одному файлу или функции, тогда static NSString* const baseUrl в вашем *.m - это хорошо.

145 голосов
/ 19 августа 2011

Вы также можете сделать

#define kBaseURL @"http://192.168.0.123/"

в заголовочном файле "константы", скажем constants.h. Тогда сделай

#include "constants.h"

вверху каждого файла, где вам нужна эта константа.

Таким образом, вы можете переключаться между серверами в зависимости от флагов компилятора, например:

#ifdef DEBUG
    #define kBaseURL @"http://192.168.0.123/"
#else
    #define kBaseURL @"http://myproductionserver.com/"
#endif
39 голосов
/ 12 октября 2012

Способ определения глобальных констант:


AppConstants.h

extern NSString* const kAppBaseURL;

AppConstants.m

#import "AppConstants.h"

#ifdef DEBUG
NSString* const kAppBaseURL = @"http://192.168.0.123/";
#else
NSString* const kAppBaseURL = @"http://website.com/";
#endif

Затем в вашем файле {$ APP} -Prefix.pch:

#ifdef __OBJC__
  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import "AppConstants.h"
#endif

Если у вас возникли какие-либо проблемы, сначала убедитесь, что для опции Precompile Prefix Header задано значение NO.

5 голосов
/ 25 марта 2013

Вы также можете объединить строковые константы следующим образом:

  #define kBaseURL @"http://myServer.com"
  #define kFullURL kBaseURL @"/api/request"
3 голосов
/ 08 апреля 2016

Я думаю, что другой способ сделать это гораздо проще, и вы просто включите его в файлы, в которые они должны быть включены, а не во ВСЕ файлы, как в файле префикса .pch:

#ifndef Constants_h
#define Constants_h

//Some constants
static int const ZERO = 0;
static int const ONE = 1;
static int const TWO = 2;

#endif /* Constants_h */

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

#include "Constants.h"
3 голосов
/ 19 ноября 2014
  1. Я определяю глобальную константу в файле YOURPROJECT-Prefix.pch.
  2. #define BASEURl @"http://myWebService.appspot.com/xyz/xx"
  3. , затем в любом месте проекта используйте BASEURL:

    NSString *LOGIN_URL= [BASEURl stringByAppendingString:@"/users/login"];
    

Обновлено: в Xcode 6 вы не найдете файл .pch по умолчанию, созданный в вашем проекте.Поэтому, пожалуйста, используйте PCH файл в Xcode 6 , чтобы вставить файл .pch в ваш проект.

Обновления: для SWIFT

  1. Создать новый файл Swift [пустой без класса] сказать [AppGlobalMemebers]
  2. & Сразу же объявить / определить элемент

    Пример:

    var STATUS_BAR_GREEN : UIColor  = UIColor(red: 106/255.0, green: 161/255.0, blue: 7/255.0, alpha: 1)  //
    
  3. Если вы хотите определить глобальный член приложения в любом файле класса, скажем, Appdelegate или Singleton, или любом другом, объявите данный член выше определения класса
2 голосов
/ 20 мая 2013

Глобальные объявления интересны, но для меня то, что сильно изменило мой путь к коду, это наличие глобальных экземпляров классов. Мне потребовалось несколько дней, чтобы по-настоящему понять, как с этим работать, поэтому я быстро суммировал это здесь

Я использую глобальные экземпляры классов (1 или 2 на проект, если необходимо), чтобы перегруппировать доступ к основным данным или логику некоторых сделок.

Например, если вы хотите, чтобы центральный объект обрабатывал все таблицы ресторанов, вы создаете свой объект при запуске, и это все. Этот объект может обрабатывать доступ к базе данных ИЛИ обрабатывать его в памяти, если вам не нужно его сохранять. Он централизован, вы показываете только полезные интерфейсы ...!

Это отличная помощь, объектно-ориентированная и хороший способ собрать все свои вещи в одном месте

Несколько строк кода:

@interface RestaurantManager : NSObject
    +(id) sharedInstance;
    -(void)registerForTable:(NSNumber *)tableId;
@end 

и реализация объекта:

@implementation RestaurantManager

+ (id) sharedInstance {
    static dispatch_once_t onceQueue;

    dispatch_once(&onceQueue, ^{
        sharedInstance = [[self alloc] init];
        NSLog(@"*** Shared instance initialisation ***");
    });
    return sharedInstance;
}

-(void)registerForTable:(NSNumber *)tableId {
}
@end

использовать его очень просто:

[[RestaurantManager sharedInstance] registerForTable: [NsNumber numberWithInt: 10]]

0 голосов
/ 06 сентября 2016

Принятый ответ имеет 2 недостатка. Во-первых, как указывали другие, это использование #define, которое сложнее отладить, вместо этого используйте extern NSString* const kBaseUrl структуру. Во-вторых, он определяет один файл для констант. IMO, это неправильно, потому что большинству классов не нужен доступ к этим константам или доступ ко всем из них, плюс файл может стать раздутым, если все константы объявлены там. Лучшим решением будет модульная константа в 3 разных слоях:

  1. Системный уровень: SystemConstants.h или AppConstants.h, который описывает константы в глобальной области видимости, к которым может обращаться любой класс в системе. Объявите здесь только те константы, к которым нужно обращаться из разных классов, которые не связаны.

  2. Уровень модуля / подсистемы: ModuleNameConstants.h, описывает набор констант, типичных для набора связанных классов внутри модуля / подсистемы.

  3. Уровень класса: константы находятся в классе и используются только им.

Только 1,2 относятся к вопросу.

0 голосов
/ 17 февраля 2014

Я бы использовал объект конфигурации , который инициализируется из plist.Зачем беспокоиться о других классах с не относящимися к делу внешними вещами?

Я создал eppz!settigns Soley по этой причине.См. Статью Расширенный, но простой способ сохранения в NSUserDefaults для включения значений по умолчанию из plist.

enter image description here

0 голосов
/ 20 мая 2013

Для числа вы можете использовать его как

#define MAX_HEIGHT 12.5
...