swiftstructnsbundle

How to get bundle for a struct?


In Swift, you can call

let bundle = NSBundle(forClass: self.dynamicType)

in any class and get the current bundle. If you NSBundle.mainBundle() this will fail getting correct bundle when for example running unit tests.

So how can you get the current bundle for a Swift struct?


Solution

  • The best solution here depends on what you need a bundle for.

    Is it to look up resources that exist only in a specific app, framework, or extension bundle that's known to be loaded when the code you're writing runs? In that case you might want to use init(identifier:) instead of dynamically looking up the bundle that defines a certain type.

    Beware of "follows the type" bundle lookups. For example, if a framework class Foo uses NSBundle(forClass: self.dynamicType) to load a resource, a subclass of Foo defined by the app loading that framework will end up looking in the app bundle instead of the framework bundle.

    If you do need a "follows the type" bundle lookup for a struct (or enum), one workaround that might prove helpful is to define a class as a subtype:

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

    Note there's nothing dynamic here, because nothing needs to be — every Foo comes from the same type definition (because structs can't inherit), so its static type matches its dynamic type.

    (Admittedly, an NSBundle(forType:) that could handle structs, enums, and protocols might make a nice feature request. Though I imagine it could be tricky to make it handle extensions and everything...)