Why can't I use the plist I created? - iphone

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.

Related

How to get the files inside a folder in Supporting Files in xcode 4.2?

I have done the following steps.
1. Created an xcode project and created a folder named "Images" inside Supporting Files.
Dragged and dropped 4 images into it. Tried to access those files using the following code
NSString *pathString = [[NSBundle mainBundle] pathForResource:#"Images" ofType:nil];
NSArray *fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pathString error: nil];
NSLog(#"the fileList is %d",[fileList count]);
The count is always 0. What should I do now? There are files inside it and I am able to use it in imageviews.
So what is the mistake that I am making?
The Xcode does not generate any folders in your app bundle that corresponds to groups. Any resources added are present in Copy Bundle Resources in your target's Build Phases. You then access your resource under [[NSBundle mainBundle] bundlePath] path.
But if you want to count files under any folder then while adding that folder you must check the option :
"Create folder references for any added folders."
This will create folders and sub-folders in the same hierarchy as you add them.Then you can easily count them in the same manner you are doing above...
Otherwise the app bundle has all of your resources at one place not in any folder as you say "Images".Use following code :
NSArray *fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[[NSBundle mainBundle] resourcePath] error: nil];
NSLog(#"the fileList is %d",[fileList count]);
It will list all your resources.
Try this,
NSString *imagespath = [[NSBundle mainBundle] pathForResource:"yourimagename" ofType:#"png" inDirectory:#"images"];

finding the path beyond the bundle

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).

Why can't files in my iPhone NSBundle folder be deleted?

I'm having trouble figuring out why files in my iPhone app seem to persist, even when I've deleted them. Here's the code that's giving me trouble:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *folderPath = [bundlePath stringByAppendingPathComponent:#"filefolder"];
NSArray *fileNames = [fileManager contentsOfDirectoryAtPath:folderPath error:NULL];
This code is supposed to look at the folder "filefolder" and read its contents into fileNames. When I run this app the very first time, it will do this. But if I change the contents of filefolder (for instance if I add or delete files) and I build and run the app again, the array filenames will contain names of all the newly added files (good) but also contains names of all the files that were supposed to have been deleted (bad)!!
Can anyone help me understand why I'm seeing this behavior?
Did you do a "Clean" in XCode after adding/removing new items from the bundle? This usually solves the problem of "stale" resources.

iPhone SDK: subFolders inside the main bundle

in the current project I have a number of folders, with subfolders, and these contain images: 01.png, 02.png.
Folder1/FolderA/f1.png
Folder1/FolderB/F1.png
When I compile the app, I looked inside the the .app and noticed that all the images are placed in the top level, with no sub-folders.
So clearly when trying to load the image this doesn't work:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"f1"
ofType:#"png"
inDirectory:#"Folder1/FolderA"];
But even more strangely, when loading image "f1", the image actually loads "F1"
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"f1.png"]];
Anyone have ideas on how to get around this problem?
Is there a compile option to create the folders in the app bundle?
TIA.
To create the subfolders inside the .app bundle, you should check the option "Create folder references for any added folders" rather than the default "Recursively create groups for any added folders"
Now in XCode, your imported folder appears blue rather than yellow. Build and go and you should see folders in your .app file.
First of all the folders you create in Xcode are simply organizational structures without any counterpart on the filesystem level. In other words all folders except for the "Classes" folder gets flatten out at the filesystem level. Therefore, even if you put your image file in the following location within xcode, it would still exist at the top-level in the filesystem: f1/f2/f3/f4/f5/image.png. Thus, in pathForResource method, you should not include the inDirectory argument.
As for the second issue, mac osx doesn't recognize case-sensitive file names. Therefore, f1 and F1 are equivalent to mac osx and will reference the same file. You can easily see this by executing the following 2 commands at a terminal session:
touch f
touch F
you'll notice that only 1 file exists after this: namely f. If you reverse the 2 commands, you still get one file, but it is named F.
ennuikiller is right. I think you can organize your images via Finder in subfolder and then refresh the image location in XCode by right clicking your image and selecting "Get Info" option. Then set the new directory.
Cheers.
Just wanted to add to Mugunth's answer, to follow up on part of the original question which was trying to use:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"f1" ofType:#"png" inDirectory:#"Folder1/FolderA"];
... to access files added using folder references. The above 'pathForResouce' call will work on simulators but not on actual iPhones (nil will be returned), because they don't seem to recognize subfolders in the 'inDirectory' part of the method. They do recognize them in the 'pathForResource' part, though. So the way of rephrasing the above so that it works on iPhones is:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"FolderA/f1" ofType:#"png" inDirectory:#"Folder1"];
I've followed your answer but it seams all files are stored flat on the root. If I use the code below to get the full path
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef url = CFBundleCopyResourceURL(mainBundle, CFSTR("About"), CFSTR("png"), NULL);
UInt8 filePath[PATH_MAX];
CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath));
I get as a result: /Users/iosif/Library/Application Support/iPhone Simulator/6.1/Applications/33FB4F79-999C-4455-A092-906A75226CDB/Arithmetics.app/About.png

Compiling an XML file into a binary

I want to parse and XML file in an iPhone app without going to disk for it.
Can I do this? How? I have included a TXT helpfile in an app using MSVC.
I put the XML file in a Folder/Group named Resources in the project.
I have the XML file in the proj directory.
I right clicked on Resources folder and selected add -> Existing File.
I right-click on the XML file and select GetInfo.
There I have tried altering the Path Type {Absolute, Relative to Project , etc}
My program runs fine on the simulator when I use:
NSString * const DG_XmlRecipeFile = #"/Users/appleuser/Cocoa/iHungry6/Recipes.xml";
It seems to me it should also work with:
NSString * const DG_XmlRecipeFile = #"Recipes.xml";
If I set the Path Type correctly. It does not.
I am a first timer. Thanks for reading this , Mark
Xcode copies the project resources to the app bundle. You can access your file within your bundle as follows:
NSString *DG_XmlRecipeFile = [[NSBundle mainBundle] pathForResource:#"Recipes" ofType:#".xml"];
Files in the bundle are read-only. If you want to modify the file you will need to copy it somewhere that you can modify it. Your app's Documents directory works well for this.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDirectory = [[paths objectAtIndex:0] retain];
NSString *newFilePath = [docsDirectory stringByAppendingPathComponent:#"Recipes.xml"];
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:DG_XmlRecipeFile toPath:newFilePath error:&error];
I don't think the path type you are referring to is the path to the resource within the app bundle that is produced. It is how the file should be referenced within the .proj file.