Not able to access .mm file into swift4 - ios

I am working on a project which contains Objective C, Objective C++, and Swift4 classes. I am trying to access the .mm file (i.e Objective C++ file) into swift class but it's giving me an error and showing it's undeclared. I have added a bridging header to the project and imported Objective C++ file's header there.
Example to understand the problem:
I have A.mm class which has B.mm class imported in it. after adding A class into the bridging header compiler is giving an error in B class.
Error In B.h :
Please help

Swift can only bridge to C and Objective-C. If your missing class uses C++ types in its header, Swift will be unable to read that file and just skip that class.
Can you change your Objective-C++ class so it only uses C++ types in its .mm file, and not in its .h file? Then it will look like a regular Objective-C class to Swift and you should be able to use it.
Alternately, you may be able to create a second class that is ObjC „on the outside“ and calls the ObjC++ class in its .mm, and that just hands through all the calls, translating C++ data types into simple C types or ObjC objects.
Look into „class extensions“ for declaring C++ properties and instance variables that would usually go into your header in the .mm file instead.

Related

Can I have a class that's partially implemented in Swift, and partially implemented in Objective C?

I want to extend my class which I wrote in Swift. I want to write the extension in Objective C because I need to put some Objective C code which I can't port into Swift. I know that I can create a .h and .m and then include the .h at the bridging header. But in the .h, I need to include the original .swift class file right?
How can I solve this? Can I include using myclass-swift.h? Thanks.
The following documentation may be helpful: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID122. You've probably already looked at that, but just in case. The following question may also help: Extending a Swift class with Objective C category.
As you know, to use Objective-C code in Swift there is the bridging header. To go the other way around, there is the auto-generated *-Swift.h header that should be imported in .m (and .mm) implementation files. The documentation says it should not be imported into .h files. In fact, the compiler won't let you import it into a .h file that is included, directly or indirectly, in the bridging header. However, with some care you can import it into other .h files.
Now, suppose your Swift class is called SwiftClass and you want to add to it a method called ocFunction() implemented in Objective-C. One approach, essentially presented in the aforementioned answer, is to implement a category in an Objective-C source file (.m):
#implementation SwiftClass (OCExtension)
-(void)ocFunction {...}
#end
Then modify your SwiftClass to include the following:
class SwiftClass : NSObject
{
...
#nonobjc func ocFunction()
{
self.perform(Selector(("ocFunction")))
}
...
}
The referenced answer suggests doing this in an extension, but since you have full control of the SwiftClass source, you can just do it in the class directly. BTW, the Objective-C category function could be named something other than the SwiftClass's function, thus eliminating the need for #nonobjc.
Another approach might be to define an Objective-C wrapper interface like this:
#interface SwiftClassOC : NSObject
+(void)ocFunction:(SwiftClass*)sc;
#end
and make it available to Swift via the bridging header. The implementation would go into a .m file. Then your ocFunction() in SwiftClass would look like
func ocFunction()
{
SwiftClassOC.ocFunction(self)
}
Please note that SwiftClassOC is stateless, so it's essentially a set of helper functions that take a SwiftClass pointer. SwiftClass is the one maintaining the state.
You can extend an Objective-C class with Swift, but you cannot extend a Swift class with Objective-C.
I want to write the extension in Objective C because I need to put some Objective C code which I can't port into Swift
You can do that, but not as part of the Swift class. What I usually do is make a "helper" class in Objective-C and import it into Swift.

How to call Obj C custom Init method of a NSOperations subclass from Swift

I have a subclass of NSOperation and custom init method which can take couple of arguments. this class is written in OBJ C. and I wanted to call this init method from Swift class for unit testing. is there a way I can call the init method directly from swift? Compiler couldn't recognize the init method.
You have to create a bridging header and import the ObjC class there. Then that class will be available in all of your swift classes
Add a new file to Xcode (File > New > File), then select “Source” and click “Header File“.
Name your file “YourProjectName-Bridging-Header.h”. ...
Create the file.
Navigate to your project build settings and find the “Swift Compiler – Code Generation” section. You may find it faster to type in “Swift Compiler” into the search box to narrow down the results. Note: If you don’t have a “Swift Compiler – Code Generation” section, this means you probably don’t have any Swift classes added to your project yet. Add a Swift file, then try again.
Next to “Objective-C Bridging Header” you will need to add the name/path of your header file. If your file resides in your project’s root folder simply put the name of the header file there. Examples: “ProjectName/ProjectName-Bridging-Header.h” or simply “ProjectName-Bridging-Header.h”.
Open up your newly created bridging header and import your Objective-C classes using #import statements. Any class listed in this file will be able to be accessed from your swift classes.
Above info was found here: http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/

