How to load resource in cocoapods resource_bundle

给你一囗甜甜゛ 提交于 2019-11-26 17:44:05

问题


I have struggled a lot to how to load resource in cocoapods resource_bundle.

The following is what i put in the .podspecs file.

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

This is what I am trying to do from the main project.

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

I did see the picture in the XDCoreLib.bundle, but it return a nil.


回答1:


I struggled with a similar issue for a while. The resource bundle for a pod is actually a separate bundle from where your code lives. Try the following:

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)



回答2:


I don't think any of the other answers have described the relationship to the Podspec. The bundle URL uses the name of the pod and then .bundle to find the resource bundle. This approach works with asset catalogs for accessing pod images both inside and outside of the 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];

Swift

See this answer.




回答3:


This will work

In .podspec add s.resources in addition to s.resource_bundles (pod install afterwards)

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

Then in your code, its as easy as:

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

Note: You may need to run pod install after updating the .podspec to have the changes to your Xcode proj




回答4:


You can just check the ID of the Bundle by selecting the Pods project, selecting the desired target, and making sure you're on the General tab.

Then in code you can load say an image in that Pod like so:

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



回答5:


Can create an extension to access the framework bundle easier in your framework source code

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)
   }
}



回答6:


Interesting thing is when you need to do it in the source files that are also in the cocoapod library I faced it when used a xib and plist files in my pod.

That was solved in the next way. Example of loading a xib file:

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



回答7:


Just for the record: I wanted to open a NIB from a Category stored in a CocoaPods library. Of course [self classForCoder] gave UIKit back (because of the Category), so the above methods didn't work.

I resolved the issue using some hardcoded paths:

NSURL *bundleURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"Frameworks/MyCocoaPodLibraryName.framework"];
NSBundle *podBundle = [NSBundle bundleWithURL:bundleURL];

CustomView *customView = [[podBundle loadNibNamed:@"CustomView" owner:self options:nil] firstObject];



回答8:


It seems like for some reason **/*.{extensions} pattern is required for this to work I ended up creating my podspec like this

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

even though my actual path is Pod/Resources/.storyboard*

And then to find my bundle I used @Jhelzer's answer although any way to get bundle e.g. by class or URL or bundleID will work after above setup.

You can also have a look into this answer for more refrences.



来源:https://stackoverflow.com/questions/35692265/how-to-load-resource-in-cocoapods-resource-bundle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!