finding the path beyond the bundle - iphone

i want to find the path of the file which is not in my bundle..
NSString *path = [[NSBundle allBundle] pathForResource:nm ofType:#"jpg" inDirectory:nil];
but it gives warning that NSArray may not respond..
is there any way to find the path of file any other folder.

allBundle returns an NSArray of all the bundles. You mean to use the method mainBundle.
If you can't find your resource then this is most likely a problem with the name of the resource you're looking for (have you checked the value of nm is correct?) Also check in your Target under the "Copy resources" section that your .jpg file is listed there. If it's not then you should drag it there to ensure that the file is copied into your bundle when you build it.
If you really want to search through all the available bundles for your resource, then you can loop through the array of bundles that allBundle returns as follows:
NSString* pathForResource = nil;
for (NSBundle currentBundle in [NSBundle allBundle])
{
pathForResource = [currentBundle pathForResource:nm ofType:#"jpg"];
if (pathForResource)
{
break; // Found resource, no longer need to search through bundles.
}
}
Note: You also don't need to use the "inDirectory:" part of the method (see the docs).

Related

accessing resources on bundles [duplicate]

This question already has answers here:
Packaging a Bundle with a static library
(3 answers)
Closed 9 years ago.
I have created a subproject as a static library and added a bundle to it, so I can wrap the project and resources that will be used by all programs using that library.
I have followed the instructions here.
http://www.galloway.me.uk/tutorials/ios-library-with-resources/
It is working fine, except when I have to work with resources like images and other files.
I thought that by importing a library and its resources to another project I could access them easily but this is not the case.
Every time I have to access a resource file on library's bundle I have to use this:
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"MyLibraryBundle" withExtension:#"bundle"]];
path = [bundle pathForResource:#"readme" ofType:"txt"];
but if the resource is on the main program I have to use [NSBundle mainBundle] instead.
This is creating a very complex logic because I may have more than one subproject and I will have to create zillions of variations.
Is there a way to make a way the app can find the resource whatever it is using a simple syntax or am I missing something?
Factor your resource accesses into a separate class. For example, something like this might work for you:
#interface CSResourceManager
+ (NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
#end
#implementation CSResourceManager
+ (NSArray *)resourceBundles
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSURL *libraryBundleURL = [mainBundle URLForResource:#"MyLibraryBundle" withExtension:#"bundle"];
NSBundle *libraryBundle = [NSBundle bundleWithURL:libraryBundleURL];
// Add more bundles here and/or cache as necessary
return #[ libraryBundle, mainBundle ];
}
+ (NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type
{
NSString *path = nil;
for (NSBundle *bundle in [self resourceBundles]) {
if ((path = [[self resourceBundle] pathForResource:resource ofType:type])) {
break;
}
}
return path;
}
#end
If locating the resource bundle every time is too slow, you may want to cache it, i.e. using a static variable.
To use this, you would now just have to write:
NSString *path = [CSResourceManager pathForResource:#"readme" ofType:#"txt"];
In addition to making your code easier to write, using a class like this will also make it easier to maintain (for example, if you want to change the name of the resource bundle, add additional resource storage locations or fallbacks, etc.).
Update #1: see modified code above to support a "search path" of sorts for locating resources.
Update #2: additional ideas for managing resources:
An alternative to using bundles at all would be to have your subprojects share a naming convention for resource files, essentially flattening the namespace. For example, prefix each resource file with the name of the library it's associated with.

Why can't I use the plist I created?

I created a plist called list.plist, I just can't read the information in it.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *datapath = [path stringByAppendingPathComponent:#"list.plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:datapath];
self.tableDataSource = array;
NSLog(#"%d", [tableDataSource count]);
When I run it, it says the count is 0, but if I change file name to Elements.plist(a plist from the sample code from Apple), it will work. The two files are in the same path. list.plist is written by myself, it won't work even I copy the dictionary from elements.plist to list.plist.
File names are case-sensitive on iOS, FYI. Also, try renaming the Elements.plist from the sample to list.plist and trying again. Maybe it's about file contents, not about file name.
Check to see if the file you created is included in the "Copy Resources" phase of your build. This is necessary to make sure it gets copied from your project's directory to the location of the bundle at runtime.
In Xcode 4, you can do by selecting the project at the top of the project navigator.Click on the "Build Phases" tab and expand the "Copy Bundle Resources" section. You should see a list of files there that get copied. If you see the Elements.plist file but not list.plist, then that is your problem. Drag list.plist from the project navigator to the list of copied files and rebuild.

How to use FILE * with iPhone

I have a file called "0.ballpoint" that all I want to do is store some coordinates with (don't really want to use Core Data because it seem a little excessive). I placed it in my project but when I try doing this:
if ( access("0.ballpoint", F_OK) != -1) {
printf("file exists\n");
}
else {
printf("doesn't exist\n");
}
It says it "doesn't exist". Do I need to put the full path name? And if I do what do I do when I place it on the actual iPhone/iPod Touch?
CoreData is not meant for File access. There are other file API's available for iPhone.
Please go through NSFileManager and NSStream documentation.
For example, if your intention is to check if file exists at certain path,you may use
(add your file to resources)
NSString *filePath = [[NSBundle mainBundle] pathForResource: #"0" ofType: #"ballpoint"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
Prefer not to use low level stuff (C File handles) unless you have a valid reason to do so. Paths are to be carefully chosen (as you cant make assumptions on certain path, which might cease to exist in future).
Having said that, if you prefer to work with C file handling ,
NSString *filePath = [[NSBundle mainBundle] pathForResource: #"0" ofType: #"ballpoint"];
FILE *fileHandle = fopen([filePath cStringUsingEncoding:NSASCIIStringEncoding],"r");
it needs to become a resource to your Application that way the file can be pulled anytime during the use of your application.
Im not too well educated in Ipod Dev, im more of a windows phone 7 developer but i know it cant access it if it is still on your computer so you need to import it into your application some how and call it with the full file path name.

fileExistsAtPath API always return NO

Following is my code I need check whether file present in document directory ,But following API does not return true at any condition but file is get created in document directory. Please check any thing wrong I am doing. I have searched on this other says this API "fileExistsAtPath" should work but it is not working in my case. Please do help me.
NSString *recordFile=[NSString stringWithFormat:#"MyFile.acc",data.uid];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDr = [documentPaths objectAtIndex:0]; // WHY 0 ?
NSString *uniquePath = [documentDr stringByAppendingPathComponent:recordFile];
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
NSLog(#"File found")
}
else {
NSLog(#"No File to play");
}
Thanks,
Sony
Probably your path is incorrect. What should be the name of the files you are trying to find? If you have #"MyFile1.acc", #"MyFile2.acc" etc (where 1, 2 is the data.uid value) then try to use this:
NSString *recordFile=[NSString stringWithFormat:#"MyFile%i.acc",data.uid];
Try to append a "/" after documentDr when define uniquePath, or
NSString *recordFile = [NSString stringWithFormat:#"MyFile%#", data.uid];
...
if([NSBundle pathForResource:recordFile ofType:#"acc" inDirectory:documentDr])
the first wrong thing i note is the first instruction.
Why do you pass 'data.uid' as an argument to the format string ? Assuming 'data.uid' is some kind of integer, there should be at least '%d' in...
I had a look to Apple Documentation, in particular, that statement which says
The directory returned by this method may not exist.
You could try getting the current directory path using NSFileManager methods, and then testing for file existence (or create a directory at a place you can easily retrieve later).
What about the others paths ? You wrote 'WHY 0 ?', i'm asking the same question as you.Try looping over the array elements, testing each time for file existence.
The code should work. Your file most likely doesn't exist. Did you use capitalisation in your file name right when saving it?
Also right now, I still don't know what the file name is since, as already said, the first line in your initial post doesn't give the format string right.
Before checking try for existance try:
[[NSString stringWithString:#"test"] writeToFile: uniquePath atomically:YES];
That should create a file at the path and you see, that fileExists works.
I tried many things but ended up that I had to delete the app, clean all targets, and then rebuild again. It's weird that somehow my new resources doesn't get copied to the app. It usually happens to files that when I added them I selected "Create folder references for any added folders".

Is possible to read plist from application bundle and documents folder at the same time?

Is it possible?to read from my local bundle and at the same time also read from documents folder into UItableview?
thanks thanks
yes.simultaneously
No — as in the iPhone isn't multicore, you can't have "simultaneous" :p
Yes — as in you can open multiple files in the same period of time. There's no conflicts as long as the files are different (if the files are the same then it depends on how others are using and locking the file etc.)
on viewDidLoad or some similar event when you would be populating your table data, you would simply just aggregate the two files together... that is you are are likely populating an array or dictionary with the contents of the file in question... so use the mutable version of array/dictionary, initialize it empty, then read in the first file from whatever location you choose, populating into your mutable array/dictionary, then do the the same for the next file. after you are done, reloadData as you normally would as if you had read form one file.
As far as simultaneous goes, technically no. However, one could have two different active threads each one reading required files and parsing the data.
Regarding the files you want to access...
Here is a quick and dirty method I use in one project (which I just happen to be working on at the moment):
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
self.blahDBPath = [self.documentsDirectory stringByAppendingPathComponent: #"blah.db"];
NSLog(#"Mainbundle Resourcepath: %#", [[NSBundle mainBundle] resourcePath]);
NSString* defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"blah.db"];
NSLog(#"Default DB Path: %#", defaultDBPath);
success = [fileManager copyItemAtPath:defaultDBPath toPath:self.blahDBPath error:&error];
if (!success) {
NSAssert1(0, #"blah blah blah '%#'.", [error localizedDescription]);
}
It is ugly but effective. I'll rewrite it when I refactor the application.
The point here is that I ask the operating system for the path to certain directories. Then I add file names or subdirectories as required. This allows the operating system to manage paths (like in the simulator where each successive build gets a new unique id as part of its path) and I just worry about the final directories and file names in the application.
One I have the paths, I copy the required file from the bundle directory and put them somewhere, the Documents directory in this case. Then I can do whatever I need to with them.
If I just wanted to access them as they are in the bundle directory, then I I just refer to them by using [[NSBundle mainBundle] resourcePath].
I think something along the lines of the above snippet is what you are looking for.
-isdi-