NSBundle -- finding resources within a bundle? - iphone

I created a directory MyDirectory inside a bundle myBundle. I then put an image myImage.png inside MyDirectory. But a call to
[myBundle pathForResource: #"myImage" ofType: #"png"]
does not find the image. What am I missing?
EDIT: To clarify, if the image is in the top level of the bundle, it finds it just fine.

First you must have added the image to the bundle. If you've did it, I guess you would have added folder references while you added the image to the project. If so, you should specify the folder hierarchy with the image name.
[myBundle pathForResource:#"MyDirectory/myImage" ofType:#"png"];
Edit: As Deepak commented below, there is even a better method pathForResource:ofType:inDirectory:
[myBundle pathForResource:#"myImage" ofType:#"png" inDirectory:#"MyDirectory"];

Did you add the image to your Xcode project (project.pbxproj)?

Related

How to get file path in iPhone app

I have a problem accessing my files in my app.
I am currently using
//Directly from TileMap example from WWDC2010
NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"Tiles"];
to access my tiles for my MKOverlay. This gives me this directory
/Users/xxxx/Library/Application Support/iPhone Simulator/4.2/Applications/9D62025C-C53B-472C-8309-xxxx/xxxx.app/Tiles
The x's is only for privacy reasons
I have my tiles in a folder called Tiles in the root of my application which is in Xcode in a group called Tiles which is in directly in the Resources group.
When I run my app, I get a simple error saying that it could not find my tiles at the generated directory (the one quote above) If I replace that piece of code and make it:
NSString *tileDirectory = #"/Users/xxxx/Documents/xxxx/Tiles";
Then my app works fine. This is obviously because it finds my tiles in its direct location on my Mac. This is fine for testing, but I need it to work on my iPhone/iPad.
This problem might be occurring due to:
The generated directory is incorrect.
The tile images aren't getting included in the builded .app file.
Either way, I have no clue of what to do to solve it.
How can I solve this problem?
[EDIT]
I changed that piece of code to:
NSString *tileDirectory = [[NSBundle mainBundle] resourcePath];
Now it works in simulator, because all files are in the apps root folder and I don't ask for it to enter another directory called "Tiles".
This runs with no error on the simulator, but when on my iPhone it gives the original error (just a different file path but also ending with /xxxx.app
How can I ensure a directory in my app file such as xxxx.app/Tiles - TileMap does this.
Since it is your files in your app bundle, I think you can use pathForResource:ofType: to get the full pathname of your file.
Here is an example:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"your_file_name"
ofType:#"the_file_extension"];
Remember that the "folders/groups" you make in xcode, those which are yellowish are not reflected as real folders in your iPhone app. They are just there to structure your XCode project. You can nest as many yellow group as you want and they still only serve the purpose of organizing code in XCode.
EDIT
Make a folder outside of XCode then drag it over, and select "Create folder references for any added folders" instead of "Create groups for any added folders" in the popup.
If your tiles are not in your bundle, either copied from the bundle or downloaded from the internet you can get the directory like this
NSString *documentdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *tileDirectory = [documentdir stringByAppendingPathComponent:#"xxxx/Tiles"];
NSLog(#"Tile Directory: %#", tileDirectory);
You need to use the URL for the link, such as this:
NSURL *path = [[NSBundle mainBundle] URLForResource:#"imagename" withExtension:#"jpg"];
It will give you a proper URL ref.
You need to add your tiles into your resource bundle. I mean add all those files to your project make sure to copy all files to project directory option checked.

how to get resource path using subpath Using NSBundle

Have the folder structure like
*Resources/books/CD_en/icon/0.jpg;
*Resources/books/CD_en/icon/1.jpg;
*Resources/books/DD_en/icon/0.jpg;
*Resources/books/DD_en/icon/1.jpg;
how to get resource path from NSBundle using the subpath 'books/CD_en/icon/0.jpg'
I tried using,
- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension inDirectory:(NSString *)subpath
[[NSBundle mainBundle] pathForResource:#"0.jpg" ofType:#"jpg" inDirectory:#"books/CD_en/icon"];
but it returns nil.
I got it. Simply we need the add the folder structure 'books/...' to the app Resource folder. Which will display in blue color.
Then the existing code is running successfully.
Thanks to yehnan.
i got same problem to retrive image from Resource folder. Adding image by following method solved my problem.
Right click on project in xcode and select Add Files to "project name".
Select your image file from computer local disk.
In the pop-up window make sure you select Copy items into destination group's folder and Create Folder References for any added folders and Add to targets.
click Add.
Then with bellow code i can retrive my image.
[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"png"];

Problem getting path to .plist using [[NSBundle mainBundle] pathForResource

I'm an Objective C noob, and I don't know enough to explain the following problem.
This code works:
NSString *plistPath = #"/Users/andrewf/MyApp/Resources/Plates.plist";
dicPlates = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
My dictionary object is loaded with values as expected.
This code does not work:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Plates" ofType:#"plist"];
dicPlates = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
plistPath comes back with a value of nil. This is the case irrespective of whether I include inDirectory:#"Resources" in the call or not. All the examples that I have found do not include inDirectory when trying to open a .plist file in the Resources directory.
I have confirmed that the file exists in the correct location and even recreated it to be sure.
This seems like such a simple problem, but I am mystified. Please assist.
I think you're confused as to where pathForResource: is looking.
This works:
NSString *plistPath = #"/Users/andrewf/MyApp/Resources/Plates.plist";
Notice that this path does not point to your application. It points to your project directory. Your plist is supposed to be at #/Users/andrewf/MyApp/build/Release/MyApp.app/Resources/Plist.plist" (for an iPhone app this would be different, more like #"/Users/andrewf/Library/Application Support/iPhone Simulator/User/Applicatons/(unique id)/MyApp.app/Resources/Plates.plist"), and it is inside the Resources folder of your app that pathForResource: is looking.
What this implies is that your resource is not in the "Copy Bundle Resources" phase of your build target. You need to drag it from the Groups and Files area to inside that phase.
I have found the problem!
The .plist file was included in the target correctly.
When the .plist was originally created, I named the file "plates.plist". Immediately after creating the file, I renamed it to "Plates.plist", and this is what I used henceforth.
Even though the file was named "Plates.plist" in my resources folder, in the target section and in the iPhone Simulator location mentioned above, the file was named "plates.plist". Curiously, the contents of the file was still updated correctly.
Now that I have changed the code to refer to "plates.plist", and renamed the file in the Resources folder to the same for good measure, everything works. I can only assume that this is a bug in the iPhone SDK.
Check that the plates.plist file has been added to the target in Xcode.
If the file is not added to the target it will not be inside the build product and NSBundle will not find it.

Bundles and file access

I've adding a series of folders to my project (using the Add existing file option). This results in the folder contents being shown in Xcode as a blue folder.
The following works:
NSString *imageName = [NSString stringWithFormat:#"/File-03/images/image-%02d.jpg", imageIndex];
return [UIImage imageNamed:imageName];
However, I want to switch to using imageWithContentsOfFile so the images are not cached.
The code below returns nil for the image:
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"/File-03/images/image-%02d.jpg", imageIndex]];
I also tried accessing the imageWithContentsOfFile using a bundle, no go.
What am I missing here?
To access and store files on the iPhone I recommend reading this.
Erica Sadun has also written a nice shorty about accessing file within a app bundle.
Note that how files are organized in Xcode does not show how they will end up in the app bundle. The best way is to select the app bundle in the Finder and CTRL-click and select Show Package Content.
Okay, I figured out one way in code to get what I needed:
NSString *dir = [NSString stringWithFormat:#"File-03/images", imageIndex];
NSString *file = [NSString stringWithFormat:#"image-%02d", imageIndex];
NSString *path = [[NSBundle mainBundle] pathForResource:file ofType:#"jpg" inDirectory:dir];
return = [UIImage imageWithContentsOfFile:path];
The trick was to inDirectory in the bundle call.
The problem with your imageWithContentsOfFile code is that you're assuming that / is the root of the bundle, when it's the root of the FS!
So, pathForResource:ofType:inDirectory: is probably the easiest way to get the path you need.
Otherwise, you can get the root of the bundle and prefix that to your paths.

iPhone - Loading local images from a local xml file

How come I can load a local xml file from the main bundle, but I can't load images?
NSString *path = [[NSBundle mainBundle] resourcePath];
This gets loaded (i know because I can trace it)
/Users/me/Library/Application Support/iPhone Simulator/User/Applications/5B888456-40FF-4C72-A2ED-5D5CFA287777/MyApp.app/test.xml
This image never loads (nor does any image):
/Users/me/Library/Application Support/iPhone Simulator/User/Applications/5B888456-40FF-4C72-A2ED-5D5CFA287777/MyApp.app/background.png
You can use [UIImage imageNamed:#"background.png"].
This will load background.png (which should be located in your Resources folder in Xcode).
You say in a comment that you're composing a NSURL for the path. To do this for a local file system path, such as a file in your bundle, you need to use NSURL fileURLWithPath:.
There are two possibilities here:
1) Either your image file name doesn't proper. That means, file name is case sensitive. So might be issue of capital-small letters.
2) You might have unchecked the target name from your image property. That means your images are not a member of the target of your project which you are compiling. To verify this, right click on any image name inside your XCode poject --> Select Get Info --> Select Targets tab from the File Info dialog --> Verify the status of the checkbox near the target name/s. In case, it is selected/checked then there is a strange issue. But if it's not selected/unchecked, that means the image is not being added to the bundle file which is created after compilation.
The third possibility here is you might not have added the image which you're referring. Re-check your project hierarchy & see all the resources are there or not.
Something like
UIImage *testimg = [UIImage imageNamed:myfilename];
if (nil==testimg) [testimg initWithContentsOfURL:myurl];
I'm away from compiler right now so I can't check whether you might need to download it to an NSData object before making it an image. You should also put the initWithContents... in a try... catch... finally block.
Hi
Use the following code
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"background" ofType:#"png"]];
NSURL *imageURL = [NSURL URLWithString:#"bundle://background.png"];