How can I load an image from Assets.car (compiled version of xcassets) within an NSBundle? (without using CocoaPods)
Asked Answered
S

3

6

We're getting these kind of error messages:

Could not load the "iconStatus" image referenced from a nib in the bundle with identifier "com.company.OurResourceBundle".

Basically, we put a bunch of images in the xcassets folder ( which works for non-bundle loaded cases ). The xcassets and nib files are packed into a resource bundle.

When the app launches,

  1. uiimageview in the nib file cannot load any images with the above error message.
  2. [UIImage imageNamed:@"OurResourceBundle.bundle/iconStatus"] returns nil

The question is related to "How can I load an image from Assets.car (compiled version of xcassets) within an NSBundle?", but we don't use CocoaPods.

Syncopated answered 4/4, 2014 at 17:49 Comment(7)
The answer is going to be essentially the same as for the question you reference. imageNamed: only loads from the main bundle, so you'll have to create a category that does all the right things to load your images from a different bundle.Phineas
I tried and it doesn't work. There is something special for xcassets being BundledSyncopated
How do you get the compiled *.car file? From my short experience all *.xcassets images just get copied (with a proper name) flat inside the *.app directory.Edmondedmonda
I added the .xcassets (a folder in the harddrive) to the "Copy Bundle Resource" section for the Bundle target of the static library. Xcode build the .car file automatically in the bundle.Syncopated
This link might help : #10999044 Have you try something like:- [UIImage imageNamed:@"iconStatus"]; or [UIImage imageNamed:@"iconStatus.png"];Juratory
I didn't know about the a compiled xcasset. In my experience images just get properly named and copied to the root of the main bundle (the root .app folder).Edmondedmonda
If you set your project's iOS Deployment Target to iOS versions earlier than 7.0, the xcassets file will not be compiled to .car. I tested it and if it doesn't hurt for you to change your iOS Deployment Target to iOS 6, this might be a solution.Wangle
A
9

In iOS 7 it is not possible to load images from any .car file aside from the one that Xcode compiles into the main bundle. This was confirmed by an Apple Developer at https://devforums.apple.com/message/968859#968859:

Unfortunately it is not possible to load images from any car file aside from the one that Xcode compiles into your main bundle, as +imageNamed: does not accept a bundle parameter, which is what is needed to do so (and even then it would only be able to open a single asset catalog in a single bundle).

In iOS 8 there is a new method that appears to do what you want:

+ (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle
    compatibleWithTraitCollection:(UITraitCollection *)traitCollection
Ashil answered 10/10, 2014 at 23:35 Comment(5)
It doesn't work for me. Seems like that method only reads the image directly under the bundle, but not the image in xcassets inside that bundle :(Transalpine
I cant find solution for this anywhere, should i just make all images as separate file from xcasset?Drip
That is what I ended up doing. It is a pain not being able to use .xcasset files in bundles, but it works fine if you just include your images in the bundle the old fashioned way.Ashil
But then i will miss the @2x and @3x feature is that right? If i do that i should just remove @1x and @2x and keep the largest one? In IOS8 it's possible but my framework is suppose to support from ios 7 thats whyDrip
You can provide '@2x' and '@3x' versions of the images. The only restriction is that they need to be named according to the naming conventions and then they will be used appropriately. For example: image.png, [email protected], and [email protected]. (No '@1x' for the standard resolution image)Ashil
S
0

you have to define your bundle

  imageView.image = UIImage(named: "iconName", in: Bundle.main, compatibleWith: nil)
Spanish answered 21/4, 2020 at 14:10 Comment(0)
W
-1

I suspect if your image assets folder gets compressed into a .car file then NSBundle will know how to search for assets inside of it. Try creating a new bundle from your resources bundle. Then ask that bundle for the path of your image. Finally create an image from that path. This is sort of the approach we take when bundling image assets and localized strings with our static libraries. Our version is a little more involved as it takes care of things like @2x and ~ipad images automatically but this is the gist of it.

    NSBundle *myBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"your bundle" ofType:@"bundle"]];
    NSString *filePath = [myBundle pathForResource:@"icon" ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:filePath];
Well answered 5/5, 2014 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.