ios - 如何使 Swift 包在 Objective-C 项目中可导入/可用?

标签 ios swift objective-c swift-package-manager

我有一个只用 Swift 编写的包,现在我想让它适用于 Objective-C 项目。我知道通常在同一个目标中使用 Swift 类可以使用为模块创建的桥接头,但是当我通过 SPM 导入我的包时,没有提示创建桥接头。这可能吗?我必须先以某些方式准备我的 swift 包裹吗?

最佳答案

令人惊讶的是,网上关于此的文档数量很少,但我终于弄明白了。这并不像在你的 package.Swift 文件中进行一些更改并单击一些按钮那么容易,但幸运的是它也不是太难。我仍在努力使我的 Swift 库完全可以在 Objc 中使用,并将根据我在此过程中发现的任何发现来更新这个答案,但这是我目前所拥有的:

  • Swift 中的类只能在 objc 中使用,如果它继承自 NSObject
  • public final class MyObjcLibrary: NSObject {}
    
  • 要将其导出到 objc,您需要附加 @objc关键字,并且您可以在关键字后面用括号指定 objc 代码使用的类名 - 当您的 objc 类只是一个包含相应 Swift 类的一堆导出函数的包装器时,这非常方便:
  • @objc(MyLibrary)
    public final class MyObjcLibrary: NSObject{}
    
    这样,您的图书馆的用户可以写[MyLibrary alloc]而不是 [MyObjcLibrary alloc] .
  • 现在您可以添加用户需要在新类中使用的所有功能(使用 @objc 关键字)。假设你有一个名为 MyLibrary 的 Swift 类:
  • @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 代码中导入和调用类和函数,只需像添加 Swift 包一样通过 SPM、Cocoapods 等添加包,然后在 objc 类中:
  • @import MyPackage
    
    ...
    
    [[MyLibrary alloc] init];
    [MyLibrary doSomethingWithID:@"my_id"];
    [MyLibrary doSomethingElseWithID:@"my_id"];
    ...
    
    注意函数是如何在 objc 中命名的——如果第一个参数不以前缀“with”开头,它会自动添加到 objc 函数签名中,例如doSomethingElseWithID .
    我见过的问题:
  • 当您的 Swift 库有更新时,有时您需要重新启动 Xcode 并删除您的 DerivedData 文件夹,以便使用更新的代码重新生成桥接头文件。
  • 关于ios - 如何使 Swift 包在 Objective-C 项目中可导入/可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66910913/

    相关文章:

    ios - 从 STATIC tableviewcell 转到新的 tableviewcontroller

    ios - 使用 MKUserTrackingModeFollowWithHeading 以编程方式更改缩放

    swift - 应用内购买成功(.purchased),调用函数但变量不保持其新值

    ios - 如何制作一个在 hh :mm:ss:ms 中计算的 Swift 3.0 计时器

    java - 访问在 Swift 中使用 J2objc 翻译的枚举

    ios - 使用 OCMockito 测试发送到模拟协议(protocol)的参数

    ios - 输入货币时如何退出第一响应者

    xcode - swift 错误 : EXE_BAD_INSTRUCTION (code=EXC_I386_INVOP, 子代码 = 0x0)

    ios - 基于SQLite的核心数据: Drop indexes to reduce size and recreate them later

    objective-c - iOS - 从 Objective-C 中的媒体获取 [Explicit] 和 [Clean] 标签