Impossible to load an image in xcassets on bundle - ios

I need to include images in a static library.
I created a bundle and inserted in my images, the problem is that it seems to work if I include the images directly in the bundle, but stops working if I put in a xcassets file.
I followed many guides and searched for a solution on this site.
The most popular solution is to insert this line of code:
[UIImage imageNamed:#"MyBundle.bundle/imageName"]
but it seems not work for me
any ideas?

There are two ways to solve this,
If your app is still supporting iOs 7, you can use this category:
https://gist.github.com/serluca/e4f6a47ffbc19fccc63e
Otherwise, starting from iOs 8 Apple added a way to do this using:
+ imageNamed:inBundle:compatibleWithTraitCollection: defined here

Running the same problem. Looks like inline bundle support is broken for XCAssets in the 1-parameter imageNamed method. There's a workaround though using imageNamed:inBundle:compatibleWithTraitCollection: Be careful, this is iOS8 only !!
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"static_lib_bundle_name" ofType:#"bundle"]];
UIImage *image = [UIImage imageNamed:#"image_in_the_xcassets_you_want" inBundle:bundle compatibleWithTraitCollection:nil];
NOTE : traitCollection is set to nil to pass the main screen traits as per apple docs (i don't quite get what it means though, if anyone knows please comment!).

For Swift 2.1:
let bundle = pathToBundle // define for your app or framework
if let image = UIImage(named: "drop_arrow", inBundle: bundle, compatibleWithTraitCollection: nil) {
// process image
}

Our images are placed in Images.xcassets and we had a problem with loading images in an IBDesignable. The following code did the job for the preview in Interface builder and the app as well:
NSBundle* bundle = [NSBundle bundleForClass:[self class]];
UIImage* image = [UIImage imageNamed:#"image.jpg" inBundle:bundle compatibleWithTraitCollection:nil];

Related

iOS App Issue - Can't access image from image asset catalog

I'm new to iOS development, so apologies for advance. I know this has been covered earlier but I can't seem to find anything that helps with my issue.
Its a fairly simple but annoying issue.
I have a image in assets with a file name of hollwood.png but a xcode name, "hollywood" (no png).
I am trying to set a UIImageView to display it.
So in ViewDidLoad I have the following: (imageContainer is the UIImageView IBOutlet)
- (void)viewDidLoad {
super viewDidLoad];
self.model = [Model sharedModel];
self.imageContainer.image = [UIImage imageNamed:#"hollywood"];
}
I can not get it to display the image from Assets.
I know the UIImageView outlet works correctly because I can have the app choose a photo from gallery and set the photo to UIImageView.
I'm having a very difficult time figuring out how to load the image I saved in the assets catalog into UIImageView.
I just had this issue. I had dragged the image and for some reason Xcode added a weird "Design" locale and I couldn't load the image using UIImage(named: ). I don't know if this is your case, but you can try right clicking on the image in the Asset Catalog, "Show in Finder", opening the folder and checking the "Contents.json" file. Each image there should only have the keys "idiom", "filename" and "scale".
Make sure your image is added in Compile Sources
AppTarget->Build Phases-> Compile Sources
If not try to add that and check.

How to store images and refere to it for my iOS interface?

I'm using XCode 6.
Let's say I have a Food model containing a (UIImage *)image property. I would like to display all my foods displaying images for my interface.
I have already the pictures for the foods (they are not in the Photo Library of the device but on my computer).
1) Where to put these image files (beet.png, banana.png etc... for example) in Xcode ? (is there a dedicated folder ?)
2) How to refere to this image file ? Example in my Food class, self.image = ?
Thanks a lot !
You can just drag and drop image files to your project while xcode is open.
make sure you use copy items if needed option, it is less hassle.
once you clikc finish for your files, you will see your files on bundle.
then all you need to do is call
[UIImage imageNamed:#"imageInBundle.png"];
imageNamed: will search your main bundle
or long way
NSBundle* bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle]URLForResource:#"YourBundle" withExtension:#"bundle"]];
NSString *imagePath = [bundle pathForResource:#"imageInBundle" ofType:#"png"];
UIImage* image = [UIImage imageWithContentsOfFile:imagePath];
1) you can create new group inside your project in XCode and drag images to it. Check in build phases, in Copy Bundle Resources to make sure they'll be copyed in final app. 2) you refer image using imageWithName. You can use UIImageView for easier management and set this image your imageWithName. Otherwise you can implement directly images in your xib. Anyway how do you want to use images? In a table, in a collection, in a detail view? Depends on you how you want to display them and how you manage to make things work.

Getting launch image from XCAssets using imageWithContentsOfFile:

I'm attempting to load images from my LaunchImage image set in a .xcassets file, but I don't want do use imageNamed:, as it wastes memory and the image only needs to be displayed for a couple of seconds during initial launch.
I have tried multiple approaches to this, but so far I have only been able to load them using imageNamed:.
This works:
[UIImage imageNamed:#"LaunchImage-700-568h.png"]
This doesn't work (returns null):
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"LaunchImage-700-568h" ofType:#"png"]]
Is there any way to do this without adding the resources explicitly to the target (aside from the assets file)? Thanks!
Looks like the answer to your question is no.
According to XCAssets documentation.
Each set in an asset catalog has a name. You can use that name to programmatically load any individual image contained in the set. To load an image, call the platform specific class method, passing in the name of the set that contains the image. The OS will load the image from the set that is most appropriate for the current scale factor. The platform method for iOS is imageNamed:. For OS X the platform method is imageNamed:
So we must use [UIImage imageNamed:] method to load images from XCAssets catalog on iOS.
See similar question and answers here.

Can't load images from bundle into storyboard

I've been working on a library that will be used across multiple applications. This library also includes resources like a storyboard and many images. I recently made this library into a .framework using the iOS Framework tutorial found on Github.
When I was first working on this library, it was in the form of an app. When I got most of the coding done, I made it into a framework. However, this is where my problem began.
I am able to present the storyboard (Engine.bundle/Platform.storyboardc), and the first screen shows which has a background image which loads. However, once I get to all of the other screens in this storyboard, the images on those screens don't load. What's weird is that the first screen image loads through the storyboard without having to set it in the code. All the other images from the storyboard don't load, yet they are all contained in the same bundle as the first image.
One of the next screen contains credit card images, which do not load. And on the screen after that, more credit card images don't load. However, once I set the images through the .m file, they load from the bundle and show on the screen. Yet when I use this same code on every other screen that doesn't show their respective images, the code doesn't work. Here's the code I'm using to load their respective images:
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"Engine" withExtension:#"bundle"]];
NSString *filePath = [bundle pathForResource:#"front" ofType: #"png"];
backgroundImageView.image = [UIImage imageWithContentsOfFile:filePath];
Whenever the screens that don't have images loaded are presented, the following is logged to the console:
Could not load the "visa.png" image referenced from a nib in the bundle with identifier "com.example.app"
Could not load the "mastercard.png" image referenced from a nib in the bundle with identifier "com.example.app"
... and so on and so forth for each image.
And it even shows on the second credit card image screen... the screen where the images actually load. Yet, it doesn't show on the very first screen presented where the image loads.
My bundle is structured like so:
Engine.bundle/
Platform.storyboardc
front.png
visa.png
amex.png
... so on and so forth.
My question is why don't the images load? And why do some load? front.png loads, and on only one screen do the credit card images show. Yet when I use the same code to load the images on to other screens, the code doesn't work.
Sorry if this post is long... it's a lot of detail. I've just been really trying to figure this out. If I didn't explain something right, please let me know. Thanks.
Okay, it sounds like you need to set the bundle identifier for your Engine bundle.
Use something like "com.IAmSoAwesome.engine"
Then, instead of using:
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"Engine" withExtension:#"bundle"]];
You can use:
NSBundle *bundle = [NSBundle bundleWithIdentifier: #"com.IAmSoAwesome.engine"];

UIImage imageNamed returns nil

I am pretty new to iOS and Xcode.
I tried to load an image with
[UIImage imageNamed:#"imageName.png/jpg and so on"];
but it only returns nil. The image should be in my project bundle, considering the fact that I can choose it from drag and drop menus in the InterfaceBuilder and it was added to Xcode via the "Add files to "projectname"..." menu.
It makes no difference whether I use .png or .jpg images, the result stays the same: they work via IB but not if I try to run the imageNamed method myself.
There are only a few reasons why an image would come back nil with imageNamed:
The image is not in your bundle. Make sure the image is actually in your project. Make sure the target is checked by clicking on the file and selecting the target it belongs to.
You have the image name spelled incorrectly or a problem with the extension.
You are using a retina display but do not have an #2x image. Try changing your simulator to retina and see if it shows up.
If you are using an asset catalog make sure you have the correct devices selected in the attribute inspector.
Some tips:
If you are testing using simulator delete the app off of your simulator and clean your project, then re-run. If it still shows up it should show up on your phone (if it doesn't it's probably an issue with the case of the filename or the #2x version).
If you are testing on your phone and it doesn't show up, make sure you are using the same version of the simulator (if you have an iPhone 4/4s make sure to use the 4/4s simulator with retina).
One last thing according to this post: JPG image doesn't load with UIImage imageNamed There is some issue with certain JPG types working with imageNamed and no extension. IMO, you should be using PNGs anyway since iOS compresses them for you, unless you just have to use JPG.
Re Mike Weller's comment. The checkbox is ....
If you verified all of the above and are finding that your UIImage(named: "myImage") returns nil from code inside of a dynamic framework you are building, then you have to change the code to:
UIImage(named: "myImage", in: Bundle(identifier: "com.myframework.name"), compatibleWith: nil)
This should retrieve the asset from CXAssets correctly.
In my case, the PNG was malformed.
For some reason Xcode preview shown it correctly, but when I tried loading it with UIImage, it returned nil.
I just had this issue for jpg files named on disk "file.jpg"
I was trying to load without the extension, just #"file". While this works fine for pngs, it does not for jpg. Once I used #"file.jpg", it worked!
Swift 5
If you get UIImage nil in dynamic framework, you should set image with bundle identifier.
You can create an extension to Bundle like this;
Create an extension;
extension Bundle {
public static let myFramework = Bundle(identifier: "com.myFramework.bundle")
}
Then you can use like this;
UIImage(named: "myImageName", in: Bundle.myFramework, compatibleWith: nil)
Or
You can use like this;
UIImage(named: "myImageName", in: Bundle(for: type(of: self)), compatibleWith: nil)
I think the first one is more useful because it's more readable than second one.
Try re-exporting your image.
I had a similar problem, UIImage imageNamed was returning nil and none of these answers fixed my problem.
I found out that it was actually something wrong with the png file. I opened the file in GIMP image editor, saved it as a new file, exported it again as png and magically it started working.
I didn't change anything in code at all so there was definitely something wrong with the actual image file.
try
[UIImage imageNamed:#"imageName.png"];
instead (with an extension)
I had the same problem: #"photo.jpg" resulted in 'nil' UIImage.
Changing to the "actual" filespec, #"photo.JPG" works fine!
I hadn't realized there was case-sensitivity there! VERY non-intuitive.
i had a similar issue, finally the cleanup fixed it: the image showed up in the simulator, but id did not show up when running the app on the iPhone.
What I did:
1) deleted the app from the iPhone
2) performed Product/Clean
after that the bug was fixed and the image showed up!
Try to use UIImage(contentsOfFile:) instead of imageNamed. It worked for me with downloaded images.
Check that file has no space at the end.
The name like name #2x.png will fail loading, but name#2x.png is fine
Does the image work on the simulator but not on the device?
If so, in this scenario it is always to do with the case of the name. The device requires exact case and the simulator is not so fussy if I remember correctly.
e.g. for an image named image.png
[UIImage imageNamed:#"Image"];
would work on the simulator but not on the device...
Make sure you have the image for the DEVICE you are using in your .xcassets file. An image flagged for iPad won't show up on the phone (or the simulated phone).
In addition to #Inturbidus's answer:
For those who came here working on Application Extensions:
The image you are working with should belongs to both targets - hosted app and extension.
In other case you'll always getting nil trying to access it from within the extension's code.
For Xcode 6.4, click on Images.xcassets and check whether there are entries for each image that you called. You may right-click on the image and select "Show in Finder" to check if the images are the correct ones added.
Make sure the Attributes Inspector name field of the image matches exactly the name you're using. In my case the image was part of a folder and so the image name was "folder/name". Using this long name solved the problem. XCode 7.3.1
In my case, using a name with accented characters proved to be a poor idea. I changed Astéroïdes to Asteroids and it worked fine.
In my case problem was with image name in asset catalog.
For example if you have image with name "TEst" and change name to "Test", changes won't be indexed. If your teammate will pull commit with this changes, image in his asset catalog will have previous name "TEst".
Very small chance to catch this situation but it's possible.
I had multiple .xcassets in my projects and 2 had duplicate name of images. So it was not loading the image in my case.

Resources