使用 Swift 导入 aurioTouch 库

Import aurioTouch Library with Swift

我正在尝试将 Objective-C 应用程序转换为 swift。

我想将 aurioTouch 中的 类 导入到 Swift 应用程序,因此我创建了以下 Bridging-Header 文件:

#import "AudioController.h"

但我在 DCRejectionFilter.h、BufferManager.h、FFTHelper.h 中收到以下错误:

Unknown type name 'class'; did you mean 'Class'?

Expected ';' after top level declarator

还有 AudioController.h:

Unknown type name 'BufferManager'

Unknown type name 'DCRejectionFilter'

当然我用的是.mm而不是.m,但这行不通。

更新

仅包括 aurioTouch 库(带有 Obj-C 和 C++)的简单 swift 项目如下: https://github.com/pika-shi/aurioTouch-Sample

目前的答案向您展示了如何解决 Bridging Header #import,并且是关于如何创建 Objective-C 包装器的分步教程对象.

.mm 不代表 Swift

.mm也不代表Objective-C

表示Objective-C++,仅将文件重命名为.mm并没有任何改进。请注意,您仍然包含相同的 .h 个文件,而 这些 是问题开始的地方。这些.h参考C++类,必须换行。

将 C++ 包装在 Objective-C

文件 AudioController.h 不是 Objective-C 文件:它包含 BufferManager.h,这是一个 C++ 文件,编译就在那里停止。

您需要创建一个真正的包装器,例如 AudioControllerBridge,其中 .hObjective-C 中,而 .mm 可以反过来引用 C++:

.h

绝对,肯定没有 C++ 允许,明确,包括,否则。

#import <Foundation/Foundation.h>
@interface AudioControllerBridge : NSObject
    // ...
@end

.mm

Objective-C++ 容忍所有你需要的C++,只要它不暴露在界面中。

#import "AudioControllerBridge.h"
#import "AudioController.h"
@implementation AudioControllerBridge
    // ...
@end

当然,您可以直接修改 AudioController.h,但我们会考虑这种不良做法:对于此答案的其余部分,我们将假设您正在尝试集成 aurioTouch 原样,仅更改了 0 行 代码。

AudioControllerBridge 实现 中,您现在可以实例化 AudioController,并导入适当的所需的所有 C++ 文件编译,你在 .h 中做不到的事情。请记住,您在 Briding-Header 中向 Swift 公开的 .h 必须是纯 Objective-C 接口。

// Bridging Header
#import "AudioControllerBridge.h"

ARC

你很快就会发现你需要下载 CoreAudio/PublicUtility 因为一些文件,比如 CADebugPrintf 只是从示例中丢失了,而且不知何故不会构建在你的新项目中,至少在 DEBUG模式。

如果你到目前为止做到了,你会发现你会收到一打弃用警告,你现在可以忽略,和一半ARC AudioController.mm 中的错误。 Fix with -fno-objc-arc 编译器标志:

如果到目前为止你做到了(道具),并且添加了:

  • Accelerate.framework
  • AudioToolbox.framework
  • AVFoundation.framework

到你在Build Phases中的目标并编译,你会发现它会构建和链接。

总结

我花了 1 小时 47 分钟才达到那个点 (证明如下)。下一步当然是实际将包装器代码放入 AudioControllerBridge,这样它就 returns (wraps):

BufferManager*          _bufferManager;
DCRejectionFilter*      _dcRejectionFilter;
- (BufferManager*) getBufferManagerInstance;

其中 class.

中的 3 个非 Objective-C 元素

BufferManagerDCRejectionFilter也包裹起来可能更干净,这样它们就可以在Swift中自由使用。我会让 reader.

做出决定

演示

仅作记录,以上所有说明都导致编译成功

let ac = AudioControllerBridge()

如屏幕截图所示。它揭示了 所有 所需的文件,并显示在 Xcode 7 上成功构建 iPhone 6 在 iOS 9.