11

Possible Duplicate:
Constants in Objective C

I store some app settings in NSUserDefaults. NSStrings are used as keys. The problem is I need to access these settings throughout the app using those NSString keys. There is a chance that I mistype such string key when accessing in some part of the app.

Throughout the app, I have such statements

[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"ReminderSwitch"];

BOOL shouldRemind = [[NSUserDefaults standardUserDefaults] boolForKey:@"ReminderSwitch"];

How and where can I declare a global NSString constant which I can access throughout the app. I will then be able to use that constant without worrying about mistyping those string keys.

Community
  • 1
  • 1
Anand
  • 9,892
  • 24
  • 86
  • 132

4 Answers4

13

First, you should go for a real extern C symbol -- not a macro. this is done like so:

SomeFile.h

extern NSString *const MONConstantString;

SomeFile.m

NSString *const MONConstantString = @"MONConstantString";

note that if you use a mix of ObjC and ObjC++, you will need to specify extern "C" for C++ TUs -- that's why you will see a #defined export which varies by language.


Then, you will want to put the constant near the interfaces it relates to. Taking your example as a lead, you might want a set of interfaces or declarations for your app's preferences. In that case, you might add the declaration to MONAppsPreferences header:

MONAppsPreferences.h

extern NSString *const MONApps_Pref_ReminderSwitch;

MONAppsPreferences.m

NSString *const MONApps_Pref_ReminderSwitch = @"MONApps_Pref_ReminderSwitch";

In use:

#import "MONAppsPreferences.h"
...
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:MONApps_Pref_ReminderSwitch];
Alex Zavatone
  • 3,522
  • 32
  • 49
justin
  • 101,751
  • 13
  • 172
  • 222
9

Your thought is right I think. For example, I made Const.h/m file like below:

Const.h

extern NSString *const UserIdPrefKey;
extern NSString *const PasswordPrefKey;
extern NSString *const HomepagePrefKey;

Const.m

#import "AEConst.h"

NSString *const UserIdPrefKey = @"UserIdPrefKey";
NSString *const PasswordPrefKey = @"PasswordPrefKey";
NSString *const HomepagePrefKey = @"UrlHomepagePrefKey";

Only Const.h must be imported.

When you write code, Xcode supports writing the key name so that you can avoid miss-typing.

Alex Zavatone
  • 3,522
  • 32
  • 49
Feel Physics
  • 2,773
  • 4
  • 22
  • 36
5

What you seem to be looking for is just a way to define string constants in your app.

See this question and this answer to it, which I've quoted below:

You should create a header file like

// Constants.h 
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

You can include this file in each file that uses the constants or in the pre-compiled header > for the project.

You define these constants in a .m file like

// Constants.m 
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant"; 

Constants.m should be added to your application/framework's target so that it is linked in to the final product.

The advantage of using string constants instead of #define'd constants is that you can test for equality using pointer comparison (stringInstance == MyFirstConstant) which is much faster than string comparison ([stringInstance isEqualToString:MyFirstConstant]) (and easier to read, IMO).

With thanks to Barry Wark :)

Community
  • 1
  • 1
Erik S
  • 1,931
  • 1
  • 17
  • 43
  • he just wants the constants in the app (internal linkage) so I'm wondering why you are suggesting he export them(external linkage)? – malhal Jul 31 '16 at 22:36
4

The easiest way to do this is make simple .h file, like Utils.h and write there following code:

#define kUserDefaults @"ReminderSwitch"

Artem Kalachev
  • 972
  • 1
  • 7
  • 19
  • 3
    yeah, not so safe, there is a chance for some other objective c file to override that without getting noticed :( – thndrkiss Feb 25 '15 at 23:16