Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where's the best place to store constants in an iOS app?

I'm developing an app just now that fetches resources from a JSON API.

all of the resources have the same base URL:

http://api.mysite.com/resources.json http://api.mysite.com/other_resources.json 

I want to store the http://api.mysite.com/ string so it's available to all of my Controllers and Models, removing some duplication when writing the resource URLs.

Where's the best place to do this? The -prefix.pch file?

Any advice appreciated

like image 702
bodacious Avatar asked Feb 12 '12 17:02

bodacious


2 Answers

I agree with Alex Coplan's answer with an important addition.

Put all your constants in a file named "Constants.h" (or w/e you want)

EDIT:

  • When I answered this question three years ago, I was on the #define bandwagon, check below for a revision.

Constants.h

#define kFilterDate @"date" #define kFilterRadius @"radius" #define kFilterSort @"sort"  //Global Strings #define kDividingString @" / "  //Strings #define kTour @"Tour" #define kToursKey @"tours" 

But instead of importing it in any file you need it, import it in your prefix file so that all of your headers import it automatically throughout your project.

Project_Prefix.pch

// // Prefix header for all source files of the project //  #ifdef __OBJC__     #import <Foundation/Foundation.h>     #import <UIKit/UIKit.h>     #import "Constants.h" #endif 

REVISION

All though all the previous information will still work, there are some things we can do to be a little bit more safe about our constants.

Create your constants in your Constants.h file using const variables

//Filters FOUNDATION_EXPORT NSString *const kFilterDate; FOUNDATION_EXPORT NSString *const kFilterRadius; FOUNDATION_EXPORT NSString *const kFilterSort;  //Global Strings FOUNDATION_EXPORT NSString *const kDividingString;  //Strings FOUNDATION_EXPORT NSString *const kTour; FOUNDATION_EXPORT NSString *const kToursKey; 

And in Constants.m

//Filters NSString *const kFilterDate = @"date"; NSString *const kFilterRadius = @"radius"; NSString *const kFilterSort = @"sort";  //Global Strings NSString *const kDividingString = @" / ";  //Strings NSString *const kTour = @"Tour"; NSString *const kToursKey = @"tours"; 

This can still be imported into your prefix file like above, but only use constants that are truly global in the file to do that. Ones that are used frequently in many places. Dumping all your constants into this file will cause your code that uses any constant to be coupled to the constants file. Thus, if you try to reuse the code, the constants file has to come with it. This isn't always necessarily bad, and many times is intended (which is fine), but limiting dependencies is always a good idea.

A few things about the revision:

  • FOUNDATION_EXPORT vs extern. The first one compiles different for C and C++. It basically means extern, but in C++ will add the "C" flag.
  • consts vs defines. consts are type safe and respect scope. defines are the exact opposite.
like image 96
ColdLogic Avatar answered Oct 01 '22 03:10

ColdLogic


Personally I prefer using actual const variables rather than defines.

In a MyConstants.m file I have:

NSString *const kXYMySiteBaseURL = @"http://api.mysite.com/"; NSString *const kXYSomeOtherURL = @"http://www.google.com/"; 

where XY is my initials or some other "unique" prefix to avoid collisions with other constants.

Then I have a MyConstants.h file like this:

extern NSString *const kXYMySitBaseURL; extern NSString *const kXYSomeOtherURL; 

Depending on how many files need to access these constants, I might include it in the precompiled header like ColdFusion suggests in his answer.

This is how Apple defines their constants in most of the Core frameworks.

like image 37
UIAdam Avatar answered Oct 01 '22 02:10

UIAdam