Location of my own directories - iphone

I am trying to understand how to create my own directory tree and access it from my application.
I am doing some kind of learning program and want to create a directory structure like this:
-MyLessonsDirectory
--LessonDirectory_1
---Step_1
---Step_2
---Step_3
--LessonDirectory_2
---Step_1
---Step_2
---Step_3
.
.
and so on
In each "Step"-directory I will have specific content for that step of the lesson. The content is added by me while developing. Hence, I don't want to create the structure and content from within the application, just access it and reading the content of the directories. If I can create this kind of structure and use it it will be very easy to create a nice design that makes it easy to create new lessons in my app.
What I cannot figure out is where I should create those directories in the file-structure in xCode and what is the path to those directories from my application.

You want to look at NSFileManager to create directories:
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error;
BOOL result = [fm createDirectoryAtPath:#"path....." withIntermediateDirectories:YES attributes:nil error:&error];
if(result){
NSLog(#"success!");
} else {
NSLog(#"error: %#",error);
}
As far as where to create the directories, you can put it in ~/Application Support/--Your App's Name-- This is where you should store your app's data if the user doesn't require access to it. Otherwise, you should let the user decide where to save it.
- (NSString *)applicationSupportDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
return [basePath stringByAppendingPathComponent:#"MyApplication"];
}

On the iPhone, you only have access to the apps own directories. The best place to put practice directories in the Documents folder in the app directory.
This...
NSString *dp=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
... gives you the path to the directory folder which you can then hand off to the NSFileManager.
If you want to see the directory structure visually, run the app on the simulator and look in
~/Library/Application Support/iPhone Simulator/User/Applications
The app will be in one of the folders with the gibberish UUID name. You can see the directories and files there in the Finder.
I would add that the iPhone already has most of the directories you might practically need. You have preferences, cache, tmp, Documents etc all in place.
Edit01:
What I want to do is to add content
manually before I start the
application. Then, from within the
application I will read the content I
added before starting the application.
You cannot alter the default directory structure and you have absolutely no control over how the application or its directories are installed. iPhone apps do not have external support files of any kind. Every thing is inside the app bundle.
However, the app bundle is really just a directory so you can stuff things inside it and copy them out into one of the default directories the first time the app runs. You can write anything you want to the documents directory.

Related

Objective C - how to access a file from iPhone/Application/Documents

I am using the following method to write image files out to the Applications/Documents folder:
- (void)saveImage:(UIImage *)image toFile:(NSString *)fileName
{
//get the data from the representation
NSData * binaryImageData = UIImagePNGRepresentation(image);
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
//write the data to a file
[binaryImageData writeToFile:[basePath stringByAppendingPathComponent:fileName] atomically:YES];
}
I thought I could just copy them to my computer, but that's not working out for me. Then, I decided to try to write the files to my hard drive. Nope. I guess that was a dumb idea, too.
I am processing bitmap images that I just want to capture somewhere (not on the device) where I can then retrieve them for testing. I've mucked with this for several hours and now it's getting late and I'm tired. Definitely ready for a little help.
Thank you in advance.
This question was answered by Rajesh Choudhary, but there were a few more hoops to go through to get the images off the phone and I wanted to post the entire process to help someone else in the future. So, here are the steps.
Enable file sharing from your app's info.plist file:
Use the code in the original post to write the file out to the
application /Documents folder.
Run your app to save the file to the iPhone application /Documents folder.
Check that your files were save by opening Organizer and selecting the iPhone running the application and selecting the application. The saved files will be located in the Documents folder in Data files in Sandbox.
To access them, open iTunes. Select the device running the application and select the Apps tab. Then, scroll to the File Sharing section, select the app and voila! The documents folder will display all your saved files on the device.
You can then select one or more of the files and click the Save to... button to save the files to your computer.
if you want to use images from device to your computer... you have to enable file sharing option in your app... When you enable it from your app's info.plist file you can see document folder in itunes.
Select you app from list and then, You can put & get files to/from document directory.
if you want to access image from document directory in app so you can use this method.
-(UIImage *)getImageFromDocumentDirectoryForFileName:(NSString *)fileName
{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
UIImage *image =[UIImage imageWithContentsOfFile:[basePath stringByAppendingPathComponent:fileName]];
return image;
}

how to create plist file in xcode 4.3.2

I am trying to create my own plist file to be used in my application, I am using apple documents as refrence for doing this.
However, I have read that if you create your own plist you need to place it in the resource folder in your applications build. The issue with that is that I have no resources folder in my build... so I am woundering what should I do?.. I have read this guys answere here, he says its fine to just place the plist file in the supporting Files folder.. is this okay to do in regards to allowing the plist to be read and written too?
To read and write to plist the best practice is to copy it to document root if you want to access it through bundle you don't have write permission. I have provided a snap shot of the code here and how you can accomplish this.
NSError *err;
NSFileManager *fileManager = [NSFileManager defaultManager];
//getting the path to document directory for the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [paths objectAtIndex:0];
NSString *path = [documentDir stringByAppendingPathComponent:#"YourFile.plist"];
//checking to see of the file already exist
if(![fileManager fileExistsAtPath:path])
{
//if doesnt exist get the the file path from bindle
NSString *correctPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"YourFile.plist"];
//copy the file from bundle to document dir
[fileManager copyItemAtPath:correctPath toPath:path error:&err];
}
You can put that plist file anywhere you want.
The important thing will be copying it into the bundle. So to be sure for that check
project settings>build phases>copy bundle resources
You can open project settings by left-clicking on your project in the project navigator.

Where to put text files for iPhone UITextView

I have multiple UITextViews with corresponding .txt files. I'm reading them with NSString's
stringWithContentsOfFile
but I don't know the path where I should put my files. If I put it to /tmp/ on my Mac, it works in Simulator, but, of course, doesn't work on the actual device. So where should I put the files, so they'll work on both Simulator and actual Device.
Add them as resources to your project and you'll be able to load them from your application bundle using path:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"filename"
ofType:#"txt"];
If you want to make these files editable, though, you can keep them in Documents folder in application sandbox. To get its path you can use:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
So workflow in this case may be the following:
Check if required file is present in documents folder. If no - copy it there from resources.
Read data from file (from Documents folder)
Save updated data to file (in Documents folder) if needed
Place them into Documents folder under your application structure. You can get actual path to it by calling:
NSString *docsDirPath = [NSHomeDirectory() stringByAppendingPathComponent: #"Documents"];
This will work on the device as well as in the Simulator.
You'll want either NSTemporaryDirectory or NSDocumentDirectory.
An in-depth example for using UITextView with files can be found at http://servin.com/iphone/iPhone-File-IO.html

Data storing in plist works in simulaor but not in device

I am new to iPhone development. I have created plist such as from my previous post. It works well in simulator but not in device.
I am getting the saved value from the plist and checking for the condition. When I use simulator it works but not in device.
(1) You can't write to a file in the resource folder of an iPhone. It is part of the security system of the phone that prevent malicious code from altering an application after it has been installed.
(2) If you want to save new data to a file you need to write the file to one of the automatically generated folders. Whenever an iPhone app is installed on the device or simulator, the system creates a default set of folders.
(3) You want to write to either the Preferences folder or the Documents folder. If the data concerns the operation of the app, write it to preferences. If it contains user data write to Documents.
Preferences:
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES);
NSString *prefsDirectory = [[sysPaths objectAtIndex:0] stringByAppendingPathComponent:#"/Preferences"];
Documents:
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
NSString *docsDirectory = [sysPaths objectAtIndex:0];
Say you want to read a default preference plist file, make some changes and then save it the preferences folder.
NSString *plistPath=[[NSBundle mainBundle] pathForResource:#"PlistFileName" ofType:#"plist"];
NSMutableArray *defaultPrefs=[[NSMutableArray alloc] initWithContentsOfFile:plistPath];
//... modify defaultPrefs
NSString *outputFilePath=[prefsDirectory stringByAppendingPathComponent:#"alteredPrefs.plist"];
[defaultPrefs writeToFile:outputFilePath atomically:NO];

Where to keep .plist file in iphone app

I am developing an iPhone app, in which i want use an .plist file to save some config variables.
in my xcode where to create that .plist file and how to access it???
thank you,
You would put in the resources folder. Then use something like this to load it:
NSString *file = [[NSBundle mainBundle] pathForResource:#"TwitterUsers" ofType:#"plist"];
NSArray *Props = [[NSArray alloc] initWithContentsOfFile:file];
Where TwitterUsers is the name of your plist file.
If your plist file contains keys and values you would make the second line an NSDictionary instead of NSArray.
To store the plist file in your Documents directory you will have to include plist file in your app and then on first launch copy it to Documents directory.
To get access to the file in Documents directory:
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
// <Application Home>/Documents/foo.plist
NSString *fooPath =
[documentsPath stringByAppendingPathComponent:#“foo.plist”];
I would recommend keeping it in the Resources directory in the app bundle, but you can just drag it into the project window. The NSBundle method pathForResource:ofType: should give you a path, which you can pass to NSDictionary's dictionaryWithContentsOfFile:.
Edit: Sorry, full code sample (thought I'd already copied & pasted):
NSString *path = [[NSBundle mainBundle] pathForResource:#"MyConfig" ofType:#"plist"];
NSDictionary *myConfig = [NSDictionary dictionaryWithContentsOfFile:path];
EDIT Just occured to me "config variables" might not be immutable. If that is the case, disregard this answer.
I would recommend you use NSUserDefaults to store configuration variables instead of rolling your own system.
If you are modifying a .plist inside your application bundle, you will risk invalidating the signature on the bundle, while will not end well.
If you must store and modify your own .plist, store it in the Documents directory, which is also where your application should store anything that it downloads, creates, etc. See File and Data Management and NSFileManager.
By default if you have included the plist in the project anywhere (under Resources or otherwise) XCode will copy it into the application bundle where you can get to it with the aforementioned pathForResource call. Just thought I'd mention that as you might prefer a grouping where you do not have it in resources...
you can find the example sqlite book ..... the silte data file was save into the directory 'Document' .... you will know the prcess
Why would it invalidate the bundle?
Would this plist file in the resources folder be backed up in iTunes like files in the documents folder?