Load image from Bundle I get a nil - ios

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]

Related

bundleForClass not returning framework bundle iOS

Using bundleForClass for retrieving bundle of framework where i have defined a class.
NSBundle *bundle = [NSBundle **bundleForClass**: [self class]]; // Class in framework
NSString *readtext = [bundle **pathForResource**:#"Test" ofType:#"rtf"];
Getting appbundle of application(Where i am using my framework) instead of framework bundle.
How to get framework bundle path and read the framework resources.
You can load NSBundle with Bundle Identifier of framework:
[NSBundle bundleWithIdentifier:YOUR_FRAMEWORK_BUNDLE_IDENTIFIRE];
If the framework has a resources bundle in it, then you can access the resources by:
NSBundle *bundle = [NSBundle bundleForClass:[YOUR_CLASS_NAME class]];
NSURL *url = [bundle URLForResource:RESOURCE_BUNDLE_NAME withExtension:#"bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithURL:url];
UIImage* infoImage = [UIImage imageWithContentsOfFile:[resourceBundle pathForResource:#"info" ofType:#"png"]];

Retrieving image from asset folder - iOS

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

Access Resources in pod

I would like to include image assets in a cocoapod library, but I'm having trouble accessing them. I've read these resources for help:
Cocoapods Resources
Cocoapods Resource Bundles
Mokacoding Resource Bundles
David Potter Resource Bundles
However, none point me in the direction of accessing the resources. I've tried the following:
[UIImage imageWithData:[NSData dataWithContentsOfURL:[(NSBundle *)[NSBundle bundleWithIdentifier:#"Assets"] URLForResource:#"my-image#2x" withExtension:#"png"]]]
[UIImage imageWithData:[NSData dataWithContentsOfURL:[(NSBundle *)[NSBundle bundleWithIdentifier:#"Assets"] URLForResource:#"my-image" withExtension:#"png"]]]
[UIImage imageWithData:[NSData dataWithContentsOfURL:[(NSBundle *)[NSBundle bundleWithIdentifier:#"Assets.bundle"] URLForResource:#"my-image" withExtension:#"png"]]]
[UIImage imageWithData:[NSData dataWithContentsOfURL:[(NSBundle *)[NSBundle mainBundle] URLForResource:#"my-image" withExtension:#"png"]]]
[[UIImage imageWithData:[NSData dataWithContentsOfURL:[(NSBundle *)[NSBundle mainBundle] URLForResource:#"my-image#2x" withExtension:#"png"]]]
[UIImage imageNamed:#"my-asset"]
[UIImage imageNamed:#"my-asset#2x.png"]
But none of them work.
I've setup my podspec with these alternatives and neither work with the above:
s.resources = ['Pod/Assets/*.{png, jpg}', 'Pod/Assets/**/*.{png, jpg}']
s.resource_bundles = {
'Assets' => ['Pod/Assets/*.{png, jpg}', 'Pod/Assets/**/*.{png, jpg}']
}
The resources show up under 'Development Pods/My App/Resources' after a pod update, but I cannot access them for the life of me. There aren't any bundles and there isn't anything named 'Assets'.
Any help or guidance would be appreciated.
It depends on the version of Cocoapods that you use. With older versions of cocoapods, you could get away with using [NSBundle mainBundle]:pathForResource:ofType:
NSString *bundlePath = [[NSBundle mainBundle]
pathForResource:#"MyResourceBundle" ofType:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
If you are using newer Cocoapods and using spec.resource_bundles instead of spec.resources in your podspec file, you have to avoid mainBundle and replace it with NSBundle bundleForClass, which "Returns the NSBundle object with which the specified class is associated"
Example:
NSString *bundlePath = [[NSBundle bundleForClass:[MyFrameworkClass class]]
pathForResource:#"MyResourceBundle" ofType:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
This tripped me up too. Maybe I'm misunderstanding +bundleWithIdentifier:, but I don't think you can use it to get to a resource bundle inside of your iOS app bundle. See the "Getting Bundles by Identifier" section of the bundle docs for more details.
What does work is +bundleWithPath:, e.g.:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"MyResourceBundle" ofType:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
I wrapped that inside of a dispatch_once block and call it any time I need to access this bundle.
I'm using the s.resource_bundles syntax in my podspec as well and this works fine with it.

Adding unit testing target to existing Xcode project, can't find resource in bundle

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];

Accessing images from nsbundle

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"];

Resources