I'm writing a class to build a cocoapods and I want to get the image I placed in Assets.xcassets. The problem is always getting nil image. Are there anything I miss?
Here is my podspec file :
Here is the directory stucture :
This is what I try to load the Image:
#import "HaloImage.h"
#implementation HaloImage
- (void)showImage {
NSBundle * bundle = [NSBundle bundleForClass:self];
NSURL * bundleUrl = [bundle URLForResource:#"Assets" withExtension:#"bundle"];
self.image = [UIImage imageNamed:bundleUrl.absoluteString];
}
#end
You can access image from Assets.xcassets by this. Give it a try
UIImage *image = [UIImage imageNamed:#"image name without extension"];
you can use image from asset or main bundle only by name (png file)
self.image = [UIImage imageNamed:#"name_of_image"];
Can you please try below code :
#implementation HaloImage
- (void)showImage {
NSBundle * bundle = [NSBundle bundleForClass:self];
NSURL * bundleUrl = [bundle pathForResource:#"Assets" withExtension:#"bundle"];
self.image = [UIImage imageNamed:bundleUrl.absoluteString];
}
#end
Related
When I try to get a UIImage from my project using NSBundle I get a nil value.
I have the image into .xcassests
This is my code to load image from bundle.
- (UIImage *)imageRating:(NSString *)imageName
{
return [UIImage imageNamed:imageName inBundle:[MyClass bundle] compatibleWithTraitCollection:nil];
}
And this is the Bundle Method.
+ (NSBundle *)bundle
{
return [NSBundle bundleForClass:[self class]];
}
Any idea why I get a nil value.
I guess the resource path is wrong.
Your image is placed in .xcassests and is finally packaged in the .app file, which is commonly used in main bundle.
If your project structure contains a framework, just if you get the current bundle in the framwork, then the path is not the resource under the main bundle, but the bundle resource of the framwork.
Because I don't know your project structure, the next step is to know the path to print the bundle and compare it with the main bundle path.
- (UIImage *)imageRating:(NSString *)imageName
{
NSBundle *bundle = [MyClass bundle];
NSBundle *mainBundle = [NSBundle mainBundle];
NSLog(#"bundle: %#\n main bundle: %#",imageBundle);
return [UIImage imageNamed:imageName inBundle:[MyClass bundle] compatibleWithTraitCollection:nil];
}
If the paths are different, there are two ways.
Put resources in the form of bundles in famework
Change [MyClass bundle] to [NSBundle mainBundle]
i have implemented image picker controller delegate:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]) {
UIImage *anImage = [info objectForKey:UIImagePickerControllerOriginalImage];
//i know i can get image name from info key.
if(self.block) self.block(YES, anImage, nil);
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
i am using UIImageView+PlayGIF category to show gif images (loader in my app) from main resource bundle successfully.Some thing like:
NSData *gifData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"loading_image.gif" ofType:nil]];
CGRect bnd = view.bounds;
loader.gifView = [[YFGIFImageView alloc] initWithFrame:CGRectMake(bnd.size.width/2-60, bnd.size.height/2-70, 120, 120)];
loader.gifView.backgroundColor = [UIColor clearColor];
loader.gifView.gifData = gifData;
Questions:
So how can i export photo library gif to document directory as (whatevername.gif), and use above category to show gif.
Or can i get direct nsdata from photolibrary and use above category to show gif.(i prefer this).
I have not tried with UIWebView, can i show gif on UIWebView.
Thanks
set property of imageView.
#property (strong, nonatomic) IBOutlet UIImageView *YFGIFImageView;
Download the Class of GIF imageLoad with UIImageView
GIFImageLoad
Now load Data from NSBundle.
NSURL *url = [[NSBundle mainBundle] URLForResource:#"loading_image" withExtension:#"gif"];
Load image with animatedImageWithAnimatedGIFData as below.
self.YFGIFImageView.image = [UIImage animatedImageWithAnimatedGIFData:[NSData dataWithContentsOfURL:url]];
OR
Load image with URL animatedImageWithAnimatedGIFURL as below.
self.YFGIFImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
OR
Load image with GIFURL animatedImageWithAnimatedGIFURL as below.
self.YFGIFImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
I've added a new target of type Cocoa Touch Unit Testing Bundle to an existing iOS project, a test case and some jpg files that I need for testing.
I'm trying to load the image from the test bundle using the following code :
#implementation PhotosViewController_Tests : XCTestCase
-(void)addImage:(NSString *)imageName
{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *imagePath = [bundle pathForResource:imageName ofType:#"jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
...
}
However, bundle returns the main bundle, not the test bundle and imagePath and image are nil.
I can successfully load images from the main bundle (using this code), but I don't understand why bundleForClass returns the mainBundle instead of the unit test one.
I printed the [NSBundle allBundles] and I get the main bundle as well :
"NSBundle </var/mobile/Applications/uuid/Photos Light.app> (loaded)"
I guess it has something to do with adding the unit testing target after the project was created, but I can't figure what else to do to load images from the test bundle.
Try adding an extension to NSBundle in your test target that looks something like this...
#implementation NSBundle (MyAppTests)
+ (NSBundle *)testBundle {
// return the bundle which contains our test code
return [NSBundle bundleWithIdentifier:#"com.mycompany.MyAppTests"];
}
#end
Then when you need to load resources from your test bundle, import that category and then your code looks like...
NSString *imagePath = [[NSBundle testBundle] pathForResource:imageName ofType:#"jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
I have a framework which is trying to access xib's and images from a bundle. I am able to access the xib fine but unable to load the images in UIImageView. I even check if the file exists and the console output is yes...
Any idea how to load the image?
Code to load xib in the framework viewcontroller file
self = [super initWithNibName:#"ViewController_iPad" bundle:[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"MyBundle" ofType:#"bundle"]]];
Code to load images
- (void) loadImage
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"MyBundle.bundle/test" ofType:#"png"];
BOOL present = NO;
present = [[NSFileManager defaultManager] fileExistsAtPath:path];
if (present)
{
NSLog(#"MyBundle.bundle/test exists");
}
else
{
NSLog(#"MyBundle.bundle/test does not exists");
}
self.testImageView.image = [UIImage imageNamed:path];
self.testImageView2.image = [UIImage imageWithContentsOfFile:path];
}
MyTestHarnessApp[11671:c07] MyBundle.bundle/test exists
When you use imageNamed: you must pass just a simple filename and the image must exist in the root of the app's resource bundle.
Your image is not in the root of the resource bundle, it is in a subfolder.
Since you have obtained the image's full path in the path variable, you must use the UIImage imageWithContentsOfFile: method:
self.testImageView.image = [UIImage imageWithContentsOfFile:path];
If +[UIImage imageNamed:] isn't resolving the path correctly, you could always use:
self.testImageView.image = [UIImage imageWithContentsOfFile: path];
You can just use the following:
self.testImageView.image = [UIImage imageNamed:#"MyBundle.bundle/test.png"];
But it seems that if you put the XIB in the bundle too, the interface will be relative to the bundle.
self.testImageView.image = [UIImage imageNamed:#"test.png"]
try going step by step.
First get the path to the bundle within your main bundle:
NSString *myBundlePath=[[NSBundle mainBundle] pathForResource:MyBundle ofType:#"bundle"];
Check to see if there is anything in the bundle. This is more for double checking. Once it is working you can choose to omit this code. But it is always a good idea to double check things.
NSBundle *imageBundle=[NSBundle bundleWithPath: myBundlePath];
NSArray *allImageURLs=[imageBundle URLsForResourcesWithExtension:#"png" subdirectory:nil];
NSLog(#"imageURLS: %#",allImageURLS);
Since you already have the bundle path add the image name to the path. Or you can just pull it from the list of urls that you already have in the above code.
NSString *myImagePath=[myBundlePath stringByAppendingPathComponent:#"test.png"];
NSLog(#"myImagePath=%#",myImagePath);
Then, since you have the full path, load the image
UIImage *testImage = [UIImage imageWithContentsOfFile:backgroundImagePath];
Code taken from shipping app.
Good Luck
Tim
If the images are already in the main bundle just use the image name: test.png or simply test
[UIImage imageNamed:#"test.png"];
[UIImage imageNamed:#"test"];
I added to my project a .bundle folder filled with some images.
Is it correct refer to this image directly writing something like ?:
[UIImage imageNamed:#"imageInBundle.png"];
Which is the best method to access and use these images ?
That is correct, imageNamed: will search your main bundle. Images in your project, even if they are in different groups in your Project Navigator will be in your main bundle and can be accessed directly by name.
If that does not work, try
[UIImage imageNamed:#"yourbundlefile.bundle/imageInBundle.png"];
Best
Apple has thankfully provided a proper API for this from iOS 8 onwards, imageNamed:inBundle:compatibleWithTraitCollection:.
It's used like so:
[UIImage imageNamed:#"image-name"
inBundle:[NSBundle bundleForClass:self.class]
compatibleWithTraitCollection:nil]
or in swift:
let image = UIImage(named: "image-name",
inBundle: NSBundle(forClass: type(of:self)),
compatibleWithTraitCollection: nil)
or in swift 5:
let image = UIImage(named: "image-name",
in: Bundle(for: type(of:self)),
compatibleWith: nil)
1) If you are working with bundles go to bundle target and set COMBINE_HIDPI_IMAGES to NO.
In another case the image will be converted to tiff format.
2) try this code:
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"YourBundle" withExtension:#"bundle"]];
NSString *imagePath = [bundle pathForResource:#"imageInBundle" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
Swift 3
let myImage = UIImage(named: "nameOfImage", in: Bundle(for: type(of: self)), compatibleWith: nil)
I can't get current bundle so i do this:
Bundle(for: type(of: self))
This Method returns image anywhere in the xcode project:=>
+(UIImage*)returnImageFromResourceBundle:(NSString*)nameOfImage
{
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"Resource" ofType:#"bundle"];
NSString *imageString = [[NSBundle bundleWithPath:bundlePath] pathForResource:nameOfImage ofType:#"png"];
UIImage *retrievedImage = [[UIImage alloc] initWithContentsOfFile: imageString];
return retrievedImage;
}
Swift version
#AndrewMackenzie's answer didn't work me. This is what did work
let image = UIImage(named: "imageInBundle.png")
imageView.image = image
My full answer is here.
Since I had to figure this out for Swift, thought I would add also....
if let imagePath = NSBundle.mainBundle().pathForImageResource("TestImage.png")
{
imageView.image = NSImage(contentsOfFile: imagePath)
}
Where I have TestImage.png in the Supporting Files group inside my bundle.
For Swift 3
let prettyImage = UIImage(named: "prettyImage",
in: Bundle(for: self),
compatibleWith: nil)
A quick way to do it if you are going to use it a couple of times in the same viewController:
Get the image anywhere in the same class as the method below:
// this fetches the image from: MyBundle.bundle/folder/to/images/myImage.png
UIImage *myImage = [self imageFromBundle:#"MyBundle" withPath:#"folder/to/images/myImage.png"];
Method that fetches the image:
- (UIImage *)imageFromBundle:(NSString *)bundleName withPath:(NSString *)imageName
{
NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:bundleName withExtension:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithURL:bundleURL];
NSString *imagePath = [bundle pathForResource:imageName ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
return image;
}
Or simply call it straight out of the bundle:
UIImage *myImage = [UIImage imageNamed:#"MyBundle.bundle/folder/to/images/myImage.png"];
If you are building a framework and you would like all instances of UIImage(named: "image") to always use your custom bundle, you can make an extension like below that will override it
// Swift 5
extension UIImage {
convenience init?(named: String) {
self.init(named: named, in: <#Your Bundle#>, compatibleWith: nil)
}
}
This is worked for me in Swift 5
// Empty UIImage array to store the images in it.
var icons = [UIImage]()
let fileManager = FileManager.default
let bundleURL = Bundle.main.bundleURL
let assetURL = bundleURL.appendingPathComponent("MyBundle.bundle") // Bundle URL
do {
let contents = try fileManager.contentsOfDirectory(at: assetURL,
includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey],
options: .skipsHiddenFiles)
for item in contents { // item is the URL of everything in MyBundle imgs or otherwise.
let image = UIImage(contentsOfFile: item.path) // Initializing an image
icons.append(image!) // Adding the image to the icons array
}
}
catch let error as NSError {
print(error)
}
I found this question when trying to solve loading images from Swift Package, so if anybode else is struggling with that as well here's how I solved it:
let image = UIImage(named: "imageName", in: Bundle.module, compatibleWith: nil)