如何为 Objective-C 和 Swift 制作一个通用的 iOS 库?
How to make an universal iOS library for both Objective-C and Swift?
我需要为 iOS 创建一个库(框架或静态库 - 我还没有决定),可以在 Objective-C 和 Swift 项目中使用。这样做的最佳方法是什么?在我看来,我有三个选择:
- 在 Objective-C 中编写库并添加对 Swift 的支持(桥接头等)。
- 在Swift中编写库并添加对Objective-C的支持。
- 写两个库,都在Objective-C和Swift。我真的很想避免这个选项。
这里的主要要求是尽可能方便开发者使用。理想情况下,他们应该能够选择自己的语言而不关心,甚至不知道库本身是用什么语言编写的。这可以做到吗?
此外,我希望能够使用 CocoaPods 分发库,如果这有任何意义的话。
选项2.没有问题(后面有详细说明)
选项3.正如你所说,你真的应该避免它。
选项 1 最佳。只需在设计 API 时考虑到 Obj-C 和 Swift 即可。这是什么意思?
• 不要使用选择器 - 它们不是 Swift 标准。
• Use nullability to convert to optionals
• 闭包和块可能具有相同的语法,但还是有细微差别,请注意:
Swift closures and Objective-C blocks are compatible, so you can pass
Swift closures to Objective-C methods that expect blocks. Swift
closures and functions have the same type, so you can even pass the
name of a Swift function.
Closures have similar capture semantics as blocks but differ in one
key way: Variables are mutable rather than copied. In other words, the
behavior of __block in Objective-C is the default behavior for
variables in Swift.
资料来源:Apple 的 Using Swift with Cocoa and Objective-C - 它详细解释了所有内容。
在设计这样的 API 时,您必须知道所有内容是如何转换的,但如果操作正确,用户将不会注意到差异:)
模块文件
确保您的 x.framework
随附 modules
文件夹和文件。
新 Xcode 为您生成。这样用户就可以在 Swift 中使用您的 Obj-C 项目,而无需将其添加到桥接文件中。这样他们就可以 import myLib
开箱即用。
为什么不Swift?
不幸的是,现在分发编译库最明智的方法是将其写入 Objective-C。
这是因为一个重要原因:Swift Binary Compatiblity Problem
While your app’s runtime compatibility is ensured, the Swift language
itself will continue to evolve, and the binary interface will also
change. To be safe, all components of your app should be built with
the same version of Xcode and the Swift compiler to ensure that they
work together.
This means that frameworks need to be managed carefully. For instance,
if your project uses frameworks to share code with an embedded
extension, you will want to build the frameworks, app, and extensions
together. It would be dangerous to rely upon binary frameworks that
use Swift — especially from third parties. As Swift changes, those
frameworks will be incompatible with the rest of your app. When the
binary interface stabilizes in a year or two, the Swift runtime will
become part of the host OS and this limitation will no longer exist.
Peter Steinberger,PSPDFKit, which is also a library distributed as a compiled library has ran into the same problem: they're stuck with Obj-C for now and can't use Swift 的创始人。
我需要为 iOS 创建一个库(框架或静态库 - 我还没有决定),可以在 Objective-C 和 Swift 项目中使用。这样做的最佳方法是什么?在我看来,我有三个选择:
- 在 Objective-C 中编写库并添加对 Swift 的支持(桥接头等)。
- 在Swift中编写库并添加对Objective-C的支持。
- 写两个库,都在Objective-C和Swift。我真的很想避免这个选项。
这里的主要要求是尽可能方便开发者使用。理想情况下,他们应该能够选择自己的语言而不关心,甚至不知道库本身是用什么语言编写的。这可以做到吗?
此外,我希望能够使用 CocoaPods 分发库,如果这有任何意义的话。
选项2.没有问题(后面有详细说明)
选项3.正如你所说,你真的应该避免它。
选项 1 最佳。只需在设计 API 时考虑到 Obj-C 和 Swift 即可。这是什么意思?
• 不要使用选择器 - 它们不是 Swift 标准。
• Use nullability to convert to optionals
• 闭包和块可能具有相同的语法,但还是有细微差别,请注意:
Swift closures and Objective-C blocks are compatible, so you can pass Swift closures to Objective-C methods that expect blocks. Swift closures and functions have the same type, so you can even pass the name of a Swift function.
Closures have similar capture semantics as blocks but differ in one key way: Variables are mutable rather than copied. In other words, the behavior of __block in Objective-C is the default behavior for variables in Swift.
资料来源:Apple 的 Using Swift with Cocoa and Objective-C - 它详细解释了所有内容。
在设计这样的 API 时,您必须知道所有内容是如何转换的,但如果操作正确,用户将不会注意到差异:)
模块文件
确保您的 x.framework
随附 modules
文件夹和文件。
新 Xcode 为您生成。这样用户就可以在 Swift 中使用您的 Obj-C 项目,而无需将其添加到桥接文件中。这样他们就可以 import myLib
开箱即用。
为什么不Swift?
不幸的是,现在分发编译库最明智的方法是将其写入 Objective-C。
这是因为一个重要原因:Swift Binary Compatiblity Problem
While your app’s runtime compatibility is ensured, the Swift language itself will continue to evolve, and the binary interface will also change. To be safe, all components of your app should be built with the same version of Xcode and the Swift compiler to ensure that they work together.
This means that frameworks need to be managed carefully. For instance, if your project uses frameworks to share code with an embedded extension, you will want to build the frameworks, app, and extensions together. It would be dangerous to rely upon binary frameworks that use Swift — especially from third parties. As Swift changes, those frameworks will be incompatible with the rest of your app. When the binary interface stabilizes in a year or two, the Swift runtime will become part of the host OS and this limitation will no longer exist.
Peter Steinberger,PSPDFKit, which is also a library distributed as a compiled library has ran into the same problem: they're stuck with Obj-C for now and can't use Swift 的创始人。