15

I created Objective C Header file. and added some properties in it.
i declared
static NSString* const kColor005C98 = @"005C98"; in Constants.h file

I defined this file in Bridging-Header file as #import "Constants.h" Now when i want to use this property kColor005C98 in some swift file it failed the build and i am getting

Undefined symbols for architecture armv7: "_kColor005C98", referenced from:

i don't know what else i need to do so i don't get this error? (i have used this property in other objective C file successfully and no issue in that case)

jww
  • 83,594
  • 69
  • 338
  • 732
waseemwk
  • 1,460
  • 3
  • 15
  • 44

1 Answers1

20

Update:

As of Swift 2/Xcode 7 and later, a static constant definition like

static NSString* const kColor005C98 = @"005C98"; // in Constants.h file

is imported to Swift and can be used without problems.


(Old answer for Swift 1.x) When the code

static NSString* const kColor005C98 = @"005C98"; // in Constants.h file

is processed by an Objective-C compiler, it is treated as two things combined into one statement:

  • A variable declaration which introduces an identifier and describes its type, and
  • a variable definition which actually instantiates/implements this identifier.

See for example What is the difference between a definition and a declaration? for a good explanation of the difference between declaration and definition.

The Swift compiler treats the statement only as a declaration. Therefore the variable is not defined anywhere, causing the linker error.

To solve the problem, you have to move the definition to an Objective-C file:

// Constants.m:
#import "Constants.h"
NSString * const kColor005C98  = @"005C98";

and change the declaration to an extern declaration:

// Constants.h:
extern NSString * const kColor005C98;

Alternatively, you can just remove the static modifier:

 NSString * const kColor005C98 = @"005C98";

to make it work with Swift. The disadvantage is that when this line is included by multiple Objective-C files, all of them will define a globally visible symbol kColor005C98, causing "duplicate symbol" linker errors.

Another alternative is to use a macro definition instead:

#define kColor005C98 @"005C98"
Martin R
  • 488,667
  • 78
  • 1,132
  • 1,248
  • Thanks for ur reply. I tried this but now i am getting "Expression is not an integer constant expression in iOS" error in Switch statement if i use NSInteger constant. – waseemwk Feb 18 '15 at 09:50
  • @WaseemKhan: I am sure that this works with integer constants as well, and it is difficult to help without seeing the actual code. – Martin R Feb 18 '15 at 09:59
  • 1
    i declared like this `extern NSInteger const someIntegerConstant;` in `Constants.h` file and defined as `NSInteger const someIntegerConstant = 1;` in 'Constants.m' file Now i am using it in switch statement like this `switch (someConditiom){ case someIntegerConstant: // some code here }` and getting "Expression is not an integer constant expression" Error – waseemwk Feb 18 '15 at 10:12
  • @WaseemKhan: Strange. That exact code compiles without problems in my test app. – Martin R Feb 18 '15 at 10:23
  • @WaseemKhan: Do you get the error message in an *Objective-C* file? In (Objective-C), the switch cases cannot be used with variables. – Martin R Feb 18 '15 at 11:56
  • Yep. getting that msg in Objective C. – waseemwk Feb 19 '15 at 05:53
  • but i was using the same in objective C when i declared it like `static NSInteger const someIntegerConstant = 1;` now with ur solution i removed the `static` keyword and changed to `extern` and provided declaration and implementation seperately. then i started getting above `Expression is not an integer constant expression` problem – waseemwk Feb 19 '15 at 05:55
  • @WaseemKhan: I see. What you can do is: Declare two variables `static NSInteger const someIntegerConstant = 1;` and `extern NSInteger const swiftIntegerConstant;` in Constants.h, and define `NSInteger const swiftIntegerConstant = someIntegerConstant;` in Constants.m. Then you can use `someIntegerConstant` as a real constant in Objective-C files, and you can use `someIntegerConstant` in Swift files. – Sorry, I could not find a nicer solution. – Martin R Feb 19 '15 at 08:07
  • i will have to find some other nice solution because i have too many such variables in my `constants.h` file. i can't duplicate them all :( – waseemwk Feb 19 '15 at 09:45
  • This really helped me out after a long, long search on a partially related problem. The C library I was trying to bridge had a bunch of static declarations. Tried to figure out how to bridge them, ultimately just removed the statics based on this post. Thanks! – atonyc Feb 09 '17 at 04:53
  • @WaseemKhan: Things have simplified with newer Swift/Xcode versions ... – Martin R Oct 31 '17 at 08:22