【问题标题】:How to make an universal iOS library for both Objective-C and Swift?如何为 Objective-C 和 Swift 创建一个通用的 iOS 库?
【发布时间】:2016-04-14 08:21:00
【问题描述】:

我需要为 iOS(框架或静态库 - 我还没有决定)创建一个可以在 Objective-C 和 Swift 项目中使用的库。这样做的最佳方法是什么?在我看来,我有三个选择:

  1. 用 Objective-C 编写库并添加对 Swift 的支持(桥接头等)。
  2. 用 Swift 编写库并添加对 Objective-C 的支持。
  3. 用 Objective-C 和 Swift 编写两个库。我真的很想避免这个选项。

这里的主要要求是开发人员应该尽可能容易使用。理想情况下,他们应该能够选择自己的语言,而不关心甚至知道库本身是用什么语言编写的。这可以做到吗?

另外,我希望能够使用 CocoaPods 分发库,如果这有任何意义的话。

【问题讨论】:

  • 选项 1 最有可能,因为随着 swift 从一个版本到另一个版本,如果您的库的用户依赖您的库,他们将不得不等待才能升级
  • 感谢 Fonix 的输入。我什至没有考虑过这个。

标签: ios objective-c swift ios-frameworks ios-library


【解决方案1】:

选项 2。 没有问题(稍后会详细介绍)
选项 3。 正如您所说,您真的应该避免它。

选项 1 是最好的。只需考虑使用 Obj-C 和 Swift 设计您的 API。什么意思?

• 不要使用选择器 - 它们不是 Swift 标准。
Use nullability to convert to optionals
• 闭包和块的语法可能相同,但有细微差别,请注意:

Swift 闭包和 Objective-C 块是兼容的,所以你可以通过 对期望阻塞的 Objective-C 方法的 Swift 闭包。迅速 闭包和函数具有相同的类型,所以你甚至可以通过 Swift 函数的名称。

闭包具有与块相似的捕获语义,但在一个方面有所不同 关键方式:变量是可变的而不是复制的。换句话说, Objective-C 中 __block 的行为是默认行为 Swift 中的变量。

来源:Apple 的Using Swift with Cocoa and Objective-C - 它详细解释了一切。

You can read more 在这里。

在设计此类 API 时,您必须知道所有内容是如何转换的,但如果您做得对,用户将不会注意到差异 :)

模块文件

确保您的 x.framework 随附有 modules 文件夹和文件。

新的 Xcode 会为您生成它。这样用户就可以在 Swift 中使用您的 Obj-C 项目,而无需将其添加到桥接文件中。所以他们可以直接使用import myLib

为什么不用 Swift?


不幸的是,目前分发编译库最明智的方法是用 Objective-C 编写它。

这是因为一个重要原因:Swift Binary Compatiblity Problem

在确保应用的运行时兼容性的同时,Swift 语言 本身会不断进化,二进制接口也会 改变。为安全起见,应用程序的所有组件都应使用 相同版本的 Xcode 和 Swift 编译器,以确保它们 一起努力。

这意味着需要谨慎管理框架。例如, 如果您的项目使用框架与嵌入式共享代码 扩展,您将需要构建框架、应用程序和扩展 一起。依赖二进制框架是危险的 使用 Swift——尤其是来自第三方的。随着 Swift 的变化,那些 框架将与您的应用程序的其余部分不兼容。当。。。的时候 二进制接口在一两年内稳定下来,Swift 运行时将 成为主机操作系统的一部分,此限制将不再存在。

PSPDFKit 的创始人 Peter Steinberger 也遇到了同样的问题:they're stuck with Obj-C for now and can't use Swift

【讨论】:

  • 感谢您的回答。就我个人而言,我现在不必坚持使用 Objective-C 并没有什么大问题。我唯一关心的是如何以某种方式打包库,以便 Swift 开发人员不必担心自己与 Objective-C 相关。
  • 很好,迈克尔,谢谢你。那么在打包我的框架时,我有什么特别需要做的吗?如何确保它可以与 Swift 一起使用?
  • 编辑了我的答案。除了确保你有新的 Xcode 之外,你不需要做任何事情:D
  • 如果通过 CocoaPods 分发,关于模块的 cmets 是不必要的。 This 是一个 Objective-C 库,它在通过 CocoaPods 引入的 Swift 中运行良好。
  • 是的,在内部使用它就可以了。你不应该在公共 API 中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多