How to use Superpowered lib in Swift project
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 static library with header files.
For that, I tried to drag and drop the .a and headers files in my project (Xcode create for me a bridging header file), add the .a in “Linked Frameworks and Libraries” in Xcode > Target > General (and so in Xcode > Target > Build phases > “Link Binary With Libraries” too) and index the .h files path in Xcode > Target > Build Settings > Search Paths > Library Search Paths.
But with that I have the error “ld: symbol(s) not found for architecture arm64”
Exactly the same as here XCode: Undefined symbols for architecture arm64 error and I tried all the solutions that I found on the web for that, still no way to compile.
Superpowered gives us a sample app to show how to mix Objective-C++ and use their lib within a Swift project (Here’s a link to the git if you want https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine).
Here is some screenshots of the sample project with what I understand and what I don’t :
The Bridging-Header-File with the prototypes of the methods of the lib that I want to use within my Swift code (I don’t like this but if it’s the only way…).
The viewController file where the code in Swift is, and where I can create a Superpowered object thank’s to the Bridging-Header-File, and call the methods that I’ve put in it.
And wtf I don’t even understand why this Objective-C++ file is here and what it contains. It comes out from nowhere, not even their lib files.
So with this sample project in mind, I’ve created my own project, here is some screenshots :
The same Bridging-Header-File that in the sample project except that I include
SuperpoweredIOSAudioIO.h so I can use
My viewController file where the code in Swift is, and where I can create a Superpowered object thank’s to the Bridging-Header-File, and call the methods that I’ve put in it.
Until here, it’s great, except that I can’t for exemple create a
SuperpoweredRecorder object. If I try to include the
SuperpoweredRecorder.h file in my Bridging-Header-File I have these errors :
So I saw that it is because
SuperpoweredRecorder.h includes some .cpp files and I have to create a wrapper for cpp (a little bit like I did with the bridging header, no ?) but that includes a .h and a .mm file and I don’t know what I have to put in that .mm file (the code of
SuperpoweredRecorder.cpp ? But I don’t have access to it)
So yes, I’m a little bit confused with all that stuff, can you help me to understand how can I use all the Superpowered lib in my Swift project please ?
- Swift access to C Struct
- string.withCString and UnsafeMutablePointer(mutating: cstring) wrapped into a function
- Xcode App No Longer Reads Input From the Folder The App is Stored In
- MySQL Connector/C++ OS X 10.9 Mavericks and XCODE 5.0.2
- XCode C++ missing sperm()
- Is there any way of reading from stdin on iPhone, either hardware or emulator?
3 Solutions Collect From Internet About “How to use Superpowered lib in Swift project”
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
I create a
SuperpoweredRecorder object as property named
_wrapped and in my methods, I call the corresponding method of the
With that, when I’ll call
start of a
SuperpoweredRecorderWrapped in my Swift code, this one will call
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.
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
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>
- Optional chaining in Swift Closure where return type has to be Void
- Change string color with NSAttributedString?
- How do iOS Push Notifications work?
- How can I send a UILongPressGesture programmatically?
- When a subclass overrides a method, how can we ensure at compile time that the superclass's method implementation is called?
- Table view from array index out of range
- NSMutableString as retain/copy
- Combine longpress gesture and drag gesture together
- Local notification in phonegap 3.3.0
- Programmatically add UINavigationController in UIViewController
- Google Maps for iOS – How can you tell if a marker is within the bounds of the screen?
- Autoresize cell xib to tableview cell width and row height
- Swift: How can you rotate text for UIButton and UILabel?
- After retrieving data from Firebase, how to send retrieved data from one view controller to another view controller?
- How do I put the image on the right side of the text in a UIButton?