xCode: Objective C: duplicate symbol error - ios

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

Related

Linker "Duplicate Symbol" error due to circular reference

I have two header of a class and it's extension(generated by Xcode for NSManaged object). But I'm getting a linker error and I figured out it was due to a circular reference.
Conversation+CoreDataClass.h
NS_ASSUME_NONNULL_BEGIN
#interface Conversation : NSManagedObject
#end
NS_ASSUME_NONNULL_END
#import "Conversation+CoreDataProperties.h"
Conversation+CoreDataProperties.h
#import "Conversation+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
NS_ASSUME_NONNULL_END
You can clearly see the circular reference here. I found this question where the problem was to add a #class declaration and remove the header. So I commented out the import statement in the Conversation+CoreDataProperties.h and added #class Conversation;. Now two errors pop up saying it's an undefined class. Have attached the screenshot of the error below. I don't quite understand why this is happening and what I need to do to fix it. Any help is much appreciated. Thanks!
Linker error
duplicate symbol _OBJC_CLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_CLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
ld: 4 duplicate symbols for architecture arm64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
So I commented out the import statement in the Conversation+CoreDataProperties.h and added #class Conversation;.
You may only do this if you're aren't using any of the Convention class's interface (for instance declaring a property of type Convention. You can't do this if you're extending Convention via a category or class extension.
You have a legit circular reference here you must resolve. You can either:
Move the class and the category into the same source file (if there's no special reason this needs to be in a category you could just move the declaration of fetchRequest into the class itself).
Stop importing +CoreDataProperties.h in the class header, and import it instead wherever callers need to be calling fetchRequest.
the duplicate symbols warning do result because
You have the class multiple times in your project and the compiler does not know, which to choose (then it is mostly a duplicate linking error)
There is something wrong with your ConversationDate+CoreDataClass
Just a question that raised from your source code: why do you import an extension of the class you want to extend?
#import "Conversation+CoreDataClass.h"
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
All the extension class usually needs to know are basically the classes they extend:
#import "Conversation.h"
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
Only the implementation file (.m) would have to import the header file. E.g:
#import "Conversation+CoreDataClass.h"
#implementation Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest {
// body
return nil;
}
#end
And last question: Are you sure there exists no other class extension with the same name in your project? CoreData might also have created them itself.
Please have a look in your xCode Project like this:
Found the solution to my problem in this answer. I just had to remove the .m files from the Compile Sources.

Duplicate symbol error with GoogleCast.framework

