duplicate symbol error in two 3rd libs, with same const definition - ios

The two libs are AFNetworking and libcomScore.a.
In AFHttpClient.h, extern NSString * const AFNetworkingReachabilityDidChangeNotification;
In AFHttpClient.m, NSString * const AFNetworkingReachabilityDidChangeNotification = #"***";
Somehow in some class in the comScore static lib, AFNetworkingReachabilityDidChangeNotification is redefined, causing error
duplicate symbol _AFNetworkingReachabilityDidChangeNotification in:
comScore-iOS-ARMV7_ARMV7S_ARM64-2.1403.14/comScore-iOS-ARMV7_ARMV7S_ARM64-2.1403.14/comScore/libcomScore.a(CSReachabilityManager.o)
/Users/apple/lib***.a(AFHTTPClient.o)
I don't want to touch the code in AFNetworking(although I can easily fix it by rename the const.)
So does anybody have any idea ?

Check importation of file you might be importing .m file instead of .h file such like
#import "myClassName.m"

Related

Header file issue with xcode 7

I have a subclass of NSObject, but I have a problem with header file, when I run the project, it shows me this:
and it allows me to add this, but directly this logical error is returned: "#end must appear in Objective-C context"
I precise that with Xcode6 I didn't have that issue with this Does anyone knows how to fix this frustrating issue ?
EDIT:
that's a constants file, do not pay attention to the file's name, here is .m file:
#import "CUSBoxes.h"
const int defaultCount = 10;
const long int repeat = 25000;
const NSString *defaultDescription = #"If any layout issue is related, change default values of each box you want to display";
#implementation CUSBoxes
#end
Usually this error causes you missed #end or invalid character in one of the .h file you used in your project. I have came across with this error, this error not exist in same files it throws check for other header files to fix this issue.
1) You might missing #end in any of the Header file.Check one by one all .h file which has #interface section,should be ended with "#end".
2) If everything looks good then Try cleaning project or Restart Xcode.(In my case,It worked).

Linker error when referencing static NSString const in Swift [duplicate]

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)
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"

xCode: Objective C: duplicate symbol error

In file CarArray (without any extension) I have the array like that (this is a very simplified version):
NSString *cars[5][3] = {
{#"1A", #"1B", #"1C"},
{#"2A", #"2B", #"2C"},
{#"3A", #"3B", #"3C"},
{#"4A", #"4B", #"4C"},
{#"5A", #"5B", #"5C"}
}
Now I want to read the data from the array in multiple files so I simply use #import "CarArray"
And I use a loop to read the data. Then I get such an error:
duplicate symbol _cars in:
/Users/Adam/Library/Developer/Xcode/DerivedData/Auto_Center-hgjlsqanvyynncgyfzuorxwchqov/Build/Intermediates/Auto Center.build/Debug-iphonesimulator/Auto Center.build/Objects-normal/i386/DetailViewController.o
/Users/Adam/Library/Developer/Xcode/DerivedData/Auto_Center-hgjlsqanvyynncgyfzuorxwchqov/Build/Intermediates/Auto Center.build/Debug-iphonesimulator/Auto Center.build/Objects-normal/i386/ModelListViewController.o
ld: 1 duplicate symbol for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How can I solve that problem?
Now I want to read the data from the array in multiple files so I simply use #import "CarArray"
This is an incorrect way of accessing array data from multiple places, because it creates multiple definitions in situations when you use the file more than once.
One way of sharing an array would be providing a header with a declaration, and a .m file with an implementation:
CarArray.h:
extern NSString *cars[5][3];
CarArray.m:
#import "CarArray.h"
NSString *cars[5][3] = {
{#"1A", #"1B", #"1C"},
{#"2A", #"2B", #"2C"},
{#"3A", #"3B", #"3C"},
{#"4A", #"4B", #"4C"},
{#"5A", #"5B", #"5C"}
}
Use #import "CarArray.h" in files from which you wish to use cars.
Another alternative would be making a class to wrap your global variable, and providing a class method for accessing the array.
You should declare your array in a header file ("CarArray.h") but define and initialize it with values in a separate implementation file ("CarArray.m").

Static const definitions in .h vs external const in .m

I've find it frustrating to define constants in the .h as externals and then assign the constants in the .m file. Seems so redundant. Is there any reason not to just define the constants in the header file?
Typical implementation would be:
// Constants.h
#interface Constants : NSObject
extern NSString *const kPCFavorites;
#end
The implementation would then be:
// Constants.m
#implementation Constants
NSString *const kPCFavorites = #"PCFavorites";
#end
However, I can just do this:
// Constants.h
static NSString *const kPCFavorites = #"PCFavorites";
#interface Constants : NSObject
#end
Obviously, this last definition doesn't even need an interface or implementation so both could be left out and become:
// Constants.h
static NSString *const kPCFavorites = #"PCFavorites";
with no .m file at all.
This seems much cleaner to me. Why wouldn't we implement constants this way? I've defined them both ways and I get no compile or runtime errors in XCode 5.
Because
static NSString * const kPCFavorites = #"PCFavorites";
declares a variable, not a constant. C doesn’t actually have a way to declare a symbolic constant (besides enum, which only works for integers).
As a result, if you use this method, every file that #includes your header will have its own variable called kPCFavorites. Historically, that would have meant that your program would increase in size because of all of the copies of kPCFavourites and the string #"PCFavourites", although more modern linkers may manage to get rid of some or all of the duplication (certainly I’d expect the linker to leave you with only one copy of the string itself; whether or not it can currently get rid of the extra pointer variables I’m not sure — but it’s easy to test).
static variables have file scope. If you compile a file which includes a header file with a static variable, that variable will exist in the compiled file. If you compile another file with the same header file, you have a second static variable and so on. If you include the header from 1000 source files, you get 1000 static variables, all with the same name.

Global variables in my Constants file

Until now if I needed access to a global variable across my app i just added
#define PATH [NSString stringWithFormat:#"www.url.com"]
To my Constants.h file.
I need to fetch the PATH value from my server.
How can i assign the value I'm getting from a server to a macro \string like the above and still be able to use just the variable PATH anywhere in my app? (Without naming the class like a property use such as class.PATH
This works:
#import <Foundation/Foundation.h>
NSString* PATH;
#interface Constants : NSObject
+(void)getPathFromServer;
#end
And PATH is accessible from anywhere in my app but I'm not sure if that should be the way to go.
As I understand so far, you need to define a macro which dynamic change it's url content.
If I'm right , you may need a Vararg Macros which takes a variable.
#define PATH(...) [NSString stringWithFormat:#"%#",__VA_ARGS__]
You can use extern keyword
Example :
//Header file
extern NSString * const path;
// .m file under implementation
NSString * const Ppath = [NSString stringWithFormat:#"www.url.com"];
Have a look at these
Constants in Objective C
#define vs const in Objective-C

Resources