How to browse folders in Objective C? - objective-c

I have a folder and inside that, few files. How can i get that files without using any UI classes?
The small eg given below will make question more clearer:
Suppose in my home folder, there is a folder Printers, inside that there are three folders Printer1, Printer2, Printer3. Now inside each subfolder there is xml file like printer1.xml inside printer1 folder, printer2.xml inside printer2 folder, printer3.xml inside printer3 folder. I have to browse through the folders and store the path to printer3.xml in a variable (of type NSString).
Please suggest me the ways to do that..

You might want to use NSFileManager and related classes..This tutorial might be useful too..

You can use NsFileManger to read directories and files,
here a sample of using FileManager to read documents dir file
//Object file manager
NSFileManager *FileManager = [NSFileManager defaultManager];
//Read Program folder and create an Array with all folder
NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//Element in 0 position contain Documents directory
//Faccio la dir dei file della directory
Files = [FileManager contentsOfDirectoryAtPath:[Paths objectAtIndex:0] error:nil];
if(Files) {
//E uno per uno li cancello
for (NSString *File in Files) {
//Here YOU CAN CREATE YOUR STRING, File CONTAINS file Name
}
}

Related

Cannot Find File with NSFileManager

Im trying to find a file with NSFileManager. The file exists but my path is never correct no matter how its phrased. The code I'm using is below. Why is NSFileManager not finding the file?
NSString *myFile = #"file1658.pdf";
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:myFile]) {
NSLog(#"good");
}
MyFile is not a full path (e.g., "/Users/Joe/Documents/file1658.pdf"), so NSFileManager is looking for it in the current working directory. You can see what that is with -[NSFileManager currentDirectoryPath].
You need to either include the full path to the file as part of myFile, or set the proper working directory with -[NSFileManager changeCurrentDirectoryPath:].
// If myFile is in "/Users/joe/Documents"...
[fileManager changeCurrentDirectoryPath:#"/Users/joe/Documents"];
if ([fileManager fileExistsAtPath:myFile]) {
NSLog(#"good");
}
Apple tries hard to get you to put your files in sensible places. The file my exist, but you will have to either give the full path, e.g. /Users/user2759189/file1658.pdf or specify what folder it is in by other means.
App bundle
If the file is in your app bundle (for example, you have added it using "Add files to [project]" in XCode) you can get its path by something like:
NSString *myFile = [[NSBundle mainBundle] pathForResource:#"file1658" ofType:#"pdf"];
Search paths
You can look for user documents in a civilised manner by using the foundation function NSSearchPathForDirectoriesInDomains and some built in constants. If the file is in the user's Documents folder, for example, you can use something like:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *myFile = [documentsPath stringByAppendingPathComponent:#"file1658.pdf"];

Downloading a file from Dropbox for documents directory deletes all my files

My app shows dropbox files, and the documents directory. when viewing dropbox files i can press a button that shows a list of all my document folders, and subdirectories in those folders so they can chose the folder they want to put that file in the documents. when doing this i used dropbox's objective c API they say to use in the documentation to download a file into a path on the system.
NSString *DocumentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
for (NSIndexPath *indexPath in [dropboxFilesTable indexPathsForSelectedRows]) {
DBMetadata *fileMetadata = [[dropboxFolderMetadata contents] objectAtIndex:indexPath.row];
[[self restClient] loadFile:fileMetadata.path intoPath:DocumentsPath];
}
the delegate for the dropbox says it is successfully put inside, but when i went back in, every folder and downloaded file has been deleted and that file is still not in the folder. i thought it would need the final path like "path to documents"/"filename", but then dropbox gives a error for that. Anyone know why its deleting all my files and not putting it in my documents?
The intoPath parameter needs to be a full filename path, not a directory. You need to update the last line to something like:
NSString *filename = [fileMetadata.path lastPathComponent];
NSString *destPath = [DocumentsPath stringByAppendingPathComponent:filename];
[[self restClient] loadFile:fileMetadata.path intoPath:destPath];
Also make sure that you are only doing this will files and not folders.

iOS : I can't write my file

I want to write a file on my iPhone app. My file is in my project's folder, but when I try to reach it :
NSString *myFile = [[NSBundle mainBundle] pathForResource:#"myFile" ofType:#"txt"];
NSLog(#"%#",myFile);
I get the following path :
2012-06-13 17:36:56.398 MyFileApp[610:15203] /Users/Damian/Library/Application Support/iPhone Simulator/5.1/Applications/1FFD4436-DCCA-4280-9E47-F6474BEE0183/MyFileApp.app/myFile.txt
Why ?
Thanks for your advices
You ask:
Why?
It's that path because that's where the file is stored.
On the device it will be different.
Note that you can't write a file to that folder anyway. You should perhaps instead write to your app's documents folder:
//Get the documents folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
//Get the final path of your file.
NSString *finalPath = #"myfile.txt"];
//And actually write that file.
[[NSFileManager defaultManager] createFileAtPath:finalPath contents:/*fileData as NSData*/ attributes:nil];
As already said you can't write to the main bundle on an actual device.
To your other question:
When you run your app in the simulator xcode will copy your project to a folder in your library directory .. in your case to:
/Users/Damian/Library/Application Support/iPhone Simulator/5.1/Applications/
Every app you run in your simulator has a folder there. Apps are not run in the folders where you actually edit your code.

Preloading Documents into iOS App

The Situation:
I have an iOS app that deals with files and lets the user save, edit, open and perform various operations with these files. I'd like to be able to have some pre-made documents for the user to look at when they open the app (ex. a template) alongside their own custom documents.
The Problem:
How can I create a document (or template file) and have it appear in the Documents folder after the user installs my app and launches it (and all preceding times)?
Background:
This document (the one that'd be installed into the app's documents directory) is created by me, not the user.
I know that to do this you need to save it in your bundle, and then when your app runs for the first time silently copy it into the Documents Directory. Should I copy it in the appDidFinishLaunchingWithOptions method or in my viewDidLoad method and write logic to detect if it's the first time the app has run?
My Code:
At this webpage: http://textsnip.com/d35fbc    
But when it runs, it always says: "File does not exist [in documents folder]", then it tells me that it's being copied. The problem is that when I examine the app's documents folder it is never there, it's still in the bundle.
Why won't it copy with this code
How does this work?
the files must in fact be added to the app bundle, then copied silently when the app launches.
The following code copies a text file from the top level of my bundle to the documents directory if it doesn't already exist.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *txtPath = [documentsDirectory stringByAppendingPathComponent:#"txtFile.txt"];
if ([fileManager fileExistsAtPath:txtPath] == NO) {
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"txtFile" ofType:#"txt"];
[fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error];
}
The only flaw in this code is that if the user deletes the file, it immediately reappears when they open the app again.
As you said, you include it in your app bundle (add it to your project and make sure it's part of your target). Then you can access it's path by calling something like this:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"MyTemplateDoc"
ofType:#"extension"];
Then you copy it to your app's documents folder.
NSString *docPath = <a path in your documents folder>
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:bundlePath
toPath:docPath
error:&error];
if (error) {
// handle copy error.
}

File write with [NSBundle mainBundle] fails

I am trying to take content from one file and write it into another. I am reading fine, but I am not able to write it into another file.
I have a database of words. I want to separate the words into different files based on the number of letters. All four letter words go into one file, and so on. I added a txt file called "4letter" into my resources and the following is my code:
NSError *error;
//READ
NSString *dbFile = [[NSBundle mainBundle] pathForResource:#"words" ofType:#"txt"];
NSString *test = [NSString stringWithContentsOfFile:dbFile encoding:NSUTF8StringEncoding error:&error];
//convert from string to array
NSArray *lines = [test componentsSeparatedByString:#"\n"];
NSFileHandle *logFile = nil;
logFile = [NSFileHandle fileHandleForWritingAtPath:[[NSBundle mainBundle] pathForResource:#"4letter" ofType:#"txt"]];
//Test if write works
for (int i=0; i<5; i++)
{
NSString *randomAnagram = [[lines objectAtIndex:i] lowercaseString];
[logFile writeData: [randomAnagram dataUsingEncoding: NSNEXTSTEPStringEncoding]];
}
In iOS, you can't write into a file in your app's bundle -- the entire bundle is read-only. Use a path into the Documents folder instead.
See special File System Programming Guide for better understnading.
In iOS, you can't write into a file in your app's bundle -- the entire bundle is read-only.
Consider reading iOS Data Storage Guidelines to better understand the purpose of directories below, in context of iCloud backup.
<Application_Home>/AppName.app
This is the bundle directory containing the app itself. Do not write
anything to this directory. To prevent tampering, the bundle directory
is signed at installation time. Writing to this directory changes the
signature and prevents your app from launching again.
<Application_Home>/Documents/
Use this directory to store critical user documents and app data
files. Critical data is any data that cannot be recreated by your app,
such as user-generated content. The contents of this directory can be
made available to the user through file sharing. The contents of this
directory are backed up by iTunes.
<Application_Home>/Library/
This directory is the top-level directory for files that are not user
data files. You typically put files in one of several standard
subdirectories but you can also create custom subdirectories for files
you want backed up but not exposed to the user. You should not use
this directory for user data files. The contents of this directory
(with the exception of the Caches subdirectory) are backed up by
iTunes. For additional information about the Library directory, see
“The Library Directory Stores App-Specific Files.”
See full list (tmp/, Documents/Inbox) in iOS Standard Directories: Where Files Reside
UPDATE
I use NSFileManager method URLForDirectory:inDomain:appropriateForURL:create:error:
Like Caleb said, you can't write to your app's directory, but you can write to your app's Documents folder. You can get it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Your app's bundle is read-only. There is two ways I could see:
1) Write in documents folder:
NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path =  [myPathList  objectAtIndex:0];
2) Use sqlite database. This is the same as 1 (you must save db in documents anyway), but you're using sqlite database. I think this is better than a lot of txt and plist files: here's a tutorial on the topic.
I use the following code :
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"set.txt"];
NSString *data=#"Kostas";
[data writeToFile:appFile atomically:YES];
NSString *myData = [NSString stringWithContentsOfFile:appFile];
NSLog(#"Data : %# ",myData);