【问题标题】:How to load resource in cocoapods resource_bundle如何在 cocoapods resource_bundle 中加载资源
【发布时间】:2016-02-29 05:00:40
【问题描述】:

我为如何在 cocoapods resource_bundle 中加载资源做了很多努力。

以下是我放在.podspecs 文件中的内容。

s.source_files = 'XDCoreLib/Pod/Classes/**/*'
s.resource_bundles = {
'XDCoreLib' => ['XDCoreLib/Pod/Resources/**/*.{png,storyboard}']
}

这就是我试图从主项目中做的事情。

let bundle = NSBundle(forClass: XDWebViewController.self)
let image = UIImage(named: "ic_arrow_back", inBundle: bundle, compatibleWithTraitCollection: nil)
print(image)

我确实在XDCoreLib.bundle 中看到了图片,但它返回 nil。

【问题讨论】:

  • 不要那样做,只需将这些资源复制到您的项目中,因为 pod 中的这些资源可以随时更新/删除。
  • 这个pod是我们自己维护的。项目规模越来越大,我们想把各个模块分开。

标签: ios cocoapods


【解决方案1】:

我曾为类似的问题苦苦挣扎了一段时间。 pod 的资源包实际上是与您的代码所在的位置分开的包。请尝试以下操作:

斯威夫特 5

let frameworkBundle = Bundle(for: XDWebViewController.self)
let bundleURL = frameworkBundle.resourceURL?.appendingPathComponent("XDCoreLib.bundle")
let resourceBundle = Bundle(url: bundleURL!)

let image = UIImage(named: "ic_arrow_back", in: resourceBundle, compatibleWith: nil)
print(image)

-- 原始答案--

let frameworkBundle = NSBundle(forClass: XDWebViewController.self)
let bundleURL = frameworkBundle.resourceURL?.URLByAppendingPathComponent("XDCoreLib.bundle")
let resourceBundle = NSBundle(URL: bundleURL!)
let image = UIImage(named: "ic_arrow_back", inBundle: resourceBundle, compatibleWithTraitCollection: nil)
print(image)

【讨论】:

  • @Quaid 第一行中的 XDWebViewController.self 是什么
  • @Siddh XDWebViewController.self 应该是 pod 内的一个类。
  • 扩展 @MattRobinson 所说的内容,您可以将 XDWebViewController.self 替换为 pod 内的任何类。该行代码的目标是通过使用属于框架(pod)的任何类来识别框架包
  • @Quaid 我可以通过这种方式加载资源,但是当我在调试窗口中打印捆绑对象时出现一个问题,这个“NSBundle (尚未加载)”即将到来。这里的“尚未加载”是什么意思。
【解决方案2】:

我认为其他任何答案都没有描述与 Podspec 的关系。捆绑 URL 使用 pod 的名称,然后使用.bundle 来查找资源捆绑。这种方法适用于资产目录,用于访问 pod 内部和外部的 pod 图像。

Podspec

Pod::Spec.new do |s|
  s.name             = 'PodName'
  s.resource_bundles = {
    'ResourceBundleName' => ['path/to/resources/*/**']
  }
end

Objective-C

