I'm trying to convert an Objective-C app to swift.
I'd like to import classes in aurioTouch to Swift app, so I created the following Bridging-Header file:
#import "AudioController.h"
but I received following errors in DCRejectionFilter.h, BufferManager.h, FFTHelper.h:
Unknown type name 'class'; did you mean 'Class'?
Expected ';' after top level declarator
and also in AudioController.h:
Unknown type name 'BufferManager'
Unknown type name 'DCRejectionFilter'
Of course I use .mm instead of .m, but this does not work.
update
The simple swift project just including aurioTouch Library (with Obj-C and C++) is as follows: https://github.com/pika-shi/aurioTouch-Sample
The present answer shows you how to solve the
Bridging Header
#import
, and is a step-by-step tutorial on how to create anObjective-C
wrapper object..mm does not mean Swift
.mm does not mean Objective-C either
It means
Objective-C++
, and merely renaming a file to.mm
offers no improvement. Notice that you are still including the same.h
files, and those are where the problem starts. These.h
referenceC++
classes, and they must be wrapped.Wrap the C++ in Objective-C
The file
AudioController.h
is not anObjective-C
file: it includesBufferManager.h
which is aC++
file, and compilation stops right there.You need to create a true wrapper, say
AudioControllerBridge
which.h
is inObjective-C
, and.mm
can, in turn, make references toC++
:.h
Absolutely, positively no
C++
allowed, explicit, included, or else..mm
Objective-C++
tolerates all theC++
you need, as long as it is not exposed in the interface.Of course, you could simply modify the
AudioController.h
directly, but we will consider this bad practice: for the rest of this answer, we will assume that you are attempting to integrate aurioTouch as-is, with exactly 0 lines of code changed.In the implementation of
AudioControllerBridge
, you can now instantiate theAudioController
, and import all theC++
files you need for proper compilation, something you could not do in the.h
. Remember that the.h
you are exposing to Swift inBriding-Header
must be a pureObjective-C
interface.ARC
You will soon see that you need to download CoreAudio/PublicUtility because some files, like
CADebugPrintf
are simply missing from the example, and somehow will not build in your new project, at least inDEBUG
mode.If you made it so far, you will then find out that you will get a dozen deprecated warnings, which you can ignore for now, and half as much ARC errors in
AudioController.mm
. Fix with-fno-objc-arc
Compiler Flag:If you made it so far (props), and have added:
Accelerate.framework
AudioToolbox.framework
AVFoundation.framework
to your target in Build Phases and compiled, you will find that it builds and links.
Wrapping it up
It took me 1h 47mins to reach that point (proof below). The next step is of course to actually put the wrapper code in
AudioControllerBridge
, so that it returns (wraps):which are the 3 non-
Objective-C
elements in thatclass
.It may be cleaner to to wrap
BufferManager
andDCRejectionFilter
as well, so that they can be used freely in Swift. I will let that decision to the reader.Demo
Just for the record, all the instructions above lead to a successful compilation of
as seen in this screenshot. It reveals all the files needed, and show a successful build on Xcode 7 for iPhone 6 on iOS 9.