Not allowing to use Constant defined in Objective C header file in swift class. Undefined symbols for architecture armv7
Asked Answered
W

1

16

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)

Weakminded answered 18/2, 2015 at 6:12 Comment(0)
I
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"
Icsh answered 18/2, 2015 at 8:9 Comment(11)
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.Weakminded
@WaseemKhan: I am sure that this works with integer constants as well, and it is difficult to help without seeing the actual code.Icsh
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" ErrorWeakminded
@WaseemKhan: Strange. That exact code compiles without problems in my test app.Icsh
@WaseemKhan: Do you get the error message in an Objective-C file? In (Objective-C), the switch cases cannot be used with variables.Icsh
Yep. getting that msg in Objective C.Weakminded
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 problemWeakminded
@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.Icsh
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 :(Weakminded
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!Gymnosperm
@WaseemKhan: Things have simplified with newer Swift/Xcode versions ...Icsh

© 2022 - 2024 — McMap. All rights reserved.