swift 如何获取结构体的bundle?

yqkkidmi  于 2023-02-07  发布在  Swift
关注(0)|答案(6)|浏览(227)

在Swift中,您可以调用

let bundle = NSBundle(forClass: self.dynamicType)

并获取当前包。如果您NSBundle.mainBundle(),则在运行单元测试时将无法获取正确的包。
那么,如何才能获得Swift struct的当前捆绑包呢?

tzdcorbm

tzdcorbm1#

这里的最佳解决方案取决于您需要捆绑包的目的。
是要查找仅存在于特定应用、框架或扩展包中的资源,而这些资源已知在您编写的代码运行时加载?在这种情况下,您可能希望使用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,尽管我想让它处理扩展和所有事情可能会很棘手......)

llycmphe

llycmphe2#

extension Bundle {
    static var current: Bundle {
        class __ { }
        return Bundle(for: __.self)
    }
}
pgvzfuti

pgvzfuti3#

针对Swift 3.0+更新:

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

qyzbxkaa4#

雨燕5

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

k2fxgqgv5#

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

Bundle.module

然而,我们需要在Package中导入一个资源来自动生成这个。
如果您没有扩展目标,Bundle.main也适用于其他项目。

az31mfrm

az31mfrm6#

斯威夫特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")!
}

相关问题