Unknown type error in .mm file - objective-c++

I have a .mm file called A.mm, and in it I import B.hpp file, I use the struct C in B.hpp.
But the Xcode build will report unknown type error, it demands me to add the namespace before the C class.
If I click go to definition of C class it can jump to the right place in B.hpp. So I wonder can I do something to avoid adding long namespace prefix?

Related

Redefinition of 'ClassName' as different kind of symbol in generated header

I created a Swift enum as an Int (so it will work with Objective-c).
When I build the project, everything is fine. However, as soon as I try to import the class in a .h file (using a forward declaration #ClassName), the generated header file errors out with Redefinition of 'ClassName' as a different kind of symbol
Looking in the generated .h file I can see it generated the new type like so:
typedef SWIFT_ENUM(NSInteger, ClassName, closed) {
type1 = 1,
type2 = 2,
};
It underlines the ClassName saying it's been re-declared. However, it exists nowhere else in the header file (doing a search and it comes up only once) and it's only declared once in a swift file.
Any suggestions on what is going on?
Enums are not classes in Objective-C, so you need to use typedef instead of forward declaration in your .h file:
typedef NS_ENUM(NSInteger, ClassName);
and then in .m file, you need to import Module-Swift.h file.

"Cannot inherit from non-open class" swift

As of Xcode 8 beta 6 I now get the compile error "Cannot inherit from non-open class (Class)" outside of its defining module"
The class I was inheriting from was part of a separate Swift framework but my project compiled for Xcode 8 beta 5. What do I need to change to get my project to compile again?
Found the answer myself.
In Swift 3 you can now mark a class as open instead of public this allows files outside of the module to subclass that class.
Simply replace public in your module class with open.
Reference here.
The class you inherit from needs to be defined as open instead of public.
A bit more context on the changes to access control in Swift 3:
Swift 2 only had 3 access levels:
private: entities are available only from within the source file where they are defined.
internal: entities are available to the entire module that includes the definition.
public: entities are intended for use as API, and can be accessed by any file that imports the module.
Swift 3 is adding 2 more access levels (open and fileprivate) and changing the meaning of private:
private: symbol visible within the current declaration only.
fileprivate: symbol visible within the current file.
internal: symbol visible within the current module or default access modifier.
public: symbol visible outside the current module.
open: for class or function to be subclassed or overridden outside the current module.
I had this error even after marking the class as open (on Xcode 14.1). The fix was a clean (Cmd + Shift + K) and rebuild.

Redefinition of 'Comment' as different kind of symbol in swift

I have a class Comment declared as such:
public class Comment: NSManagedObject {
vars and methods...
}
When I try to compile my project, I get an error that reads:
Redefinition of 'Comment' as different kind of symbol
It highlights this line in the generated .h file: #interface Comment : NSManagedObject, and it tells me that the original declaration of Comment is in AIFF.h (something part of Foundation) and the line of the declaration is: typedef struct Comment Comment;.
I've only recently gotten this problem, and I've built the project with a Comment object successfully before. Why would an error like this happen in Swift?
Edit
If I remove the NSManagedObject superclass it compiles...
It may be a case that your class Comment is defined somewhere else in Foundation framework. What you need to do is importing only specific classes that you need inside your file. First remove all import statements in the source file and then import NSManagedObject like this:
import class CoreData.NSManagedObject
Then you will gain access to the NSManagedObject class you need for your Comment subclass. If you need any classes or structs from Foundation framework (for example NSError) you should import them like this:
import class Foundation.NSError
This will eliminate compiler errors about redefinition of class Comment.
Also make sure to clean the project and clean build folder by using Command + Shift + K and Command + Shift + alt + K

Can't access constants from one swift file in another

I'm converting some code from Objective C to Swift so I can get a handle on Swift.
Basically, in Objective C, I had a header file containing some global constants which were accessible in other Objective C classes.
I changed my .h file to be .swift and changed the constants to look like:
public let INVALID_INTEGER_VALUE = (-32768)
public let INVALID_LONGLONG_VALUE = (0x8000000000000000)
...
But when I try to access these in another Swift file, the compiler gives "Use of unresolved identifier..." I tried importing my .swift file, but that also didn't work (as far as I can tell, I shouldn't need to import any of my swift files as they are part of the same module).
Any thoughts?
You could also run into this if the file that is trying to use the constant has been added to another target (like the tests target) that the file containing the constants has not been added to.

Error: 'class name' redeclared as different kind of symbol?

I was facing the same error as asked in this question
I overcome with this error by solution of declaring class ahead of time in my .h file with the class parameter
I am having FFTBufferManager.h and FFTBufferManager.cpp file and using it in HomeView.h and HomeView.mm file
class FFTBufferManager,CAStreamBasicDescription,DCRejectionFilter;
But now I am having error as
#include "FFTBufferManager.h"
#include "aurio_helper.h"
#include "CAStreamBasicDescription.h"
class CAStreamBasicDescription,FFTBufferManager; //here it shows this error
EXpected Unqualified-id befor ',' token
#interface HomeView
{
FFTBufferManager* fftBufferManager;
//it shows erros
EXpected Unqualified-id befor ',' token
ISO c++ forbids declaration of FFTBufferManager with no type
}
#property FFTBufferManager* fftBufferManager;
//shows error
'FFTBufferManager' is not a type
I'm gathering you're using both C++ and Objective-C.
I'd suggest renaming all your .cpp and .m files in which Objective-C and C++ code are meeting to use the extension .mm - this tells the compiler to use "Objective-C++" rules, and will stop a lot of compiler troubles.
Also, it seems CAStreamBasicDescritpion is a C++ class - you'll have to forward-declare it with class CAStreamBasicDescritpion;, not #class CAStreamBasicDescritpion; (note, no "at" sign) - the second form is only for forward-declaring Objective-C classes. This I suspect is the root cause of the particular error you have observed.
EDIT in response to comment: I'm not sure about your first new issue - that should work fine so long as both FFTBufferManager and CAStreamBasicDescription are C++ classes. As to your second one, depending on where exactly that line of code is (CAStreamBasicDescription thruFormat;) you may need to include the header rather than just the forward-declare: you're declaring an instance of CAStreamBasicDescription here, and the compiler needs to know its structure to do so.
You can't declare more than one class at a time.
Change your declarations to
class CAStreamBasicDescription;
class FFTBufferManager;
The compiler is looking for an unqualified-id because it believes that you're declaring a variable of type CAStreamBasicDescription, so it expects a variable name where you gave it a comma.
Looks like you are trying to create a class that already exists in one of the Cocoa frameworks.