I just started porting an Android app to iOS, and am hitting a major roadblock that I can't figure out despite scouring many similar questions.
I am attempting to follow the pattern implemented in the CastVideos sample where the GoogleCast API is encapsulated in a singleton class which I've called CastManager. To use my singleton class, I #import "CastManager.h" in AppDelegate.m. Then in CastManager.h, I #import <GoogleCast/GoogleCast.h> so that I can use classes and protocols from it as part of CastManager's public interface. However, because I'm importing CastManager.h in both CastManager.m and AppDelegate.m, the linker is finding duplicate symbols from the GoogleCast framework.
This is my CastManager.h:
#import <GoogleCast/GoogleCast.h>
#import <Foundation/Foundation.h>
#interface CastManager : NSObject
#property(nonatomic, strong) GCKDeviceScanner *deviceScanner;
+ (instancetype)sharedCastManager;
#end
And corresponding CastManager.m:
#import "CastManager.h"
#implementation CastManager
+ (instancetype)sharedCastManager {
NSLog(#"sharedCastManager");
static CastManager *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[self alloc] init];
});
return singleton;
}
- (instancetype)init {
NSLog(#"init()");
if (self = [super init]) {
self.deviceScanner = [[GCKDeviceScanner alloc] init];
}
return self;
}
#end
And this is the main part of my AppDelegate.m:
#import "AppDelegate.h"
#import "CastManager.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CastManager *castManager = [CastManager sharedCastManager];
return YES;
}
However, this results in the following error from the linker when attempting to build the project:
duplicate symbol _kGCKDeviceCapabilityVideoOut in:
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/CastManager.o
... many similar errors ommitted for brevity ...
duplicate symbol _kGCKDeviceCapabilityAudioIn in:
/Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
/Users/nate/Projects/MyCastApp/GoogleCast.framework/GoogleCast(GCKDevice.o)
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
As far as I can tell, this exactly copies the pattern as defined in the CastVideos sample, but the sample compiles fine, and mine doesn't, and I've scoured through both projects trying to find what is different, but I just don't see it. Further, I don't see anything really wrong with doing this, and would expect it to work fine. I can't think of any other way to do it, really.
Here are the relevant files from the CastVideos sample for comparison:
ChromecastDeviceController.h
ChromecastDeviceController.m
AppDelegate.m
Other questions point to solutions that don't apply or don't fix it:
I'm not importing a .m file on accident.
I don't have duplicate references to any files in the project.
The "Compile Sources" section of the "Build Phases" project setting doesn't include any duplicates.
I've added the '-ObjC' linker flag as described by the GoogleCast API docs, though it has the same error with or without it.
I've tried deleting the delegate data and doing a clean before building.
This is with Xcode 6.3.1 running on OS X Yosemite 10.10.3 and the GoogleCastSDK-2.6.0 package from the SDK documentation page
I have checked in my sample project with the problem at https://github.com/nshafer/MyCastApp
Any help is greatly appreciated!
Edit: the duplicate is somewhat related, it's definitely about the same symbols, but the answers there didn't help, as I'm not using Object-C++, but rather just Objective-C. I don't have a .mm file, just a .m file.
For me it helped to switch the "No Common Blocks" compiler setting to NO:
It pretty much seems to make sense, the setting is explained here: What is GCC_NO_COMMON_BLOCKS used for?
The linker tells you that you have a variable named kGCKDeviceCapabilityVideoOut in two files, AppDelegate.m and CastManager.m. Since it's not in your source code, it's most likely in the GoogleCast code that you are including.
Either change the GoogleCast.h file, or make sure it is only included in one .m file. Including it from CastManager.h means it is indirectly included in every file that includes CastManager.h, so I would avoid that and only include it from CastManager.m. You'll probably have to add
#class GCKDeviceScanner;
in your CastManager.h file.
I found another fix, which is to edit GCKDevice.h in the GoogleCast.framework/Headers folder. Change the 4 constants from GCK_EXPORT to GCK_EXTERN near the top of the file.
/** Device capability flag for video out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoOut;
/** Device capability flag for video in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoIn;
/** Device capability flag for audio out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioOut;
/** Device capability flag for audio in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioIn;
I detailed this in a bug report I filed with Google's issue tracker, but it was marked as a duplicate of another somewhat related issue. Either way, it will perhaps get fixed in the next version. Until then, I would suggest going with changing the "No Common Blocks" setting as detailed in Joobik'com's answer, as that doesn't involve changing the 3rd party code.

XCode 5 - Undefined symbols for architecture armv7:

I am getting this error for a single class from a static library, which I have compiled myself. It has all been working fine and I wanted to add another class as a simple data transfer object called PPClientData.
The error is:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_PPClientData", reference from: objc-class-ref in
CPPIntegrationDelegate.o
The relevant file is included in the library compile targets and I have used otool -d on the (fat) library and it shows
libPPIntegration.a(PPClientData.o) (architecture armv7):
(__DATA,--data) section
The header for the class (PPClientData.h), which is included in the app is like this:
#import <Foundation/Foundation.h>
#interface PPClientData : NSObject
#property(nonatomic, strong) NSString* clientId;
// 3 others identical to the above with different names
#end
and the .m file which should be compiled into the library looks like this:
#import "PPClientData.h"
#implementation PPClientData
#synthesize clientId;
//Synthesize others
-(id)init {
self = [super init];
return self;
}
#end
It is consumed in a single class in the app as follows. If this one function that consumes it is commented out, the linker error goes away (it links to other classes in the library) but with this in, it fails. This is a delegate function for the library.
#import "CPPIntegrationDelegate.h"
#import "PPClientData.h"
#implementation CPPIntegrationDelegate
// Various other functions that work fine
-(PPClientData*)clientData:(PPIntegration*)integration {
PPClientData* dict = [[PPClientData alloc]init]; // This is the line that causes the linker error
dict.clientId = #"whatever";
// set other properties of dict
return dict;
}
I understand what the linker is trying to do and what the error suggests but I don't see what I've missed. Can anyone help?
If you are on Xcode 5.1, try to remove arm64 from Valid Architectures (under Build Settings) and also change the Architectures from "Standard architectures" to just armv7 and armv7s. This might be relevant to you: how to stop xcode5.1 building for 64bit
Well, it wasn't the architectures causing the problem but in some way, xcode or whatever had been confused by the order of the forward declaration of the class I was using and then the definition itself. Initially, the broken code was something like:
BrokenClass.h
// Definitions etc.
GoodClass.h
#class BrokenClass;
- (BrokenClass*)someMethod:(SomeType*) param;
GoodClass.m
#import "BrokenClass.h"
- (BrokenClass*)someMethod:(SomeType*) param
{
}
Which was included into my App by including GoodClass.h into a header file, which forward declared BrokenClass and then included BrokenClass.h into an m file which should have completed the definition, where the class was used.
Anyway, to fix it, I changed the GoodClass code to:
GoodClass.h
#import "BrokenClass.h"
- (BrokenClass*)someMethod:(SomeType*) param;
Removed the #import in the m file and then only included the one GoodClass.h into my app (which brought in the BrokenClass).
Whether this is a bug somehow or more likely, I had too many forward declarations etc. I'm not sure.

SpringBoard header errors when compiling tweaks with theos

I am new to jailbreak tweaks development and I am using theos to develop my tweaks but I ran into some issues when I was compiling my tweak with the make command.
Basically I dumped all the IOS 7 SpringBoard headers with class-dump-z and placed all of them in the theos/include folder. I realize that there's a class called XXUnknownSuperClass and when I was compiling the tweak I got some error from that class.
/theos/include/Spring/SBUIAnimationController.h:8:9: error:
'XXUnknownSuperclass.h' file not found with <angled> include; use "quotes"
instead
#import <XXUnknownSuperclass.h> // Unknown library
^~~~~~~~~~~~~~~~~~~~~~~
"XXUnknownSuperclass.h"
/theos/include/Spring/XXUnknownSuperclass.h:14:12: error:
cannot find interface declaration for 'XXUnknownSuperclass'
#interface XXUnknownSuperclass (SBApplicationAdditions)
fatal error: too many errors emitted, stopping now [-ferror-limit=]
And the next question that I have is can I hook the SBIconViewDelegate to run custom method when the app icons on the SpringBoard is tapped?
Thanks a lot for your helps!
Some of the header files from class dump can not be used directly. There are some common errors and could be changed as below.
#import "NSObject.h"
->
#import <Foundation/NSObject.h>
#class CTPhoneNumber, NSArray, NSDate, NSDictionary, NSMutableArray, NSMutableDictionary, NSObject<CTMessageAddress, NSCopying>, NSString;
->
#class CTPhoneNumber, NSArray, NSDate, NSDictionary, NSMutableArray, NSMutableDictionary, NSObject<CTMessageAddress, NSCopying>, NSString;
NSObject<CTMessageAddress><NSCopying>
->
NSObject<CTMessageAddress,NSCopying>
For your question, you can delete the declaration or implementation about "XXUnknownSuperclass" or just delete "XXUnknownSuperclass" sometimes.
I prefer only declare the interfaces about current project. You can also search "iOS header" on github.com and download headers dumped and modified by others.
Commonly SBIconViewDelegate is implemented by SBIconController, you can check SBIconController's header file and hook related methods.

Unit testing a static library with RestKit

I'm attempting to follow along with the RestKit unit test guide ( https://github.com/RestKit/RestKit/wiki/Unit-Testing-with-RestKit ) except that my project is a static library instead of an app.
Here is the test I've written:
- (void)testMappingOfDate
{
id parsedJSON = [RKTestFixture parsedObjectWithContentsOfFixture:#"plan.json"];
RKMappingTest *test = [RKMappingTest testForMapping:[self planMapping] object:parsedJSON];
[test expectMappingFromKeyPath:#"plan.date" toKeyPath:#"date"];
STAssertNoThrow([test verify], nil);
}
When I attempt to run the test I receive this error on the first line of the test:
error: testMappingOfDate (api_clientTests) failed: -[NSBundle parsedObjectWithContentsOfResource:withExtension:]: unrecognized selector sent to instance 0x1765c40
It seems like its not finding the NSBundle category defined by RestKit, but my test target header search path is set to "$(BUILT_PRODUCTS_DIR)/../../Headers" and I've verified this path includes NSBundle+RKAdditions.h which contains the supposed "unrecognized selector".
Is there something I'm missing here?
You are trying to include a category within your binary that comes from a library. To get that accomplished you will need to add the following to your (Unit-Test-Target's) build settings.
Other Linker Flags: -ObjC
From Apple's QA:
Objective-C does not define linker symbols for each function (or
method, in Objective-C) - instead, linker symbols are only generated
for each class. If you extend a pre-existing class with categories,
the linker does not know to associate the object code of the core
class implementation and the category implementation. This prevents
objects created in the resulting application from responding to a
selector that is defined in the category.
Solution:
To resolve this issue, the static library should pass the -ObjC option
to the linker. This flag causes the linker to load every object file
in the library that defines an Objective-C class or category. While
this option will typically result in a larger executable (due to
additional object code loaded into the application), it will allow the
successful creation of effective Objective-C static libraries that
contain categories on existing classes.
The error means that the "unrecognized selector" issue is at runtime. The compiler and NSBundle+RKAdditions.h do not give this error they would at compile timr.
The issue is that the code that has #implementation NSBundle(RKAdditions) is not linked into your app. So you need to add this to your build

Resources