使 Swift OSS 库与 Objective-C 兼容

Posted

技术标签:

【中文标题】使 Swift OSS 库与 Objective-C 兼容【英文标题】:Making a Swift OSS library compatible with Objective-C 【发布时间】:2017-02-22 20:45:11 【问题描述】:

我正在用 Swift 构建一个库,它必须支持 Objective-C。

我已经检查了this answer,它建议使用 Objective-C 编写库,但给我的要求是使用 Swift 编写库。我以源代码形式提供库,因此那里关于不稳定 ABI 的论点(反对用 Swift 编写库)不应该适用于我的情况。

所以我听说为了使这个 Swift 库适用于 Objective-C,我必须避免使用 Swift 中的高级功能,而这些功能在 Objective-C 中不可用。例如:

泛型 结构 所有 Swift 类必须派生自 NSObject

所以我的两个问题是:

    在哪里可以找到这些限制的详尽列表? 如何快速测试我的库是否与 Objective-C 兼容?我对 Swift 和 Objective-C 的互操作性主题完全不熟悉。网上能找到的文章不多。 Apple 官方文档是否足够?哪些部分可以提供帮助?

感谢这里的所有帮助。

【问题讨论】:

你可以在 Objective-C 中编写单元测试来测试你的 Swift 库的特性。 @MikeTaverne 好点! 【参考方案1】:

Objective-C 不提供的最全面的 Swift 功能列表位于 Apple 的 Using Swift with Cocoa and Objective-C guide 的 Swift Type Compatibility 部分。

从那里引用,排除列表如下:

泛型 元组 在没有 Int 原始值的 Swift 中定义的枚举 输入 Swift 中定义的结构 Swift 中定义的***函数 Swift 中定义的全局变量 Swift 中定义的类型别名 Swift 风格的可变参数 嵌套类型 柯里化函数

whole guide 值得一读,但我要特别注意Mix and Match section,它描述了从 Objective-C 和反之亦然调用 Swift,包括外部框架。

我肯定会建议按照@Mike Taverne 的建议进行操作:在 Objective-C 中进行一套单元测试,以练习您在 Swift 中开发的 API。这是确保一切按预期工作的最佳方式。

【讨论】:

如果我在应用程序的私有部分使用泛型怎么办?在公共部分我会使用兼容的东西..会很好吗?我可以用这种方式编写具有客观 c 兼容性的 swift API 吗? 链接已损坏(它们重定向到 Swift),但可以找到 here,从 2017 年存档。【参考方案2】:

有更多的事情需要事先了解。

    您不能通过目标 c 类扩展 swift 类。 您不能在泛型 swift 类或方法上使用 @objc(不过,您可以在方法上使用 @objc swift 类中的泛型)

因此 api 将比用目标 c 编写的更受限制,因为它支持泛型(尽管人们喜欢说不是真正的泛型等......)并且不能扩展您在 api 中提供的任何类也有很大的限制,但它仍然是可行的。

您只需将@objc 放在任何地方,编译器就会很快告诉您不支持的内容。有时铸造也很棘手......我最终这样铸造,因为我在 swift 代码中从 swift 接收目标 c 泛型类

as! CSResponse<AnyObject> as! (CSResponse<AnyObject> & CSListData) 

这是有效的代码,但直接强制转换是不可能的。

最好的方法是为 swift 编写纯 swift 并根据需要使用目标 c 库,否则您将努力编写一行代码。 (像我一样:))

【讨论】:

以上是关于使 Swift OSS 库与 Objective-C 兼容的主要内容,如果未能解决你的问题,请参考以下文章

同时使用Swift和Objective-C,怎么做?

如何使用iOS原生语言编写Swift类?

如何让 ImageMagick 库与 Swift 4/iOS 11 一起使用?

Flutter 插件问题(引入插件同时存在静态库与swift)

如何使 googleads 库与 Google Ads API v2 弃用保持一致?

将 Swift 导入 Objective-C:未创建 Objective-C 标头“-Swift.h”