iPhone : Get the file path which is within subfolder of Resource folder - ios

I am new to iPhone programming. I want to read the content of a text file located in a subfolder of the Resource folder.
The Resource folder structure is the following:
Resource
Folder1---->Data.txt
Folder2---->Data.txt
Folder3---->Folder1---->Data.txt
There are multiple files named "Data.txt", so how can I access the files in each folder? I know how to read the text file, but if the Resource structure is similar to the above structure then how can I get the path?
For example, if I want to access the "Data.txt" file from Folder3, how can I get the file path?
Please suggest.

Your "resource folder" is actually the contents of your main bundle, also know as the application bundle. You use pathForResource:ofType: or pathForResource:ofType:inDirectory: to get the full path for a resource.
Loading the contents of a file as a string is done with the stringWithContentsOfFile:encoding:error: method for an autoreleased string of with initWithContentsOfFile:encoding:error: if you want a retained string.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Data"
ofType:#"txt"
inDirectory:#"Folder1"];
if (filePath != nil) {
theContents = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:NULL];
// Do stuff to theContents
}
This is almost the same answer as given by Shirkrin previously, but with the slight difference that it works on target. This is because initWithContentsOfFile: is deprecated on Mac OS X, and not available at all iPhone OS.

To continue psychotiks answer a full example would look like this:
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString *filePath = nil;
if (filePath = [thisBundle pathForResource:#"Data" ofType:#"txt" inDirectory:#"Folder1"]) {
theContents = [[NSString alloc] initWithContentsOfFile:filePath];
// when completed, it is the developer's responsibility to release theContents
}
Notice that you can use -pathForResource:ofType:inDirectory to access ressources in sub directories.

Shirkrin's answer and PeyloW's answer above were both useful, and I managed to use pathForResource:ofType:inDirectory: to access files with the same name in different folders in my app bundle.
I also found an alternative solution here that suited my requirements slightly better, so I thought I'd share it. In particular, see this link.
For example, say I have the following Folder References (blue icons, Groups are yellow):
Then I can access the image files like this:
NSString * filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"pin_images/1/2.jpg"];
UIImage * image = [UIImage imageWithContentsOfFile:filePath];
As a side note, the pathForResource:ofType:inDirectory: equivalent looks like this:
NSString * filePath = [[NSBundle mainBundle] pathForResource:#"2" ofType:#"jpg" inDirectory:#"pin_images/1/"];

NSBundle* bundle = [NSBundle mainBundle];
NSString* path = [bundle bundlePath];
This gives you the path to your bundle. From there on, you can navigate your folder structure.

Related

ios9 : NSLocalizedString inside framework

I had create a framework that send data to server. Whenever I get response from the server I translate it using NSLocalizedString but it not working.
I tried to change Main Bundle to my Framework Bundle like this :
NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:#"Frameworks/MYFRAMEWORK.framework"];
NSBundle *bundle = [NSBundle bundleWithPath:frameworkBundlePath];
[bundle localizedStringForKey:#"Message" value:#"" table:nil];
But still not working. is there any way to localized message when the Localizable.string is inside the framework ?
Thanks
Finally, I tried to recreate Localizable.string and whenever I want to localize I use this :
NSString *message = [[NSBundle bundleForClass:self.class] localizedStringForKey:#"MESSAGE" value:nil table:nil];
I put this code inside class of framework, so bundle of self.class is direct to framework bundle. Thank's for everybody help.
Try to use [NSBundle bundleForClass:self.class].

Where should I put the XML file in iPhone Simulator's filesystem. XCode 4.2

A little embarrassing question, but I can find an answer which works in my case... I need to put some xml file (settings.xml) in order to read some data from it during application runtime.
According to some answers here and not only here, I have putted it here:
~/Library/Application Support/iPhone Simulator/5.0/[AppUUID]/Documents
and I'm trying to use it as follows:
// Loading data from external XML File
NSURL *url = [[NSBundle mainBundle]
URLForResource: #"settings" withExtension:#"xml"];
NSError *err;
if ([url checkResourceIsReachableAndReturnError:&err] == NO){
NSLog(#"FILE NOT FOUND");
}
Result: "FILE NOT FOUND".
I've tried to do put the file under any possible directory in
~/Library/Application Support/iPhone Simulator/5.0/[AppUUID]/ and efect is still the same.
I'm using XCode 4.2
If you are putting the file into the .../Documents folder then you need to use the following code to access it (you are looking for it in the App Bundle, which is a different location altogether):
NSString *docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [docFolder stringByAppendingPathComponent:#"settings.xml"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
{
// Read file
}
else
{
NSLog(#"settings.xml file not found!");
}

XCode - How to access Data in specific filepaths

I want to access data (xml, to be specific) in different filepaths, depending on some parameters. In short, theres a /Saves/ folder, which contains several other folders (/Save1/, /Save2/, /Save3/, etc). I want to be able to parse.
Lets assume the file I want to access is in the following path:
/../projectname/Saves/Save1/dialogue.xml
Within finder I created the folder substructure and then copied it into my XCode project. That means, these folders exist in the filestructure and not just in XCode.
Afterwards I'm trying to do the following:
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:"#/Saves/Save1/dialogue.xml"];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
However, that doesn't seem to work properly. Logging the path variable I get the following:
/Users/<username>/Library/Application Support/iPhone Simulator/5.1/Application/<appcode>/<appname>.app/Saves/Save1/dialogue.xml
Where's my mistake? Thanks in advance for any help.
Please make sure you have added same folder in project target also. One you add the same structure under project target and compile then same folders will be created in your .app file. then you can access it the way you mentioned.
try this:
//NSString *path = [[NSBundle mainBundle] pathForResource:#"dialogue" ofType:#"xml" inDirectory:#"Saves/Save1"];
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Saves/Save1/dialogue.xml"];
if([[NSFileManager defaultManager] fileExitsAtPath:path])
{
NSMutableData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
}
else
{
NSLog(#"File doesnot exits");
}

ios - printing HTML from a .html file not working in a UIWebView

I got "hello world" text to print after I hardcoded some html right into my UIWebView functions, but now I am trying to move that HTML to a file elsewhere on the file system, and it isnt rendering.
Here is what I have:
- (void)viewDidAppear:(BOOL)animated
{
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"learn" ofType:#"html" inDirectory:#"src/html_files"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[theWebView loadHTMLString:htmlString baseURL:nil];
}
and my HTML file is in a directory that I made called src/html_files and the file is named learn.html
What am I doing incorrectly that the HTML is not rendering on the screen?
Thank you!
Ok, so Groups are just a construct in Xcode for keeping your app's resources organized. Although Xcode uses the little folder icon, it doesn't necessarily mean those are actually separate folders on the (Mac or iOS) filesystem.
But, it sounds like you have added that file as a bundle resource. That's what the code you posted looks like, too, but I had to ask, to be sure.
Most likely, the only thing wrong is that this:
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"learn"
ofType:#"html"
inDirectory:#"src/html_files"];
should be this instead:
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"learn"
ofType:#"html"];
From the Apple documentation for NSBundle,
+ (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)extension
inDirectory:(NSString *)bundlePath
bundlePath
The path of a top-level bundle directory. This must be a valid path. For example, to
specify the bundle directory for a Mac app, you might specify the path /Applications/MyApp.app.
The bundlePath parameter is not meant to specify relative paths to your bundle resources. The version of pathForResource:ofType: that does not have a bundlePath parameter is almost always what you'll use. It will find the learn.html file wherever it lives, once your app is installed, and return the full path to that. You don't really have to worry about how it's nested. It's just a bundle resource.
Give that a try. As I suggested in my comment, though, I always recommend taking advantage of the error parameter for debugging:
NSError* error;
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error: &error];
if (error != nil) {
NSLog(#"Error with stringWithContentsOfFile: %#", [error localizedDescription]);
}

Bundle subdirectory access

I'm try to implement ability to change interface in my program, something like themes. I'm decide to use bundles, so in my case they looks like this:
Theme1.bundle
Theme2.bundle
Every bundle have folders:
Theme1.bundle
graphic
pic1.png
pic2.png
sound
sound1.wav
sound2.wav
So I can get path to any required picture from bundle with this code:
path = [NSString stringWithFormat:#"%#.bundle/graphic/%#", selectedBundle, imageName];
When I get pictures from bundle there is no problem, path looks like this (I check it using breakpoints):
Theme1.bundle/graphic/pic1.png and I create UIImage
image = [UIImage imageNamed:path];
Pictures loaded without any problem.
But when I trying to play sound using AVAudioPlayer, I get path to sound by same way and path looks like this:
Theme1.bundle/sound/sound1.wav, but when I try to create NSData
sound = [NSData dataWithContentsOfFile:path];
it is not initialized.
When I try to keep sounds in main bundle and get it with
path = [[NSBundle mainBundle] pathForResource:#"sound1" ofType:#"wav"];
everything is OK, and path looks like this
/var/mobile/Applications/E8313E88-CE05-44B2-A80C-B05331D8596F/Myapp.app/sound1.wav
I cant understand why this works with pictures but not with sound?
Why I cant get sound from bundle?
Only one thing I can suggest - imageNamed: do some work to find right path to file and dataWithContentsOfFile: does not.
In your code instead of
sound = [NSData dataWithContentsOfFile:path];
Use
NSString * path = [NSString stringWithFormat:#"%#.bundle/sounds/%#", selectedBundle, soundName];
NSString *fullPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:path];
sound = [NSData dataWithContentsOfFile:path];
Explanation:
ImageNamed attaches the path of the application to the image name you specify

Resources