I want to make an app in Swift that simply record via the mic of the iPhone and then play the sound recorded.
For that, I\'d like to use the lib Superpowered that is a s
As I said in comment to @OmniProg, I had a little conversation with the CTO of Superpowered that helped me a lot to find the solution below.
So, as Swift cannot interact directly with C++ but can with Objective-C, I had to create objects in Objective-C++ (.mm file, a mix between C++ and Objective-C) that wrap C++ classes of the lib Superpowered.
Here is an example with the SuperpoweredRecorder object from the lib :
Here I create a .h file where I prototype my wrapper with the name SuperpoweredRecorderWrapped
, and I also prototype in it all the methods of the SuperpoweredRecorder
of the lib that I want to use.
Then I create a new .m file that I rename .mm and I implement SuperpoweredRecorderWrapped
on it.
I import both SuperpoweredRecorderWrapped.h
and SuperpoweredRecorder.h
.
I create a SuperpoweredRecorder
object as property named _wrapped
and in my methods, I call the corresponding method of the _wrapped
object.
With that, when I'll call start
of a SuperpoweredRecorderWrapped
in my Swift code, this one will call start
of _wrapped
, a SuperpoweredRecorder
object. See the trick ?
And finally I include all the wrapped classes in my Bridging-Header, like that I can instantiate my wrapped objects from Swift.
NOTE: All the C++ code HAVE to be in .mm files, that's why I make my #include
of .h that contains C++ code in my .mm file and not in my .h file.
I haven't programmed in Objective-C++, but I do have experience with C, C++, Objective-C, and Swift, so here are some observations and ideas based on looking at the Superpowered SDK and sample code.
A bridging header lets Swift interface directly with Objective-C, and since Objective-C is a strict superset of C, this implies interfacing with C as well. However, you cannot interface directly with C++, and that's where Objective-C++ comes to the rescue. From what I'm seeing you can mix Objective-C and C++ code in Objective-C++, which allows Objective-C to use C++ classes.
Now on to some specifics.
The bridging header in the SuperpoweredFrequencies example that you looked at introduces a new Objective-C class, Superpowered
, which is not part of the library, but of the example, and is implemented in Superpowered.mm
. It is an Objective-C++ file, because Superpowered
calls some C++ code.
Looking at Superpowered.mm
, you will see that it imports Objective-C headers:
#import "SuperpoweredFrequencies-Bridging-Header.h"
#import "SuperpoweredIOSAudioIO.h"
as well as C and C++ headers:
#include "SuperpoweredBandpassFilterbank.h"
#include "SuperpoweredSimple.h"
We could have used import
instead of include
for C++ code, too, but they are probably using include
just to emphasize that it is C++ code. Looking at SuperpoweredBandpassFilterbank.h
, we see that SuperpoweredBandpassFilterbank
is a C++ class. It is used in Superpowered.mm
by the Superpowered
Objective-C++ class, see the filters
member, which is a pointer to a SuperpoweredBandpassFilterbank
object.
In the project you attempted to build, I see where the Superpowered
interface is declared in the bridging header, but I don't see an implementation. The failure to #import SuperpoweredRecorder.h
is due to SuperpoweredRecorder.h
being a C++ header. The #include
should be in your Objective-C++ (.mm) file, it's useless in the bridging header, since Swift can't make sense of C++ anyhow.
Hopefully this is helpful. Welcome to the world of C++.
I'm a bit surprised that you would have to provide prototypes of method. I used Objective C libraries in my Swift project before and I only had to add the header files in my bridging header.
See example from my project. The bridging header contains just that:
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "QTouchposeApplication.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <VungleSDK/VungleSDK.h>