如何在 objective-c 项目中制作 Swift 包 importable/usable?
How to make a Swift package importable/usable in an objective-c project?
我有一个只用 Swift 编写的程序包,现在我想让它适用于 objective-c 项目。我知道通常在同一个目标中使用 Swift 类 你可以使用为模块创建的桥接 header,但是当我通过 SPM 导入我的包时,没有提示创建一个桥接 header。这可能吗?我是否必须先以某些方式准备我的 swift 包裹?
网上关于这个的文档少得惊人,但我终于弄明白了。这不像在 package.Swift 文件中进行一些更改并单击一些按钮那么容易,但幸运的是它也不是太难。我仍在努力使我的 Swift 库在 Objc 中可用,并将使用我在此过程中发现的任何发现更新此答案,但这是我目前所拥有的:
- Swift中的class如果继承自NSObject
,则只能在objc中使用
public final class MyObjcLibrary: NSObject {}
- 要导出到objc,需要追加
@objc
关键字,并且可以在关键字后面用括号指定objc代码使用的class名称——这个非常方便你的 objc class 只是一个包装器,带有一堆你对应的 Swift class: 的导出函数
@objc(MyLibrary)
public final class MyObjcLibrary: NSObject{}
这样,您图书馆的用户就可以写 [MyLibrary alloc]
而不是 [MyObjcLibrary alloc]
。
- 现在您可以在新 class 中添加用户需要使用的所有功能(使用
@objc
关键字)。假设您有一个名为 MyLibrary
: 的 Swift class
@objc(MyLibrary)
public final class MyObjcLibrary: NSObject{
private var myLibrary: MyLibrary
@objc public init() {
myLibrary = MyLibrary()
}
@objc public static func doSomething(withID: String) {
myLibrary.doSomething(withID)
}
@objc public static func doSomethingElse(ID: String) {
myLibrary.doSomethingElse(ID)
}
...
}
- 要在您的 objc 代码中导入和调用您的 classes 和函数,您只需像添加 Swift 包一样通过 SPM、Cocoapods 等添加包,然后在你的对象 class:
@import MyPackage
...
[[MyLibrary alloc] init];
[MyLibrary doSomethingWithID:@"my_id"];
[MyLibrary doSomethingElseWithID:@"my_id"];
...
注意函数在 objc 中的命名方式 - 如果第一个参数不是以前缀“with”开头,它会自动添加到 objc 函数签名中,例如doSomethingElseWithID
.
我遇到的问题:
- 当您的 Swift 库有更新时,有时您需要重新启动 Xcode 并删除 DerivedData 文件夹,以便使用更新的代码重新生成桥接头文件。
我有一个只用 Swift 编写的程序包,现在我想让它适用于 objective-c 项目。我知道通常在同一个目标中使用 Swift 类 你可以使用为模块创建的桥接 header,但是当我通过 SPM 导入我的包时,没有提示创建一个桥接 header。这可能吗?我是否必须先以某些方式准备我的 swift 包裹?
网上关于这个的文档少得惊人,但我终于弄明白了。这不像在 package.Swift 文件中进行一些更改并单击一些按钮那么容易,但幸运的是它也不是太难。我仍在努力使我的 Swift 库在 Objc 中可用,并将使用我在此过程中发现的任何发现更新此答案,但这是我目前所拥有的:
- Swift中的class如果继承自NSObject ,则只能在objc中使用
public final class MyObjcLibrary: NSObject {}
- 要导出到objc,需要追加
@objc
关键字,并且可以在关键字后面用括号指定objc代码使用的class名称——这个非常方便你的 objc class 只是一个包装器,带有一堆你对应的 Swift class: 的导出函数
@objc(MyLibrary)
public final class MyObjcLibrary: NSObject{}
这样,您图书馆的用户就可以写 [MyLibrary alloc]
而不是 [MyObjcLibrary alloc]
。
- 现在您可以在新 class 中添加用户需要使用的所有功能(使用
@objc
关键字)。假设您有一个名为MyLibrary
: 的 Swift class
@objc(MyLibrary)
public final class MyObjcLibrary: NSObject{
private var myLibrary: MyLibrary
@objc public init() {
myLibrary = MyLibrary()
}
@objc public static func doSomething(withID: String) {
myLibrary.doSomething(withID)
}
@objc public static func doSomethingElse(ID: String) {
myLibrary.doSomethingElse(ID)
}
...
}
- 要在您的 objc 代码中导入和调用您的 classes 和函数,您只需像添加 Swift 包一样通过 SPM、Cocoapods 等添加包,然后在你的对象 class:
@import MyPackage
...
[[MyLibrary alloc] init];
[MyLibrary doSomethingWithID:@"my_id"];
[MyLibrary doSomethingElseWithID:@"my_id"];
...
注意函数在 objc 中的命名方式 - 如果第一个参数不是以前缀“with”开头,它会自动添加到 objc 函数签名中,例如doSomethingElseWithID
.
我遇到的问题:
- 当您的 Swift 库有更新时,有时您需要重新启动 Xcode 并删除 DerivedData 文件夹,以便使用更新的代码重新生成桥接头文件。