1

I read through the advice here Constants in Objective-C, but I find two errors in the accepted answer:

  1. I keep getting linker errors when I implement the approach of using .m and .h
  2. In my constants.m file, I get the error "unknown type" for NSString

    I am also getting an error following the advice from @VictorHanHee as a further suggestion of how to link the constants to a .pch file:

  3. I don't have a .pch file by default, and when I create a new one it doesn't have the formatting expected from the answer.

All I have done is create constants.h and constants.m and put the constant declarations in them as provided in the accepted answer. I also created a .pch file, but as I said it doesn't at all match VictorHanHee's description.

Is this older posting outdated, or if not what am I missing? I don't really know how to go forward with a linker error. I simply want to have a file constants.h where I declare all constants and can include this file in as many classes as I want to make life easier. Can someone tell me how to do this nowadays or point to a more recent discussion?

Also here is the linker error (or part of log I can copy and paste anyway, not full message)

    -[AccountInfoViewController viewDidLoad] in AccountInfoViewController.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

As you can see, I am trying to access the constant from viewDidLoad. I am simply trying to print it out with NSLog.

Here are the .h and .m files I was originally using:

.h

extern NSString * const PREFS_MY_CONSTANT;

.m

NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

Ok here is the template that actually seems to work:

.h

#ifndef Project_prefs_h
#define Project_prefs_h


#endif


extern NSString * const PREFS_MY_CONSTANT;

.m

#import <Foundation/Foundation.h>
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

So the older post is perhaps misleading or I misunderstood them when they said remove everything apart from the constants - but if you don't actually want to remove everything, shouldn't you say so? That's a fair amount of text in there not to mention...

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
sunny
  • 3,853
  • 5
  • 32
  • 62
  • 2
    "I get the error "unknown type" for NSString" That sounds like you're forgetting to import Foundation framework. – matt Apr 20 '15 at 15:21
  • 2
    Can we see your .h and .m? Do they inherit from NSObject? Are you declaring them before the interface and implementation? etc etc. – Dare Apr 20 '15 at 15:23
  • @matt In the original post it says not to include anything other than the text declaring the constants. That is why I did not import Foundation framework. – sunny Apr 20 '15 at 15:36
  • @Dare They don't inherit from anything - should they? I'm simply following directions from original post that says const declarations should be the only text in the file. I figured that meant not importing Foundation framework for example. – sunny Apr 20 '15 at 15:36
  • The class they're in certainly inherits from something – Dare Apr 20 '15 at 15:37
  • @Dare do you know of a full example showing exactly what they should look like? As I said, I followed instructions from referenced post word-for-word, and those instructions said nothing else in the file. I'm looking for a full and exact template of what should go in each of these files. – sunny Apr 20 '15 at 15:39
  • Voting to close this question because the OP refuses to show the actual code. – matt Apr 20 '15 at 15:40

2 Answers2

1

In recent version of Xcode there is no ProjectName-Prefix.pch created automatically file so you should import the file where it is required then try using the constant.

Easiest way:

// Prefs.h
#import <Foundation/Foundation.h>

#define PREFS_MY_CONSTANT @"prefs_my_constant"

Better way:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

There are a few different ways to create constants in Objective-C, but the easiest way is to use #define statements.

To start, create a new header file. This is where we’ll store all the constants. Name it something original like “Constants.h”.

Here’s a sample file with a few constants:

//
//  Constants.h
//  App Name


#import <Foundation/Foundation.h>

#define NUM_SECTIONS        7

#define NUM_SECTION_1_ITEMS 2
#define NUM_SECTION_2_ITEMS 14
#define NUM_SECTION_3_ITEMS 5

#define APP_TITLE           @"App Name"
#define APP_AUTHOR          @"Miscellanea"

To use these constants in your project, you need to import your header file in each implementation file (*.m) where you’ll be referencing them.

#import "Constants.h"
– (void)viewDidLoad
{
    self.title = APP_TITLE;

    for (int i = 0; i < NUM_SECTIONS; ++ i)
    {
        // etc.
    }
}
NobodyNada
  • 7,529
  • 6
  • 44
  • 51
Nischal Hada
  • 3,230
  • 3
  • 27
  • 57
  • Thanks for your advice, but I had tried this without the .pch and it still doesn't work. I have prefs.h and prefs.m exactly as you have specified (no code besides what you have in your answer). When I try to build, I get a Parse Issue in prefs.m: "Unknown type name 'NSString' – sunny Apr 20 '15 at 15:26
  • // Prefs.h #define PREFS_MY_CONSTANT @"prefs_my_constant" use this method – Nischal Hada Apr 20 '15 at 15:27
  • thanks again, but this gives me the linker error I mentioned in my earlier message: Undefined symbols for architecture armv7: "_PREFS_MY_CONSTANT", referenced from: -[AccountInfoViewController viewDidLoad] in AccountInfoViewController.o ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) – sunny Apr 20 '15 at 15:33
  • Just create only header file. Do you know how to do that – Nischal Hada Apr 20 '15 at 15:37
  • Pop an `@import Foundation;` at the top of your `prefs.h` to fix the **Unknown type** error – Ashley Mills Apr 20 '15 at 15:37
  • @nischalhada Yes I did try creating only a header file - that gives me the linker error I just pasted in my comment and in my original file. – sunny Apr 20 '15 at 15:41
  • Create a constant with name Constants.h then dont forget to import #import as shown in above example – Nischal Hada Apr 20 '15 at 15:43
  • @nischalhada what worked is the following for .h #ifndef Loq_ly_prefs_h #define Loq_ly_prefs_h #endif extern NSString * const PREFS_MY_CONSTANT; and the following for .m #import NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant"; – sunny Apr 20 '15 at 15:45
  • @AshleyMills yes you were right about this. Perhaps it just goes without saying in the original post, but that's not how I understood their comment to delete everything apart from the constant declarations. Thank you! – sunny Apr 20 '15 at 15:52
-1

Here is the template that does seem to work. It's not different from the old answer except that you don't delete everything apart from the constants.

.h

#ifndef Project_prefs_h
#define Project_prefs_h  
#endif
extern NSString * const PREFS_MY_CONSTANT;

.m

#import <Foundation/Foundation.h>
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

Apart from this it appears no longer possible to use .pch file to automatically include the constants across all classes.

sunny
  • 3,853
  • 5
  • 32
  • 62