C++ file in Swift/Objective C - objective-c

i am currently developing a simple app on my own.
I want to use a library from some sample app. The library consists of .mm files (C++ code) and runs perfectly on the original project.
However, when i copy the library to my file (Objective C), it seems that my other object files do not see the file. All the classes and protocol defined in this library are not recognised at all.
Errors are such as "No type or protocol name", "Unknown typename "classname" " when i try to use the library classes and protocols.
I have spent quite a lot time searching, but to no veil.
Thanks in advance.

Objective-C simply won't understand the C++ language constructs like class, etc. If you want to use this Objective-C++ code in your app then your app also needs to become Objective-C++ which can be done simply by renaming all your source files from *.m to *.mm.
In the case of Swift, however, you cannot expose C++ to it at all, and can only integrate it with C or Objective-C, so you are therefore forced to create a pure Objective-C wrapper for the C++ code (i.e. implementation in .mm but exposing no C++ types in its header file).

Related

What is the use of bridging header? Should we avoid using bridging header?

What is the use of bridging header?
Is it just for using Objective-C and Swift code in the same project?
Should we avoid using bridging header?
Say, if there are two third party library which are very similar; one of them is in Objective-C and other is in Swift. Should we use the Swift library or use Objective-C library. Are there any downside of using bridging headers?
Apple has written a great book that covers this in depth. It can be found here:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
I will quote it to answer your questions:
"What is the use of bridging header?
Is it just for using Objective-C and Swift code in the same project?"
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.
The answer to this question is yes. It is just there to make Swift and Objective-C work together in the same project.
"Should we avoid using bridging header? Say, if there are two third party library which are very similar; one of them is in Objective-C and other is in Swift. Should we use the Swift library or use Objective-C library. Are there any downside of using bridging headers?"
There are always tradeoffs. The first answer to this is no you should not avoid using a bridging header; however, as far as third party libraries you have to look at many factors. Which one has more functionality? Is it being maintained and/or added to frequently?
Using an Objective-C library will also add things to be aware of and work around. From the book:
Troubleshooting Tips and Reminders
Treat your Swift and Objective-C files as the same collection of code, and watch out for naming collisions.
If you’re working with frameworks, make sure the Defines Module (DEFINES_MODULE) build setting under Packaging is set to “Yes".
If you’re working with the Objective-C bridging header, make sure the Objective-C Bridging Header (SWIFT_OBJC_BRIDGING_HEADER) build setting under Swift Compiler - Code Generation is set to a path to the bridging header file relative to your project (for example, “MyApp/MyApp-Bridging-Header.h").
Xcode uses your product module name (PRODUCT_MODULE_NAME)—not your target name (TARGET_NAME)—when naming the Objective-C bridging header and the generated header for your Swift code. For information on product module naming, see Naming Your Product Module.
To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class or it must be marked #objc.
When you bring Swift code into Objective-C, remember that Objective-C won’t be able to translate certain features that are specific to Swift. For a list, see Using Swift from Objective-C.
If you use your own Objective-C types in your Swift code, make sure to import the Objective-C headers for those types before importing the Swift generated header into the Objective-C .m file you want to use your Swift code from.
Swift declarations marked with the private modifier do not appear in the generated header. Private declarations are not exposed to Objective-C unless they are explicitly marked with #IBAction, #IBOutlet, or #objc as well.
For app targets, declarations marked with the internal modifier appear in the generated header if the app target has an Objective-C bridging header.
For framework targets, only declarations with the public modifier appear in the generated header. You can still use Swift methods and properties that are marked with the internal modifier from within the Objective-C part of your framework, as long they are declared within a class that inherits from an Objective-C class. For more information on access-level modifiers, see Access Control in The Swift Programming Language (Swift 2.2).
Que : What is the use of bridging header?
Its correct to say, Bridging header allows user to use Objective-C classes/files in their swift code in same project.
A Swift bridging header allows you to communicate with your old Objective-C classes from your Swift classes. You will need one if you plan to keep portions of your codebase in Objective-C. It should be noted that even if you decide to convert all of your code to Swift, some classes or libraries you may use such as SVProgressHUD haven’t been rewritten in Swift and you will need to use a bridging header to use them.
Que : Should we avoid using bridging header?
Considering your question there are 2 possible cases.
case 1 : Lets say your project is developed in Objective-C and now you are developing new features using swift in it, in this case you have to have BridgingHeader as you need access of your Objective-C classes in swift code.
case 2 : If your project is developed in swift then there is no need to have Bridging header, as well if its in only Objective-C and you are not planning to move it in swift then also you don't need it.
Read more about Using swift with cocoa and Objective-C in apple documentation.
Following apple document image indicates usage of Bridging header
No, there are no downsides to using Obj-c code in your Swift project. Bridging header only exposes your Obj-c files to Swift. The two languages can coexist in the same project with no problems, as you can expose your Swift code to the Obj-c just as easily too - xCode will generate a header for all of your public Swift declarations. Although everything is possible, if you start a new project you should stick to one language so the project is easier to understand. For example if you decide on Swift you should only use Obj-c for libraries that are not available in Swift.
The bridging header allows the use of Swift and Objective-C in the same project. There are no downsides to having a bridging header in your project as the two languages can work well together within the same app.
Removing a bridging header from a project after it has been added may cause errors, as it is referenced in other places in the project when it is created.
If you only intend to use one of the two languages, a bridging header is unnecessary. On the other hand, if you are using both Swift and Objective-C, a bridging header is required and will not cause any issues.
Here is a link to find more information on the subject:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
I hope that answered your question. Good luck with your project!
What is the use of bridging header?
You have already got that answer. You're right.
Should we avoid using bridging header?
No. Its good when a third party library developed in Obj-C and may not available in Swift yet. You should use bridging header to have a best library for your app.
It depends which on you choose. In case of networking? If your project is in Obj-C based you can use AFNetworking or with the case of Swift you can use AlamoFire, you can still use AFNetworking in Swift but its not suggestable.
Bridging headers are a great way to get Objective - C code into your Swift project. If you have two libraries, one that is in Swift and one that is in Objective - C, choose the one that will offer more functionality in your app. If they offer the same functionality, I'd just go with the Swift library -> My reasoning: if the Objective-C library isn't widely used and there aren't many tutorials on how to convert the Objective - C code into Swift, it can be very time consuming to figure it out on your own. If you use a Swift library, the code is already formatted in the correct language, saving you time and potentially money (depending on if this is a hobby for you or not). As far as any downsides to using a bridging header, their really isn't! With so many libraries written in Objective-C, you almost need a bridging header in your app. Take, for example, Reachability (Here is a video on implementation in Swift). This is a library that Apple created to handle network interruptions in your app. This is a great tool for developers and requires a bridging header. Here is a great YouTube video on how to use a bridging header, but if you add a header file into your Swift file, Xcode typically asks to crete one for you. Hope this helps!

How does Objective-C compile?

I'm just curious, does Objective-C compile into C code or does the Objective-C runtime work like a layer of abstraction above the program? Sorry in advance if I don't know what I'm talking about!
A little history lesson:
Both C++ and Objective C originally started out as preprocessors for C. So you typed in your ObjC code, and it would effectively run a search-and-replace over the code and translate the Objective-C commands into straight C code that used a little helper library (the stuff in objc/runtime.h and similar files).
As the language started getting more complex, it was changed into a full parser that replaced/extended the parser in a C compiler with/into one specific to Objective-C. So while it would be perfectly possible to compile Objective-C into straight C, current ObjC compilers don't do it that way anymore.
Compiling Objective-C into C doesn't make sense, because then it would need to parse the C code and compile it.
Objective-C compiles into machine code. Remember that the language (Objective-C, C, C++) only defines the rules to correctly write code. The compiler checks to see if your code is correct and compiles it, i.e., translates it into executable code.
Also, don't confuse Objective-C language, and the Objective-C runtime. The language defines the syntax, the runtime allows the compiled code to run (in a way it's like you say, it is a layer, but it doesn't get compiled every time with your program).
EDIT:
The runtime implements the core behavior of a computer language. The runtime contains compiled code of functions in a similar way a library does. In C, for example, when you call printf() your code is compiled into machine code and linked with the library containing the implementation of that function; what this machine code does is passing parameters to the executable code in the library.
Speaking strictly from Xcode, the code is compiled with the LLVM compiler. Here is more information about the LLVM compiler. You'll be able to find more information about how the LLVM compiler works online through simple Google searches.

Mixing C++ and Objective C

Where can i find a concrete document or a dos and donts documentation on using C++ with Objective-C?
Apple seems to have removed that document from their website and i am all puzzled with collating bits of information from blogs and questions posted here.
Anyone can guide about the same.
When do we use .mm file, while mixing syntax or while using an object in .m file which belongs to a C++ class ?
While passing objects between functions belonging to two different language like passing objective-c object to a function in cpp file is it necessary to collect it in void * or can I use (ObjectiveC inteface)*?
You need to use Objective-C++ whenever you are either #include/#importing or directly writing both Objective-C and C++ code in the same file. It's usually obvious with explicit code; the #includes are often less so, and you need to take care to avoid "leaking" one of the languages into too much of the other. Your example of #importing a C++ header file is clear-cut: you can only do that with Objective-C++. Note that if your Cplusplus was a struct type, you could forward-declare it as such instead of #importing a C++ header.
If you do this in a header, it will "poison" the header to only work in that mode. You'll need to actively avoid this, or your whole project will soon end up with only .mm files. I have documented some techniques in this article and previously, in this earlier article. For newer versions of Objective-C, you can also add ivars to classes in category extensions. This means you can define C++-typed ivars in your .mm file, not the header, which allows .m files to #import it.
For your second question (Please only ask one question at a time): the id type is defined in the objc.h header file in terms of C and thus will work in both Objective-C and C++. Likewise, the Objective-C runtime API is exposed in terms of C functions, which will work from C++, too. If you actually want to send messages and access properties on Objective-C objects with the canonical syntax from C++ code, you'll need to switch that file to Objective-C++.
Use .mm files when you have a c++ syntax in your code or when including file(s) which contain c++ code.
Mixing C++ with objective-c may be a bit confusing but if you think pointer-wise than it is not a big deal. Treat C++ object instance methods as you would in C++ and the same goes for objective c objects.

Xcode/clang: Why do some, not all, of my headers give "warning: no rule to process file xxx for architecture arm7"

I am building an iOS 5 app with ARC using clang on Xcode 4.2/Lion. Good practice for me is to try to get rid of as many warnings as possible but I'm lost on this one. The app has quite a few classes, but a limited number of their header files (8 or 9) give linker warnings like this:
warning: no rule to process file '$(PROJECT_DIR)/TKMyClass.h' of type sourcecode.objj.h for architecture arm7`
I don't see any significant commonalities across these headers: a couple are 3rd party OSS code; the rest are all my own. One is a plain-C header file (with no corresponding .c) containing nothing but constants, #defines and enums; a couple are UIView and UIViewController subclasses created with Xcode's templates; the rest are ordinary Obj-C classes, some of which inherit from NSObject and some of which don't. All (of my classes) were created from scratch within the project at various times. Both older and newer classes give no warnings.
My project uses a mix of C++, Objective-C++ and Objective C classes. The warning-generating classes here are mostly Objective C (their implementations are in .m files) but the two 3rd party classes are implemented in Objective C++ (.mm).
The project otherwise builds fine and runs in the simulator and on iDevices.
To my shame I'm not particularly familiar with the project settings pages in Xcode. I expect the solution is contained in there somewhere but I'm not sure where to start without breaking things.
That means that you have accidentally added header files to be compiled. You need to go into your projects Build Phases and remove all header files from the Compile Sources section.
Check your Architecture (Project and Target): Standard (armv7) - $(ARCHS_STANDARD_32_BIT) and go to Build Pharse (Compile Source) and cheek there should not be any .h file added there.

Using C++ namespaces in objective C

I am working on a project that requires a third party library implemented in C++. I have successfully added library to my xcode project, but the problem is that the classes in library contains namespaces and when I try to access methods via namespaces, the XCode generates an error that: "utils undeclared". "utils" is the namespace I am trying to use.
My question is that is there a way to use C++ namespaces in ObjectiveC?
The code I am using to call the method is:
utils::method();
I have tried renaming my ObjectiveC ".m" file to ".mm" file, but the problem remains the same.
We are using C++ libraries in Objective-C and have no problem using C++ namespaces. As Mustafa has indicated, you need to change the Objective-C file extension to .mm to get XCode to recognize the file as Objective-C++. Then you just need to #include (not #import) the C++ headers containing the C++ namespace declarations - this is as you would normally do for 'normal' C++.