Duplicate interface definition for class (Xcode, ObjC) - ios

i'm trying to add the SDK of google admob in my game but when i try to build the project after adding the admob sdk, i keep getting the error "Duplicate interface definition for class GADInterstitial"
However, when I do the same in a fresh project, I don't run into any issues at all. I have checked all the imports and project settings, they are all the same.
What should I look for, to resolve such an issue ?

You have two interfaces with the same name. Use Xcode's find in project menu option to find instances of "GADInterstitial".
Hope it will be help you.

The Objective-C #import pre-processor statement specifically ignores duplicate header files, unlike the C/C++ #include pre-processor statement (where it's necessary to use guard macros or #pragma once).
So I think you are using #include "GADInterstitial.h", instead of #import "GADInterstitial.h", somewhere in your source tree.

Related

import swift class in objective-c, <myModule>-Swift.h file not found

I have an iOS project written with Objective-C. I created an Swift class in the project, the bridging header file for accessing objective-c in Swift is generated successfully, and it works fine.
My problem is the other way around. I want to import Swift class in objective-c code.
In xcode, target -> Build Settings--> Swift Compiler section, I see Objective-C Generated Interface Header Name field with value myModule-Swift.h , but when I import this header in my objective-c class:
#import "myModule-Swift.h"
I get compiler error:
myModule-Swift.h file not found
and in project, I cannot find this file either. How can I solve this problem?
My xcode version is 6.4
Updated May 2018 Xcode 9.3
Build Settings->Objective-C Generated Interface Header Nameand set the value to YourModule-Swift.h (this is usually already set, this is the filename you need to import on .m file #import "YourModule-Swift.h"
(Example, Project named CData)
Same as Step 1, Go to Build Settings and search for "Defines Module", set both values to YES
Create a class that extends NSObject on .swift file
Build the project again
Import YourModule-Swift.h file on .m file (Please notice it's case sensitive, Mymodule !== MyModule)
In case anybody is wondering why after spending hours on this issue it is still unresolved, you might be in a situation similar to mine, where I was actually developing a framework, rather than an app.
In such case, the format of the import statement for Objective-C Generated Interface Header is as follows:
#import <ModuleName/ModuleName-Swift.h>
OMG.. the actual import statement was not "class-Swift.h" but rather "projectname-Swift.h"
You can find the name of the file if you look under build settings->Swift Compiler Code Generation -> Objective-C Generated Interface Header Name
The file was not generated when I dragged in Swift source into the GUI. Only when I right-clicked->Add file to "project". It then asked to generate the header files.
My addition to Daniel Kroms answer:
Never add -Swift.h Header to header. Even if it seems to work. Add the Import to .m file only!
In case you use in your header swift classes, make a forward declaration with #class swiftclassname before your #interface
Then you will see your real errors in your code.
For me, the problem was that I had bitcode on. When I clicked on the "Update to recommended project settings", it changed a few settings which probably the culprit. I turned "Enabled Bitcode" to "No" in the Build Settings and it is fixed now.
I was stacked this for a quite a while. In my case, my target name is something like "my-app" using dash as a part of target name. I tried to #import "my-app-Swift.h", but Xcode kept giving me errors.
I dug under 'DerivedData' folder and I found "my_app-Swift.h". So if you are using some interesting characters for the target name. You may try replace those with underscore _.
I ran into the same issue yesterday and worked for hours to fix it with no avail. Others may have been in the same boat as I. I did all of the steps described above, but nothing worked.
The cause of mine breaking was because of project name artifacts all over my project (from previously changing its name improperly).
If all of the above steps fail, I would suggest doing like I did and renaming your project so that Xcode can reset somethings... That solved the problem for me.
Doing so worked like a charm!
In my case, I have forgotten to check a swift framework to the target/classes that I was using it, really specifically case but it may help someone in the future.
For me the solution was to create a new target. For an unknown reason, the target that I had didn't have that "Swift Compiler - General" settings and thus no to "Objective-C Generated Interface Header Name" field. Having that field specified in the project was not enough.
This is not an exact answer but more of a workaround, but can save you time in some difficult cases. If you, as suggested by some of the the previous answers, can actually find the swift header buried inside the derived data folder, you are allowed to import it using the full path. This is not specific to the swift header, instead it can be applied to any header. Hope you can find this answer useful.
This answer solves my problem, but what's confusing to me is that when I convert bitcode to YES, then clean Xcode DerivedData, bulid again,also Bulid succeeds

Don't we need to link framework to XCode project anymore?

Base on this question
Why don't iOS framework dependencies need to be explicitly linked to a static library
I read the selected answer and still don't understand so I made an example project
Test Project on Github
In the test project, I remove all framework from Link Binary With Libraries and File navigation for both main project and the static library (including Foundation.framework and UIKit.framework too), basically, both project link to 0 frameworks.
Questions are
In static library, it's including MapKit/MapKit.h without referencing the Mapkit.framework to the project, why is its still working?
In main project, I remove UIKit.framework and Foundation.framework from the project, why is it still working?
Since it's working for now, will there be any issue later?
Thank you for your comment.
P.S. By working, I mean I can run on the simulator and I can archive the main project without any error.
Edit 25/07/2014
I tried with the real app that I'm working on, it's the same.
I highlight Foundation, UIKit, CoreData and 10 another frameworks in File Navigation, well, all of them.
Uncheck the target in Utilities Panel --> Target Membership
Build : Pass, Run : Pass
Every functionality of my app is still working as expected. I don't get this.
Check your project build settings. Underneath LLVM 5.1 — Language — Modules you should see the option 'Link Frameworks Automatically'. In your case it sounds like it's set to 'YES', the default.
In that case, instead of producing an error when you reference a class that the compiler doesn't know, it'll figure out which Framework contains that class and link it. In your code it'll be MKMapView or one of the other MapKit classes that triggers the linkage.
EDIT: from the relevant 'What's New?' document:
Auto Linking is enabled for frameworks imported by code modules. When
a source file includes a header from a framework that supports
modules, the compiler generates extra information in the object file
to automatically link in that framework. The result is that, in most
cases, you will not need to specify a separate list of the frameworks
to link with your target when you use a framework API that supports
modules.
Another way of looking at it is that the compiler is smart enough to mutate #import to #import when the framework has been built appropriately. All system frameworks have been.
To elaborate #Tommy's answer, a framework that supports modules satisfies the following 2 conditions:
Under Build Settings > Packaging
Define Modules is set to YES
Module Map File exists.
So, if you're certain that the framework you're using in your code modularizes like that, you can choose to not explicitly add it in the link phase as it will be automatically added as long as in the project file, under Apple Clang - Language - Modules, The option Link Frameworks Automatically is set to YES.

tgmath.h doesn't work if modules are enabled

I looked into using tgmath.h to deal with the CGFloat typedef float/double mess when dealing with arm64.
This answer has a pretty good description of how to use it, except that it didn't work at all for me. No matter what, my code was still calling the math.h functions.
After spending some time looking at all of the project compiler settings, I found that disabling the "Modules" feature (#import vs #import - iOS 7) makes it all work. More specifically, the option in the project settings is called Enable Modules(C and Objective-C) in the Apple LLVM 5.1 - Language - Modules dropdown.
To see a quick example of this issue, download a project that uses tgmath, such as MBProgressHUD, and see what happens when you enable the modules project setting. The tgmath.h calls get replaced with regular math.h calls.
My question is:
Why do modules prevent tgmath from being imported properly?
Is there a way to get around it and use both tgmath and modules? I would like to still be able to use them.
I'm not sure what's causing the issue, but as a workaround you could at least disable modules for only the file(s) where you're using tgmath.h:
Navigate to the target's Build Phases tab in Xcode.
Under the Compile Sources phase, locate the source files.
Double-click the source file and type -fno-modules in the Compiler Flags popover to disable Clang modules for that file.
At least this way you would still get the benefits of modules in most of your project. (This is assuming, of course, you don't need tgmath.h in the majority of your source files.)
It might already be in your math library under the name ctgmath: Link

#import vs #import - iOS 7

I am playing around with some of the new iOS 7 features and working with some of the Image Effects as discussed in the WWDC video "Implementing Engaging UI on iOS". For producing a blur effect within the source code for the session, UIImage was extended via a category which imports UIKit like so:
#import UIKit;
I think I saw something about this in another session video but I'm having trouble finding it. I'm looking for any background information on when to use this. Can it only be used with Apple frameworks? Are the benefits of using this compiler directive enough that I should go back and update old code?
It's a new feature called Modules or "semantic import". There's more info in the WWDC 2013 videos for Session 205 and 404. It's kind of a better implementation of the pre-compiled headers. You can use modules with any of the system frameworks in iOS 7 and Mavericks. Modules are a packaging together of the framework executable and its headers and are touted as being safer and more efficient than #import.
One of the big advantages of using #import is that you don't need to add the framework in the project settings, it's done automatically. That means that you can skip the step where you click the plus button and search for the framework (golden toolbox), then move it to the "Frameworks" group. It will save many developers from the cryptic "Linker error" messages.
You don't actually need to use the #import keyword. If you opt-in to using modules, all #import and #include directives are mapped to use #import automatically. That means that you don't have to change your source code (or the source code of libraries that you download from elsewhere). Supposedly using modules improves the build performance too, especially if you haven't been using PCHs well or if your project has many small source files.
Modules are pre-built for most Apple frameworks (UIKit, MapKit, GameKit, etc). You can use them with frameworks you create yourself: they are created automatically if you create a Swift framework in Xcode, and you can manually create a ".modulemap" file yourself for any Apple or 3rd-party library.
You can use code-completion to see the list of available frameworks:
Modules are enabled by default in new projects in Xcode 5. To enable them in an older project, go into your project build settings, search for "Modules" and set "Enable Modules" to "YES". The "Link Frameworks" should be "YES" too:
You have to be using Xcode 5 and the iOS 7 or Mavericks SDK, but you can still release for older OSs (say iOS 4.3 or whatever). Modules don't change how your code is built or any of the source code.
From the WWDC slides:
Imports complete semantic description of a framework
Doesn't need to parse the headers
Better way to import a framework’s interface
Loads binary representation
More flexible than precompiled headers
Immune to effects of local macro definitions (e.g. #define readonly 0x01)
Enabled for new projects by default
To explicitly use modules:
Replace #import <Cocoa/Cocoa.h> with #import Cocoa;
You can also import just one header with this notation:
#import iAd.ADBannerView;
The submodules autocomplete for you in Xcode.
Nice answer you can find in book Learning Cocoa with Objective-C (ISBN: 978-1-491-90139-7)
Modules are a new means of including and linking files and libraries into your projects. To understand how modules work and what benefits they have, it is important to look back into the history of Objective-C and the #import statement
Whenever you want to include a file for use, you will generally have some code that looks like this:
#import "someFile.h"
Or in the case of frameworks:
#import <SomeLibrary/SomeFile.h>
Because Objective-C is a superset of the C programming language, the #import state‐ ment is a minor refinement upon C’s #include statement. The #include statement is very simple; it copies everything it finds in the included file into your code during compilation. This can sometimes cause significant problems. For example, imagine you have two header files: SomeFileA.h and SomeFileB.h; SomeFileA.h includes SomeFileB.h, and SomeFileB.h includes SomeFileA.h. This creates a loop, and can confuse the coimpiler. To deal with this, C programmers have to write guards against this type of event from occurring.
When using #import, you don’t need to worry about this issue or write header guards to avoid it. However, #import is still just a glorified copy-and-paste action, causing slow compilation time among a host of other smaller but still very dangerous issues (such as an included file overriding something you have declared elsewhere in your own code.)
Modules are an attempt to get around this. They are no longer a copy-and-paste into source code, but a serialised representation of the included files that can be imported into your source code only when and where they’re needed. By using modules, code will generally compile faster, and be safer than using either #include or #import.
Returning to the previous example of importing a framework:
#import <SomeLibrary/SomeFile.h>
To import this library as a module, the code would be changed to:
#import SomeLibrary;
This has the added bonus of Xcode linking the SomeLibrary framework into the project automatically. Modules also allow you to only include the components you really need into your project. For example, if you want to use the AwesomeObject component in the AwesomeLibrary framework, normally you would have to import everything just to use the one piece. However, using modules, you can just import the specific object you want to use:
#import AwesomeLibrary.AwesomeObject;
For all new projects made in Xcode 5, modules are enabled by default. If you want to use modules in older projects (and you really should) they will have to be enabled in the project’s build settings. Once you do that, you can use both #import and #import statements in your code together without any concern.
#import Module(ObjC) or Semantic import
instead of usual module using
//as example
#include <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
History:
[#include -> #import] -> [Precompiled Headers .pch] -> #import Module(ObjC); -> [import Module(Swift)]
It is a part of LLVM Modules
#import <module_name>; declaration says to compiler to load(instead of compile) a precompiled binary of module which decrease a building time. Previously compiler compiled dependency every time when runt into it but now it should be compiled beforehand and just loaded
//previously
run into dependency -> compile dependency
run into dependency -> compile dependency
//#import
compile dependency
run into dependency -> load compiled binary
run into dependency -> load compiled binary
[Modulemap] - bridge between module and headers
Xcode
Enable Modules(C and Objective-C)(CLANG_ENABLE_MODULES) - CLANG #include, #import directives are automatically converted to #import that brings all advantages. Modulemap allows to do it seamless because contains a map between headers and sub/modules
Pass -fmodules
#include, #import -> #import
Link Frameworks Automatically(CLANG_MODULES_AUTOLINK) - enables system modules auto linking. Requires activated CLANG_ENABLE_MODULES. Auto-linking allows to pass -framework <framework_name> based on #import, #import(Objective-C), import(Swift)
If NO - passes -fno-autolink flag
CLANG_ENABLE_MODULES == NO and CLANG_MODULES_AUTOLINK == NO
If you want to handle system(#import <UIKit/UIKit.h>) linking manually(instead of auto-linking) you have two variants:
Add dependency into General -> Frameworks and Libraries or Frameworks, Libraries, and Embedded Content
Build Settings -> Other Linker Flags(OTHER_LDFLAGS) -> -framework <module_name>
Next error will be thrown if:
Undefined symbol: _OBJC_CLASS_$_UIView
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_UIView", referenced from:
objc-class-ref in ClassB.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
CLANG_ENABLE_MODULES is disabled
CLANG_MODULES_AUTOLINK is disabled and no manual linking
Reverse engineering
otool -l <binary>
//-l print the load commands
//find LC_LINKER_OPTION
//cmd LC_LINKER_OPTION
It currently only works for the built in system frameworks. If you use #import like apple still do importing the UIKit framework in the app delegate it is replaced (if modules is on and its recognised as a system framework) and the compiler will remap it to be a module import and not an import of the header files anyway.
So leaving the #import will be just the same as its converted to a module import where possible anyway
It seems that since XCode 7.x a lot of warnings are coming out when enabling clang module with CLANG_ENABLE_MODULES
Take a look at Lots of warnings when building with Xcode 7 with 3rd party libraries
There is a few benefits of using modules. You can use it only with Apple's framework unless module map is created. #import is a bit similar to pre-compiling headers files when added to .pch file which is a way to tune app the compilation process. Additionally you do not have to add libraries in the old way, using #import is much faster and efficient in fact. If you still look for a nice reference I will highly recommend you reading this article.

ios - Parse Issues in NSObjCRuntime, NSZone, and NSObject

I'm using AddThis to add sharing options in my iOS app.
I have imported the classes and added the -fno-objc-arc flag to all the imported classes since they don't use ARC.
However, when I try to run the app I get a slew of Parse Issues such as:
Expected identifier or '('
Unknown type name 'NSString'
Unknown type name 'Protocol'
...
These errors occur in NSObjCRuntime, NSZone, and NSObject. I have the requisite frameworks included as well. Any ideas?
Including this image if it helps:
I had the same issue on my project when I was trying to mix C code (.h and .c) with Objective-C code. Found the reason of the issue:
Check your .pch file to make sure every Objective-C framework #import (such as #import <UIKit/UIKit.h>) is enclosed in:
#ifdef __OBJC__
#endif
If they're outside of this conditional scope, the compiler will try to import Objective-C frameworks into C source code.
I just changed the filename of Base64Transcoder.c to Base64Transcoder.m, and now the project compiles. I have no idea why this fixes the problem, but it works.
I had the same issue, using C and C++ code with objective C, and i doesnt have a .pch
The easiest solution was to go into your build settings -> Custom Compiler Flags and set the "Other C Flags" to "-x objective-c" and set the "Other C++ Flags" to "-x objective-c++"
this will do the trick with xCode 7.2
I have had the same problem when my project contained .cpp files.
If .cpp file doesn't contain ObjectiveC frameworks(e.g. ) it has to 'Default-C++ Source' type
,
but if .cpp file has ObjectiveC frameworks - it must be as 'Objective-C++ Source'
TLDR: if your PCH file is OK, look through your CPP file headers to see if you've accidentally included any headers for Objective C objects.
The Details:
I got this because I had accidentally included an Objective-C class header in a C++ class header, indirectly. The structure was this:
Compass.h defined a pure Objective C class.
ActionTracker.h defined a C++ class that understood Objective C constructs (via ActionTracker.mm).
HelloWorld.h defined a purely C++ class.
In my original setup, HelloWorld.h included ActionTracker.h, but this was OK as ActionTracker.h didn't yet contain Compass.h. Later, I changed my code and included Compass.h in ActionTracker.h, which then pulled it into HelloWorld.h and I got these errors.
I had this same problem when I tried to move the info.plist file from one directory to another.
This somehow triggered XCode to edit the build phases for that target and significantly increased the amount of "Compile Sources" and "Copy Bundle Resources".
Luckily my project has multiple targets that I use for testing, (i.e. App Demo, App Dev, App Local, App 1.1, App 1.2 etc)
So I just duplicated one of the unaffected targets and renamed it (also renamed the bundle identifier and the build scheme) and this obviously fixed the problem for me since it's not the whole project that was affected but only that specific target.
If you want to try my solution, try to create a new target from scratch, or duplicate and rename any of your un-affected targets.

Resources