在Swift中,您可以调用
let bundle = NSBundle(forClass: self.dynamicType)
并获取当前包。如果您NSBundle.mainBundle(),则在运行单元测试时将无法获取正确的包。那么,如何才能获得Swift struct的当前捆绑包呢?
NSBundle.mainBundle()
struct
tzdcorbm1#
这里的最佳解决方案取决于您需要捆绑包的目的。是要查找仅存在于特定应用、框架或扩展包中的资源,而这些资源已知在您编写的代码运行时加载?在这种情况下,您可能希望使用init(identifier:),而不是动态查找定义特定类型的包。请注意“遵循类型”捆绑包查找。例如,如果框架类Foo使用NSBundle(forClass: self.dynamicType)加载资源,则加载该框架的应用所定义的Foo的子类最终将在应用捆绑包中查找,而不是在框架捆绑包中查找。如果您确实需要一个“遵循类型”的绑定包来查找一个结构(或枚举),一个可能会证明有用的变通方法是将一个类定义为一个子类型:
init(identifier:)
Foo
NSBundle(forClass: self.dynamicType)
struct Foo { class Bar {} static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) } }
注意,这里没有动态的东西,因为没有什么需要动态的--每个Foo都来自相同的类型定义(因为结构体不能继承),所以它的静态类型匹配它的动态类型。(诚然,一个能够处理结构体、枚举和协议的NSBundle(forType:)可能会成为一个nice feature request,尽管我想让它处理扩展和所有事情可能会很棘手......)
NSBundle(forType:)
llycmphe2#
extension Bundle { static var current: Bundle { class __ { } return Bundle(for: __.self) } }
pgvzfuti3#
针对Swift 3.0+更新:
struct Foo { class Bar {} static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) } }
qyzbxkaa4#
雨燕5
k2fxgqgv5#
对于Swift Packages,我们通过以下方式获取Swift结构体在同一模块(目标)中任意位置声明的Bundle:
Bundle.module
然而,我们需要在Package中导入一个资源来自动生成这个。如果您没有扩展目标,Bundle.main也适用于其他项目。
Bundle.main
az31mfrm6#
斯威夫特4+
如果你把这个结构体添加到你的项目中,你可以做let bundle = InternalConstants.bundle。在我看来,这是一个非常优雅的解决方案。
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")! }
6条答案
按热度按时间tzdcorbm1#
这里的最佳解决方案取决于您需要捆绑包的目的。
是要查找仅存在于特定应用、框架或扩展包中的资源,而这些资源已知在您编写的代码运行时加载?在这种情况下,您可能希望使用
init(identifier:)
,而不是动态查找定义特定类型的包。请注意“遵循类型”捆绑包查找。例如,如果框架类
Foo
使用NSBundle(forClass: self.dynamicType)
加载资源,则加载该框架的应用所定义的Foo
的子类最终将在应用捆绑包中查找,而不是在框架捆绑包中查找。如果您确实需要一个“遵循类型”的绑定包来查找一个结构(或枚举),一个可能会证明有用的变通方法是将一个类定义为一个子类型:
注意,这里没有动态的东西,因为没有什么需要动态的--每个
Foo
都来自相同的类型定义(因为结构体不能继承),所以它的静态类型匹配它的动态类型。(诚然,一个能够处理结构体、枚举和协议的
NSBundle(forType:)
可能会成为一个nice feature request,尽管我想让它处理扩展和所有事情可能会很棘手......)llycmphe2#
pgvzfuti3#
针对Swift 3.0+更新:
qyzbxkaa4#
雨燕5
k2fxgqgv5#
对于Swift Packages,我们通过以下方式获取Swift结构体在同一模块(目标)中任意位置声明的Bundle:
然而,我们需要在Package中导入一个资源来自动生成这个。
如果您没有扩展目标,
Bundle.main
也适用于其他项目。az31mfrm6#
斯威夫特4+
如果你把这个结构体添加到你的项目中,你可以做
let bundle = InternalConstants.bundle
。在我看来,这是一个非常优雅的解决方案。另一种可能的解决方案(不太优雅):