【问题标题】:How to get bundle for a struct?如何获取结构的捆绑包?
【发布时间】:2015-09-27 18:14:25
【问题描述】:

在 Swift 中,你可以调用

let bundle = NSBundle(forClass: self.dynamicType)

在任何类中并获取当前包。如果你 NSBundle.mainBundle() 这将无法在例如运行单元测试时获得正确的包。

那么如何获取 Swift struct 的当前捆绑包?

【问题讨论】:

  • 也在寻找这个问题的答案。我目前有一个占位符类定义和一个 NSBundle 扩展帮助,所以我可以继续工作,直到找到合适的解决方案

标签: swift struct nsbundle


【解决方案1】:

这里的最佳解决方案取决于您需要捆绑包的用途。

是否要查找仅存在于特定应用程序、框架或扩展包中的资源,这些资源已知会在您编写的代码运行时加载?在这种情况下,您可能希望使用 init(identifier:) 而不是动态查找定义特定类型的包。

注意“遵循类型”的捆绑查找。例如,如果框架类 Foo 使用 NSBundle(forClass: self.dynamicType) 加载资源,则由加载该框架的应用定义的 Foo 的子类最终会在应用包中查找,而不是在框架包中查找。

如果您确实需要对结构(或枚举)进行“遵循类型”的捆绑查找,一种可能有用的解决方法是将类定义为子类型:

struct Foo {
     class Bar {}
     static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) }
}

注意这里没有什么动态的,因为不需要任何东西——每个Foo都来自同一个类型定义(因为结构不能继承),所以它的静态类型匹配它的动态类型。

(诚然,可以处理结构、枚举和协议的 NSBundle(forType:) 可能会成为 nice feature request。虽然我认为让它处理扩展和所有事情可能会很棘手......)

【讨论】:

  • “static let fooBundle = Bundle(for: Foo.Bar.self)”也可以吗? @rickster
  • 是的,这看起来可行。 (我的原始答案早于 NSBundle 被重命名为 Swift 的 Bundle。)尽管如此,请随意测试它。
【解决方案2】:

为 Swift 3.0+ 更新:

struct Foo {
     class Bar {}
     static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}

【讨论】:

    【解决方案3】:

    Swift 4+

    如果您将此结构添加到您的项目中,您可以使用let bundle = InternalConstants.bundle。在我看来,这是一个非常优雅的解决方案。

    internal struct InternalConstants {
        private class EmptyClass {}
        static let bundle = Bundle(for: InternalConstants.EmptyClass.self)
    }
    

    另一个潜在的解决方案(不太优雅):

    internal struct InternalConstants {
        internal static let bundle = Bundle(identifier: "com.hello.world")!
    }
    

    【讨论】:

      【解决方案4】:
      extension Bundle {
          static var current: Bundle {
              class __ { }
              return Bundle(for: __.self)
          }
      }
      

      【讨论】:

      • 谢谢!适用于 Xcode 11.7 + SwiftUI 实时预览
      【解决方案5】:

      斯威夫特 5

      struct Foo {
          class Bar {}
          static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
      }
      

      【讨论】:

        【解决方案6】:

        对于 Swift 包,我们通过以下方式获得 Swift 结构在同一模块(目标)中的任何位置声明的 Bundle:

        Bundle.module
        

        但是,我们需要在包中导入一个资源来自动生成。

        如果您没有扩展目标,Bundle.main 也适用于其他项目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-09
          相关资源
          最近更新 更多