Import ViewController.swift in Objective C file

I'm trying to use my new ViewController.swift file in my existing objective C project.
Below is swift file code
import UIKit
class TutorialViewController: UIViewController{
}
Below is Objective C code
#import "TutorialViewController-Swift.h" //"TutorialViewController-Swift.h" file not found
I'm unable to import swift code. I had followed all the steps in this
Please let me know, where am I making mistake. Is it only applicable for NSObject class.
Thanks in advance
You can't import a swift class directly to Objective C class like that way. By default Xcode generates a swift bridging header for this purpose. You need to import that header. Normally that header file uses the following naming convention:
<#your module name #>-Swift.h
Or you can get the value from your target's build settings:
Choose your target
Go to Build Settings tab
Go to Swift Compiler - Code Generation category
Check the value of Objective-C Generated Interface Header Name
Import that header in your objective-c class to use all your swift classes
As per document, When you import Swift code into Objective-C, you rely on an Xcode-generated header file to expose those files to Objective-C. This automatically generated file is an Objective-C header that declares the Swift interfaces in your target. It can be thought of as an umbrella header for your Swift code. The name of this header is your product module name followed by adding "-Swift.h".
By default, the generated header contains interfaces for Swift declarations marked with the public modifier. It also contains those marked with the internal modifier if your app target has an Objective-C bridging header. 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. If your app target is compiled with testing enabled, a unit test target can access any declaration with the internal modifier as if they were declared with the public modifier by prepending #testable to the product module import statement.
You don’t need to do anything special to create the generated header file—just import it to use its contents in your Objective-C code. Note that the Swift interfaces in the generated header include references to all of the Objective-C types used in them. 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 access the Swift code from.
For more details follow this Importing Swift into Objective-C

Unknown type name class, did you mean Class

So I tried to import aurioTouch into my app and I keep getting this error saying
"unknown type name 'class' did you mean "Class"?
My bridging header file:
#import "AudioController.h"
#import "BufferManager.h"
#import "FFTHelper.h"
#import "DCRejectionFilter.h"
I tried changing this to .mm for all these files but it doesn't solve my issue. Anyone have any ideas why this is happening?
To mix C++ and Objective-C you need to use the .mm extension. If, however, your class is only C++ (and only includes C/C++ headers) then you can use the normal .cpp extension.
.mm
A source file with this extension can contain C++ code in addition to Objective-C and C code. This extension should be used only if you
actually refer to C++ classes or features from your Objective-C code.
I had the same issue, and I could solve by the following answer:
Import aurioTouch Library with Swift
In short, AudioController.h is not an Obj-C file because it imports C++ files (BufferManager.h, FFTHelper.h, and DCRejectionFilter.h). So you cannot bridge it to Swift just like that.
You have to create a pure Obj-C file wrapping AudioController.h.

Using Swift classes inherited from Objective C libraries code in Objective C code

I'm working on a Swift project, using couple of ObjC libraries.
One of them is SWTableViewCell. My app's lists' cells inherit from SWTableViewCell, a subclass of UITableViewCell that adds swiping action on cells.
Libraries are added with cocoapods.
I want to import some Swift code into ObjC, within my main project. The project-Swift.h is being generated as it should (every Swift class inheriting from NSObject, annotated as #objc is being included), but it contains errors:
project-Swift.h:135:31: Cannot find interface declaration for 'SWTableViewCell', superclass of 'MySWTableViewCell'; did you mean 'UITableViewCell'?
How to remedy this situation?
I need the header to be generated properly in order to use Swift classes in ObjC
My goal is either to ignore these classes, or let XCode that it needs to import additional header during project-Swift.h
This should solve your problem:
Create a bridging header file in you project: File > New > File > (iOS or OS X) > Source > Header File
In your Objective-C bridging header file, import the needed Objective-C headers you want to expose to Swift: in your case you need #import "SWTableViewCell.h"

Resources