如何在Swift项目中使用Superpowered lib

时间:2016-03-16 14:48:36

标签: c++ ios swift objective-c++

我想在Swift中创建一个应用程序,只需通过iPhone的麦克风录制,然后播放录制的声音。

为此,我想使用lib Superpowered这是一个带头文件的静态库。

为此,我尝试将.a和头文件拖放到我的项目中(Xcode为我创建一个桥接头文件),在Xcode>中的“Linked Frameworks and Libraries”中添加.a。目标>一般(在Xcode>目标>构建阶段>“链接二进制与库”)并索引Xcode中的.h文件路径>目标>构建设置>搜索路径>图书馆搜索路径。

但是有了这个错误“ld:symbol(s)找不到架构arm64” 与XCode: Undefined symbols for architecture arm64 error完全相同,我尝试了在网上找到的所有解决方案,但仍无法编译。

SO!

Superpowered为我们提供了一个示例应用程序,以展示如何在Swift项目中混合使用Objective-C ++并使用它们的lib(如果你想要https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine,这里是git的链接。)

以下是示例项目的一些截图,其中包含我理解的内容以及我不了解的内容:

Bridging header file Superpowered

Bridging-Header-File包含我想在我的Swift代码中使用的lib方法的原型(我不喜欢这个,但如果这是唯一的方法......)。

ViewController file

viewController文件,其中包含Swift中的代码,我可以创建一个Superpowered对象,感谢Bridging-Header-File,并调用我放入的方法。

.mm file

和wtf我甚至不明白为什么这个Objective-C ++文件在这里以及它包含什么。它无处不在,甚至不是他们的lib文件。

因此,考虑到这个示例项目,我创建了自己的项目,这里有一些截图:

Briging-Header-File

示例项目中的相同Bridging-Header-File,但我包含SuperpoweredIOSAudioIO.h,所以我可以使用SuperpoweredIOSAudioIODelegate

viewController

我的viewController文件,其中Swift中的代码是,我可以创建一个Superpowered对象,感谢Bridging-Header-File,并调用我放入的方法。

直到这里,它很棒,除了我不能例外创建一个SuperpoweredRecorder对象。如果我尝试在我的Bridging-Header-File中包含SuperpoweredRecorder.h文件,我会遇到以下错误:

errors

所以我看到它是因为SuperpoweredRecorder.h包含一些.cpp文件而我必须为cpp创建一个包装器(有点像我用桥接头做的那样,没有?)但是包括.h和.mm文件,我不知道我必须放入.mm文件(SuperpoweredRecorder.cpp的代码?但我无法访问它)

所以是的,我对这些东西有点困惑,你能帮我理解如何在Swift项目中使用所有Superpowered lib吗?

3 个答案:

答案 0 :(得分:6)

正如我在对@OmniProg的评论中所说的那样,我与Superpowered的CTO进行了一些对话,帮助我找到了以下解决方案。

因此,由于Swift无法直接与C ++交互,但可以使用Objective-C,我不得不在Objective-C ++(.mm文件,C ++和Objective-C之间的混合)中创建对象,这些对象包含了lib Superpowered的C ++类。

以下是来自lib:

的SuperpoweredRecorder对象的示例

SuperpoweredRecorderWrapped.h

在这里,我创建一个.h文件,在其中我使用名称SuperpoweredRecorderWrapped对我的包装器进行原型设计,并且我还在其中原型化了我想要使用的lib的SuperpoweredRecorder的所有方法。 / p>

SuperpoweredRecorderWrapped.mm

然后我创建一个新的.m文件,我重命名.mm并在其上实现SuperpoweredRecorderWrapped。 我导入了SuperpoweredRecorderWrapped.hSuperpoweredRecorder.h。 我创建一个SuperpoweredRecorder对象作为名为_wrapped的属性,在我的方法中,我调用_wrapped对象的相应方法。 有了这个,当我在Swift代码中调用start的{​​{1}}时,这个会调用SuperpoweredRecorderWrapped的{​​{1}},start个对象。看看技巧?

Bridge-Header

最后我将所有包装的类包含在我的Bridging-Header中,就像我可以从Swift实例化我的包装对象。

注意:所有C ++代码都必须在.mm文件中,这就是为什么我在.mm文件中创建包含C ++代码的_wrapped .h的原因而不是我的.h文件。

答案 1 :(得分:3)

我没有用Objective-C ++编程,但我确实有C,C ++,Objective-C和Swift的经验,所以这里有一些基于查看Superpowered SDK和示例代码的观察和想法。

桥接头允许Swift直接与Objective-C接口,并且由于Objective-C是C的严格超集,这也意味着与C接口。但是,您无法直接与C ++接口,而这正是Objective-C ++的拯救之处。从我所看到的,你可以在Objective-C ++中混合Objective-C和C ++代码,它允许Objective-C使用C ++类。

现在谈谈一些细节。

你看过的SuperpoweredFrequencies示例中的桥接头引入了一个 new Objective-C类Superpowered,它不是库的一部分,而是示例的一部分,并且是在Superpowered.mm中实施。它是一个Objective-C ++文件,因为Superpowered调用了一些C ++代码。

查看Superpowered.mm,您将看到它导入了Objective-C标头:

#import "SuperpoweredFrequencies-Bridging-Header.h"
#import "SuperpoweredIOSAudioIO.h"

以及C和C ++标题:

#include "SuperpoweredBandpassFilterbank.h"
#include "SuperpoweredSimple.h"

我们本可以使用import代替include来代替C ++代码,但他们可能只是强调它是{+ 1}}是C ++代码。查看include,我们看到SuperpoweredBandpassFilterbank.h是一个C ++类。它由SuperpoweredBandpassFilterbank Objective-C ++类在Superpowered.mm中使用,请参阅Superpowered成员,该成员是指向filters对象的指针。

在您尝试构建的项目中,我看到在桥接头中声明SuperpoweredBandpassFilterbank接口的位置,但我没有看到实现。 Superpowered失败的原因是#import SuperpoweredRecorder.h是C ++标头。 SuperpoweredRecorder.h应该在你的Objective-C ++(。mm)文件中,它在桥接头中没用,因为无论如何Swift都无法理解C ++。

希望这很有帮助。欢迎来到C ++世界。

答案 2 :(得分:0)

我有点惊讶你必须提供方法的原型。 之前我在Swift项目中使用了Objective C库,我只需要在我的桥接头中添加头文件。

请参阅我的项目中的示例。桥接头只包含:

//  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>