Ios file handling and location access - ios

I am having an ios app that reads contents of a csv file and produces output.When i run the program on a simulator ,i can directly specify the file path(/Users/abc/file.csv).Where to keep these files and access them in a n iphone.We cant specify the static path here?

Just drag & drop them to your project, and access them like this:
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *myFile = [mainBundle pathForResource:#"myFile" ofType:#"csv"]

If you place the file in your application directory, you can access it by:
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"yourfilename" ofType:#"csv"];

For reading static files, use the other people's answers.
If you need to write out a file, you need to access the Documents directory.
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"file.csv"];
And then use NSFileManager for writing the file. Classes such as NSDictionary have helper functions for writing their values to a file, too.

Related

How to access files at a path NSURL

Hello everyone i have the following code :
NSString* issuePath =[[self contentURL] URLByAppendingPathComponent:#"magazine"].path;
I have a file called a.plist in the above directory. I have to read the a.plist file contents. How to do that. Before the file was local and I was accessing it as follows
NSString *path = [[NSBundle mainBundle] pathForResource:#"a" ofType:#"plist"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"a.plist"];
NSMutableDictionary *plistContents = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
Refer this file handler utility which provides API's to interact with most of your file related operations.
It exposed API for below features,
Check if the file, or directory, exists in the given path
Create a folder in a given path
Verify if a folder exists at a given path
Get the size of a file
Check if a file with that name exists in the folder
Check if this folder has more subfolder or if it's the last folder
File Handler Utility Class link
You can simply use the following method.
NSString *path = [[NSBundle mainBundle] pathForResource:#"a" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];

pathForResource is empty in iOS

Can't understand, why does this line of the code return (null)?
// Get path of data.plist file to be created
plistPath = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
I need to create new plist but can't understand, does the empty file should be created before to get the path to it.. Any ideas?
PS I had only h,m and no plist files in my project now.
You don't create new files in your bundle after deployment. The bundle contains all the resources and files that ship with your app.
Instead, you create new files in your app's Documents folder. To get the documents folder path, you can use a method like this (as included in some of the app template projects):
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
Then you simply append the file name you want to use.
NSString *path = [self applicationDocumentsDirectory];
path = [path stringByAppendingPathComponent:#"data.plist"];
You might also want to have some additional folders in your Documents folder for organizational purposes. You can use NSFileManager to do that.
Yes, your guess was right - you would need to create a file first. Here is what the class reference documentation had to say about the method's return value
"Return Value
The full pathname for the resource file or nil if the file could not be located."
You could do something like:
if ( [ [NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"] )
plistPath = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
else
// Create new file here
Also, you could leave out the type extenxion in the method call above if you are searching for a unique file name.
Source: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/Reference/Reference.html

.plist path on iOS device

-(void)login{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"login" ofType:#"plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
In iOS Simulator the plist has been correctly written, but when I try to write the .plist on my iPhone, it doesn't work. I guess it is because of the wrong .plist path.
Do the iOS devices use different path?
First you have to check if the file exits in your documents directory. If it doesn't exits there then you can copy it to the document directory. You can do it this way
-(void)login{
BOOL doesExist;
NSError *error;
NSString *filePath= [[NSBundle mainBundle] pathForResource:#"login" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * path =[[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:#"login.plist"]];
doesExist= [fileManager fileExistsAtPath:path];
if (doesExist) {
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:path];
}
else
{
doesExist= [fileManager copyItemAtPath:filePath toPath:path error:&error];
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
}
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
You can't write to the [NSBundle mainBundle] location. In order to write files like a plist, you should save in the documents folder, this way:
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *filePathToSave = [arrayPaths objectAtIndex:0];
If the plist is part of your app, I would recommend you, in the first launch, to already copy it to the documents folder using the same filePathToSave, so you will always look at it there, both to read or to save.
This is a big mistake, as the main bundle only is readable and only composed at compile time in the App Bundle. The App Bundle lives in a separate place, whereas the data you should write to disk should be placed into the Documents, Temporary or Library folder of your sandbox.
To gain more understanding please read the official File System Programming Guide.
Everything you need to know is written there.
You can also write to subfolders and you should choose between the 3 above mentioned main directories in terms of backing up, when syncing with iTunes or iCloud. For instance contents in the tmp Folder won't be backed up.
You can not write to the mainBundle on an iOS device. You will have to save the file to a directory and modify it there.
Just to bring the answers into the modern world - you should really be using the URL based methods for getting directories:
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *URLForDocumentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]

How to hide folders created in Document Directory in ios?

I have created some PDF files programatically, which i am storing into the devices memory using the following code >>>>
NSString *fileName = [NSString stringWithFormat:#"SampleTextFile.pdf",strFinalString];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [path objectAtIndex:0];
NSString *saveFileName = fileName;
NSString *documentPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
I can see the file in the Devices Document folder.
I want to hide these files so that the user can not see or delete it.
Can anyone help me out to do this.
A good place to store private data is in ~/Library/Application Support/, which is the folder used on the Mac for this purpose.
You can generate a path to this folder using:
NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject];
You'll have to create the folder yourself the first time you use it, which you can do with:
if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir])
{
[[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:NULL];
}
I wrote a simple library that makes this and all other useful iOS folders available as methods on NSFileManager: https://github.com/nicklockwood/StandardPaths
Just prefix the filename with a dot, as in .SampleTextFile.pdf.
But the real solution is to not store the document in the NSDocumentDirectory in the first place. You should create subdirectory in the NSLibraryDirectory and store this stuff there. It also gets backed up and will not get purged like Caches and tmp, but the user cannot access it with iTunes.

Adding folder to iPad bundle works on simulator, not on device

I have two targets for my app.
Each has its file own Info.plist and a custom folder included (as references, not as group).
When I run my target on the simulator the folder is correctly inserted in the bundle and the files inside it are read without problems.
This is the code to read the folder path:
NSBundle* mainBundle;
NSString *fileFolder;
mainBundle = [NSBundle mainBundle];
NSLog(#"Bundle path: %#", [mainBundle bundlePath]);
NSLog(#"Folder name: %#", [mainBundle objectForInfoDictionaryKey:#"CustomFolder"]);
NSString *folder = [mainBundle objectForInfoDictionaryKey:#"CustomFolder"];
fileFolder = [[[NSBundle mainBundle] pathForResource:folder ofType:nil] retain];
NSLog(#"Folder: %#", fileFolder);
If I try to debug the app on the device, Bundle path and Folder name are correct, but the folder string is null.
I've checked inside my app product, and the there is the right folder, with all the files.
So what's the problem? Is it a read permission issue?
UPDATE
The resulting path running in iPad Simulator is this
/*/Library/Application Support/iPhone Simulator/4.3.2/Applications/8337B9E5-1BFE-4A17-969E-E3E6E43193D6/MyApp.app/CustomFolder/
UPDATE 2
The problem is that I've added the folder with "Create folder references for any added folders".
I replaced pathForResource with stringByAppendingPathComponent, but the problem now persist for subpathsOfDirectoryAtPath.
You have to make sure you use the correct place in the iPad memory. there is no restrictions to where you save stuff on the simulator. This code works
+(NSString*) pathToDocumentsFolder
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
+(NSString*) pathToFileInDocumentsFolder:(NSString*)filename
{
NSString *pathToDoc = [NSBundle pathToDocumentsFolder];
return [pathToDoc stringByAppendingPathComponent:filename];
}

Resources