我想在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包含我想在我的Swift代码中使用的lib方法的原型(我不喜欢这个,但如果这是唯一的方法......)。
viewController文件,其中包含Swift中的代码,我可以创建一个Superpowered对象,感谢Bridging-Header-File,并调用我放入的方法。
和wtf我甚至不明白为什么这个Objective-C ++文件在这里以及它包含什么。它无处不在,甚至不是他们的lib文件。
因此,考虑到这个示例项目,我创建了自己的项目,这里有一些截图:
示例项目中的相同Bridging-Header-File,但我包含SuperpoweredIOSAudioIO.h
,所以我可以使用SuperpoweredIOSAudioIODelegate
。
我的viewController文件,其中Swift中的代码是,我可以创建一个Superpowered对象,感谢Bridging-Header-File,并调用我放入的方法。
直到这里,它很棒,除了我不能例外创建一个SuperpoweredRecorder
对象。如果我尝试在我的Bridging-Header-File中包含SuperpoweredRecorder.h
文件,我会遇到以下错误:
所以我看到它是因为SuperpoweredRecorder.h
包含一些.cpp文件而我必须为cpp创建一个包装器(有点像我用桥接头做的那样,没有?)但是包括.h和.mm文件,我不知道我必须放入.mm文件(SuperpoweredRecorder.cpp
的代码?但我无法访问它)
所以是的,我对这些东西有点困惑,你能帮我理解如何在Swift项目中使用所有Superpowered lib吗?
答案 0 :(得分:6)
正如我在对@OmniProg的评论中所说的那样,我与Superpowered的CTO进行了一些对话,帮助我找到了以下解决方案。
因此,由于Swift无法直接与C ++交互,但可以使用Objective-C,我不得不在Objective-C ++(.mm文件,C ++和Objective-C之间的混合)中创建对象,这些对象包含了lib Superpowered的C ++类。
以下是来自lib:
的SuperpoweredRecorder对象的示例在这里,我创建一个.h文件,在其中我使用名称SuperpoweredRecorderWrapped
对我的包装器进行原型设计,并且我还在其中原型化了我想要使用的lib的SuperpoweredRecorder
的所有方法。 / p>
然后我创建一个新的.m文件,我重命名.mm并在其上实现SuperpoweredRecorderWrapped
。
我导入了SuperpoweredRecorderWrapped.h
和SuperpoweredRecorder.h
。
我创建一个SuperpoweredRecorder
对象作为名为_wrapped
的属性,在我的方法中,我调用_wrapped
对象的相应方法。
有了这个,当我在Swift代码中调用start
的{{1}}时,这个会调用SuperpoweredRecorderWrapped
的{{1}},start
个对象。看看技巧?
最后我将所有包装的类包含在我的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>