如何获取结构的捆绑包?
How to get bundle for a struct?
在Swift中,可以调用
let bundle = NSBundle(forClass: self.dynamicType)
在任何 class 中并获取当前包。如果你 NSBundle.mainBundle()
这将无法获得正确的包,例如 运行 单元测试。
那么如何获得 Swift struct
的当前包?
此处的最佳解决方案取决于您需要捆绑包的用途。
是否要查找仅存在于已知在您编写的代码运行时加载的特定应用程序、框架或扩展包中的资源?在这种情况下,您可能希望使用 init(identifier:)
而不是动态查找定义特定类型的包。
注意 "follows the type" 包查找。例如,如果框架 class Foo
使用 NSBundle(forClass: self.dynamicType)
加载资源,则加载该框架的应用程序定义的 Foo
的子 class 最终将结束查看应用程序包而不是框架包。
如果您确实需要对结构(或枚举)进行 "follows the type" 包查找,一种可能有用的解决方法是将 class 定义为子类型:
struct Foo {
class Bar {}
static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) }
}
请注意,这里没有任何动态,因为不需要 - 每个 Foo
来自相同的类型定义(因为结构不能继承),所以它的静态类型匹配它的动态类型。
(不可否认,一个可以处理结构、枚举和协议的 NSBundle(forType:)
可能会成为一个 nice feature request。尽管我认为让它处理扩展和所有事情可能会很棘手......)
更新 Swift 3.0+:
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
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")!
}
extension Bundle {
static var current: Bundle {
class __ { }
return Bundle(for: __.self)
}
}
Swift 5
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
对于 Swift 包,我们通过以下方式获得 Bundle Swift 结构在同一模块(目标)中的任何位置声明:
Bundle.module
但是,我们需要在包中导入资源才能自动生成。
Bundle.main
如果您没有扩展目标,也适用于其他项目。
在Swift中,可以调用
let bundle = NSBundle(forClass: self.dynamicType)
在任何 class 中并获取当前包。如果你 NSBundle.mainBundle()
这将无法获得正确的包,例如 运行 单元测试。
那么如何获得 Swift struct
的当前包?
此处的最佳解决方案取决于您需要捆绑包的用途。
是否要查找仅存在于已知在您编写的代码运行时加载的特定应用程序、框架或扩展包中的资源?在这种情况下,您可能希望使用 init(identifier:)
而不是动态查找定义特定类型的包。
注意 "follows the type" 包查找。例如,如果框架 class Foo
使用 NSBundle(forClass: self.dynamicType)
加载资源,则加载该框架的应用程序定义的 Foo
的子 class 最终将结束查看应用程序包而不是框架包。
如果您确实需要对结构(或枚举)进行 "follows the type" 包查找,一种可能有用的解决方法是将 class 定义为子类型:
struct Foo {
class Bar {}
static var fooBundle: NSBundle { return NSBundle(forClass: Foo.Bar.self) }
}
请注意,这里没有任何动态,因为不需要 - 每个 Foo
来自相同的类型定义(因为结构不能继承),所以它的静态类型匹配它的动态类型。
(不可否认,一个可以处理结构、枚举和协议的 NSBundle(forType:)
可能会成为一个 nice feature request。尽管我认为让它处理扩展和所有事情可能会很棘手......)
更新 Swift 3.0+:
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
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")!
}
extension Bundle {
static var current: Bundle {
class __ { }
return Bundle(for: __.self)
}
}
Swift 5
struct Foo {
class Bar {}
static var fooBundle: Bundle { return Bundle(for: Foo.Bar.self) }
}
对于 Swift 包,我们通过以下方式获得 Bundle Swift 结构在同一模块(目标)中的任何位置声明:
Bundle.module
但是,我们需要在包中导入资源才能自动生成。
Bundle.main
如果您没有扩展目标,也适用于其他项目。