Bal*_*cze 7 bundle storyboard ios cocoapods swift
我正在制作一个 pod (MySDK) 并希望从CocoaPods生成的单独资源包中加载资产。
但是,我无法让它工作。
这是我尝试加载故事板的方法:
let storyBoard = UIStoryboard(name: "SDK", bundle: Bundle(identifier:"org.cocoapods.SchedJoulesSDK"))
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
'在捆绑包中找不到名为'SDK'的故事板
该捆绑包已添加到 Xcode 中:
我的podspec样子是这样的:
s.resource_bundles = {
'MySDK' => ['SDK/*/*.{xib,storyboard,xcassets}']
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
Mec*_*cki 20
如果你在 CocoaPods PodSpec 文件中使用resource或resources,你告诉 Cocoapods 这些是你的库将在运行时加载的资源文件。
如果您的库是作为动态框架构建的,则这些文件只是复制到该框架的资源文件夹路径中,一切都会好起来的。然而,如果您的库是作为静态库构建的,则这些将被复制到主应用程序包 ( .app)的资源文件夹中,这可能会出现问题,因为该主应用程序可能已经拥有该名称的资源,或者另一个 Pod 可能拥有该资源同名,在这种情况下,这些文件将相互覆盖。Pod 是作为动态框架构建还是作为静态库构建的,并不是由 PodSpec 指定的,而是由集成您的 Pod 的应用程序在 Podfile 中指定的。
因此,对于具有资源豆荚,强烈建议使用resource_bundles,而不是!
在你的情况下,线条
s.resource_bundles = {
'MySDK' => ['SDK/*/*.{xib,storyboard,xcassets}'] }
Run Code Online (Sandbox Code Playgroud)
告诉 CocoaPods 创建一个名为MySDK ( MySDK.bundle)的资源包,并将与模式匹配的所有文件放入该资源包中。如果你的 Pod 是作为框架构建的,这个包位于你的框架包的资源文件夹中;如果它是作为静态库构建的,则该包会被复制到主应用程序包的资源文件夹中,如果您将包命名为与 Pod 相同的名称(您不应将其命名为“ MySDK ”,而是“ SchedJoulesSDK ”)。
此包将具有与您的 Pod 相同的标识符,但是当构建动态框架时,您的框架包也将具有该标识符,然后当您通过标识符加载它时,正在加载哪个包是未定义的行为(并且目前外部包总是在我的测试中获胜)。
正确的代码看起来像这样(虽然没有测试):
// Get the bundle containing the binary with the current class.
// If frameworks are used, this is the frameworks bundle (.framework),
// if static libraries are used, this is the main app bundle (.app).
let myBundle = Bundle(for: Self.self)
// Get the URL to the resource bundle within the bundle
// of the current class.
guard let resourceBundleURL = myBundle.url(
forResource: "MySDK", withExtension: "bundle")
else { fatalError("MySDK.bundle not found!") }
// Create a bundle object for the bundle found at that URL.
guard let resourceBundle = Bundle(url: resourceBundleURL)
else { fatalError("Cannot access MySDK.bundle!") }
// Load your resources from this bundle.
let storyBoard = UIStoryboard(name: "SDK", bundle: resourceBundle)
Run Code Online (Sandbox Code Playgroud)
由于resourceBundle不能在运行时更改,因此只创建一次(例如在应用程序启动时或在您的框架初始化时)并将其存储到全局变量(或全局类属性)中是安全的,因此您可以在需要时始终使用它(a bundle 对象也几乎不使用任何 RAM 内存,因为它只封装元数据):
final class SchedJoulesSDK {
static let resourceBundle: Bundle = {
let myBundle = Bundle(for: SchedJoulesSDK.self)
guard let resourceBundleURL = myBundle.url(
forResource: "MySDK", withExtension: "bundle")
else { fatalError("MySDK.bundle not found!") }
guard let resourceBundle = Bundle(url: resourceBundleURL)
else { fatalError("Cannot access MySDK.bundle!") }
return resourceBundle
}()
}
Run Code Online (Sandbox Code Playgroud)
属性是惰性初始化的(这是static let属性的默认值,不需要lazy关键字)并且系统确保这种情况只发生一次,因为let属性一旦初始化就不能更改。请注意,您不能Self.self在该上下文中使用,您需要使用实际的类名。
在您的代码中,您现在可以在需要的地方使用该包:
let storyBoard = UIStoryboard(name: "SDK",
bundle: SchedJoulesSDK.resourceBundle)
Run Code Online (Sandbox Code Playgroud)
你可以使用像...
s.resource = "icon.png" //for single file
Run Code Online (Sandbox Code Playgroud)
或者
s.resources = "Resources/*.png" //for png file
Run Code Online (Sandbox Code Playgroud)
或者
s.resources = "Resources/**/*.{png,storyboard}" //for storyboard and png files
Run Code Online (Sandbox Code Playgroud)
或者
s.resource_bundles = {
"<ResourceBundleName>" => ["path/to/resources/*/**"]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8115 次 |
| 最近记录: |