// grab bundle using `Class` in pod source (`self`, in this case)
NSBundle *bundle = [NSBundle bundleForClass:self.classForCoder];
NSURL *bundleURL = [[bundle resourceURL] URLByAppendingPathComponent:@"PodName.bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithURL:bundleURL];
UIImage *podImage = [UIImage imageNamed:@"image_name" inBundle:resourceBundle compatibleWithTraitCollection:nil];

斯威夫特

this answer

【讨论】:

    【解决方案3】:

    似乎出于某种原因需要 **/*.{extensions} 模式才能正常工作,我最终像这样创建了我的 podspec

    s.resource_bundle = { '<BundleName>' => 'Pod/Resources/**/*.storyboard' }
    s.resource = 'Pod/Resources/**/*.storyboard'
    

    即使我的实际路径是 Pod/Resources/.storyboard*

    然后找到我使用的捆绑包 @Jhelzer's answer 尽管可以通过任何方式获取捆绑包,例如通过类或 URL 或 bundleID 将在上述设置后工作。

    您还可以查看this answer 以获得更多参考。

    【讨论】:

      【解决方案4】:

      这会起作用

      .podspec 中添加s.resourcess.resource_bundles(之后是pod install

      s.resources = 'XDCoreLib/Pod/Resources/**/*.{png,storyboard}'
      

      然后在您的代码中,它就像:

      let image = UIImage(named: "image_name.png", in: Bundle(for: type(of: self)), compatibleWith: nil)
      

      注意:您可能需要在更新 .podspec 后运行 pod install 才能对您的 Xcode 项目进行更改

      【讨论】:

      • 应该是 s.resource = 'XDCoreLib/Pod/Resources/**/*.{png,storyboard}' 而不是 s.resources = ' XDCoreLib/Pod/Resources/**/*.{png,storyboard}'
      • 请注意,这仅在您的 cocoapod 不是静态框架时才有效。确保 s.static_framework 在 podspec 中应该为 false。对于静态框架,唯一的解决方案是使用单独的包。
      【解决方案5】:

      仅作记录:我想从存储在 CocoaPods 库中的类别中打开一个 NIB。当然[self classForCoder]UIKit 给回了(因为Category),所以上面的方法都不行。

      我使用一些硬编码路径解决了这个问题:

      NSURL *bundleURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"Frameworks/MyCocoaPodLibraryName.framework"];
      NSBundle *podBundle = [NSBundle bundleWithURL:bundleURL];
      
      CustomView *customView = [[podBundle loadNibNamed:@"CustomView" owner:self options:nil] firstObject];
      

      【讨论】:

        【解决方案6】:

        您可以通过选择 Pods 项目、选择所需的目标并确保您位于“常规”选项卡上来检查 Bundle 的 ID。

        然后在代码中,您可以像这样在该 ​​Pod 中加载一个图像:

        backgroundImageView.image = UIImage(named: "business_fellas", in: Bundle(identifier: "org.cocoapods.StandardLibrary3-0"), compatibleWith: nil)
        

        【讨论】:

        • 这在构建静态库时对我有用,但在构建框架时对我不起作用。这是因为框架和资源包都将具有相同的包标识符,Bundle() 返回的包将是框架包 (.framework) 和包含资源的资源包 (.bundle)。
        【解决方案7】:

        可以在您的框架源代码中创建扩展以更轻松地访问框架包

        extension Bundle {
           static func getResourcesBundle() -> Bundle? {
              let bundle = Bundle(for {your class}.self)
              guard let resourcesBundleUrl = bundle.resourceURL?.appendingPathComponent({bundle name}) else {
                 return nil
              }
              return Bundle(url: resourcesBundleUrl)
           }
        }
        

        【讨论】:

          【解决方案8】:

          有趣的是,当您需要在 cocoapod 库中的源文件中执行此操作时 在我的 pod 中使用 xib 和 plist 文件时,我遇到了它。

          下一个方法解决了。加载xib文件示例:

          let bundle = Bundle(for: self.classForCoder)
          let viewController = CocoapodViewController(nibName: "CocoapodViewController", bundle: bundle)
          

          【讨论】:

            【解决方案9】:
            import class Foundation.Bundle
            
            private class BundleFinder {}
            
            extension Foundation.Bundle {
                /// Returns the resource bundle associated with the current Swift module.
                static var module: Bundle = {
                    let bundleName = "ID3TagEditor_ID3TagEditorTests"
            
                    let candidates = [
                        // Bundle should be present here when the package is linked into an App.
                        Bundle.main.resourceURL,
            
                        // Bundle should be present here when the package is linked into a framework.
                        Bundle(for: BundleFinder.self).resourceURL,
            
                        // For command-line tools.
                        Bundle.main.bundleURL,
                    ]
            
                    for candidate in candidates {
                        let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
                        if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                            return bundle
                        }
                    }
                    fatalError("unable to find bundle named ID3TagEditor_ID3TagEditorTests")
                }()
            }
            

            发件人:https://www.fabrizioduroni.it/2020/10/19/swift-package-manager-resources/

            【讨论】:

              【解决方案10】:

              对我来说,以下工作有效,因为我使用的是静态 pod。

              
              s.resource_bundle = '<BundleName>' => 'Path to resources'
              s.resource = 'Path to resources'
              
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-01-03
                • 2015-07-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多