NSMutableString returns null - objective-c

I'm trying to construct a string from the file names in my app's document folder.
So far I have:
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [directoryPaths objectAtIndex:0];
NSError *error = nil;
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error];
NSLog(#"contents of document folder = %#", directoryContent);
This prints:
contents of app's document folder = (
".DS_Store",
File1.doc,
"File2.pdf",
....
)
I'd like to construct a string of file names, separated in some way, perhaps by semi-colon and attempted it (initially without any separation) via this code:
NSMutableString *fileList;
for (NSString *folder in directoryContent)
{
[fileList appendString:[NSString stringWithFormat:#"%#", folder]];
}
NSLog(#"file list = %#", fileList);
This prints file list = (null), and I can't figure out where I'm going wrong. Any ideas?

You shold initialize the MutableString before adding strings. NSMutableString* fileList = [[NSMutableString alloc] init ];

Related

.m file to string

I am trying to convert a .m file to string. I will search for files in a folder and then want to use each of its contents as a string. This is the code I am using:
- (IBAction)searchAction:(id)sender {
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:folderLabel.stringValue error:nil];
NSPredicate *fltr = [NSPredicate predicateWithFormat:#"self ENDSWITH '.m'"];
NSArray *onlyMs = [dirContents filteredArrayUsingPredicate:fltr];
for (int i=0; i<[onlyMs count]; i++) {
NSString* text = [[NSString alloc] initWithContentsOfFile:[onlyMs objectAtIndex:i]
encoding:NSUTF8StringEncoding
error:nil];
NSLog(#"string: %#", text);
}
}
2013-02-13 02:38:05.700 LocalizedStringSearch[19001:303] string: (null)
Except here, all the log is returning is null even though it will find all the .m file correctly.
Anyone know what I'm doing wrong?
Thanks a lot!
I think contentsOfDirectoryAtPath: gives you an array of filenames only, not full path names, so you need to prepend the path before you open files. EDIT: I think I might be confusing that with enumeratorAtPath:... if so continue using the filenames you have rather than appending them to the original folder name.
Here's an example (untested):
NSString *fullPath = [folderLabel.stringValue stringByAppendingPathComponent:[onlyMs objectAtIndex:i];
NSError *error = nil;
NSString *text = [[NSString alloc] initWithContentsofFile:fullPath
encoding:NSUTF8StringEncoding
error:&error];
if (text == nil)
NSLog(#"%#", error);
else
NSLog(#"%#", text);
The above will only work if the files actually are encoded using UTF-8. If you are unsure of the encoding, you can let the framework try and figure it out for you with:
NSString *fullPath = [folderLabel.stringValue stringByAppendingPathComponent:[onlyMs objectAtIndex:i];
NSError *error = nil;
NSStringEncoding enc;
NSString *text = [[NSString alloc] initWithContentsofFile:fullPath
usedEncoding:&enc
error:&error];
if (text == nil)
NSLog(#"%#", error);
else
NSLog(#"%#", text);

Renaming an existing file with Obj-C

I've seen this question asked a few times but I have been unable thus far to achieve success using any of the post solutions. What I am trying to do is rename a file in the local storage of an app (also kind of new to Obj-c). I am able to retrieve the old path and create the new path, but what would I have to write in order to actually change the files name?
What I have thus far is:
- (void) setPDFName:(NSString*)name{
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* initPath = [NSString stringWithFormat:#"%#/%#",[dirPaths objectAtIndex:0], #"newPDF.pdf"];
NSString *newPath = [[NSString stringWithFormat:#"%#/%#",
[initPath stringByDeletingLastPathComponent], name]
stringByAppendingPathExtension:[initPath pathExtension]];
}
NSError *error = nil;
[[NSFileManager defaultManager] moveItemAtPath:initPath toPath:newPath error:&error];
The code is very messy; try this:
- (BOOL)renameFileFrom:(NSString*)oldName to:(NSString *)newName
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
NSString *oldPath = [documentDir stringByAppendingPathComponent:oldName];
NSString *newPath = [documentDir stringByAppendingPathComponent:newName];
NSFileManager *fileMan = [NSFileManager defaultManager];
NSError *error = nil;
if (![fileMan moveItemAtPath:oldPath toPath:newPath error:&error])
{
NSLog(#"Failed to move '%#' to '%#': %#", oldPath, newPath, [error localizedDescription]);
return NO;
}
return YES;
}
and call this using:
if (![self renameFileFrom:#"oldName.pdf" to:#"newName.pdf])
{
// Something went wrong
}
Better still, put the renameFileFrom:to: method into a utility class and make it a class method so it can be called from anywhere in your project.

write NSString to file

I'm trying to write a string to a file and store that in the applicationSupport folder within my app. But my NSLog() statement doesn't log anything in the debugger. I have tried to go through it with the debugger, and i can see that the content is nil, so i'm guessing that's why it's not outputting anything, but i don't know why it's set to nil. Can anybody see my mistake?
NSString *document = [[[[[[[[description stringByAppendingString:#" "]stringByAppendingString:focus]stringByAppendingString:#" "]stringByAppendingString:level]stringByAppendingString:#" "]stringByAppendingString:equipment]stringByAppendingString:#" "]stringByAppendingString:waterDepth];
//NSLog(#"%#", document);
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *supportDirectory = [paths objectAtIndex:0];
//filename
NSString *filename = [NSString stringWithFormat:[_nameTextField.text stringByAppendingString:#".txt"], supportDirectory];
[document writeToFile:filename atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
NSString *content = [[NSString alloc]initWithContentsOfFile:filename usedEncoding:nil error:nil];
NSLog(#"%#", content);
filename is wrong. It should have the following format: "directory/file.extension". You can use the methods stringByAppendingPathComponent and stringByAppendingPathExtension to construct such a string.
NSString *filename = [supportDirectory stringByAppendingPathComponent:[_nameTextField.text stringByAppendingPathExtension:#"txt"]];
Also, as a side note, the first line should be rewritten using stringWithFormat like this:
NSString *document = [NSString stringWithFormat:#"%# %# %# %# %#", description, focus, level, equipment, waterDepth];
You have wrong initialize filename. It should be:
NSString *filename = [NSString stringWithFormat:#"%#/%#", supportDirectory,[_nameTextField.text stringByAppendingString:#".txt"]];
it will works! Good luck:)
The
NSString *filename = [NSString stringWithFormat:[_nameTextField.text stringByAppendingString:#".txt"], supportDirectory];
is wrong. It should be:
NSString *filename = [NSString stringWithFormat:"%#%#",[_nameTextField.text stringByAppendingString:#".txt"], supportDirectory];

iPad app - generating text file

Can someone explain and give example code to do the following steps in my iPad app:
do some things in my app, which generates some data (as a string)
write that data to a text file
be able to plug in my iPad to my computer and grab those text files off
How can I do this?
For writing string in a file use this
NSString *str = #"your string";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:#"data.txt"];
NSError *error;
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
Then set Application supports iTunes file sharing key to YES in your plist file.
When you connect your device with iTunes from there you can save your data.txt
Here is the video how to get files from iTunes
Edited as requested.
NSUserDefaults *deflt = [NSUserDefaults standardUserDefaults];
//this number file is saved, I'm not saving the file name as data0.txt.
//The first file to be saved is data1.txt
int num = [deflt integerForKey:#"fileNameNum"];
num++;
NSString *fileName = [NSString stringWithFormat:#"data%d.txt",num];;
NSString *str = #"your string";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSError *error = nil;
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error == nil) {
//Save the number of the file that you have save in doc directory
[deflt setInteger:num forKey:#"fileNameNum"];
}

Rename file in Cocoa?

How would I rename a file, keeping the file in the same directory?
I have a string containing a full path to a file, and a string containing a the new filename (and no path), for example:
NSString *old_filepath = #"/Volumes/blah/myfilewithrubbishname.avi";
NSString *new_filename = #"My Correctly Named File.avi";
I know about NSFileManager's movePath:toPath:handler: method, but I cannot workout how to construct the new file's path..
Basically I'm looking for the equivalent to the following Python code:
>>> import os
>>> old_filepath = "/Volumes/blah/myfilewithrubbishname.avi"
>>> new_filename = "My Correctly Named File.avi"
>>> dirname = os.path.split(old_filepath)[0]
>>> new_filepath = os.path.join(dirname, new_filename)
>>> print new_filepath
/Volumes/blah/My Correctly Named File.avi
>>> os.rename(old_filepath, new_filepath)
NSFileManager and NSWorkspace both have file manipulation methods, but NSFileManager's - (BOOL)movePath:(NSString *)source toPath:(NSString *)destination handler:(id)handler is probably your best bet. Use NSString's path manipulation methods to get the file and folder names right. For example,
NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] movePath:oldPath toPath:newPath handler:nil];
Both classes are explained pretty well in the docs, but leave a comment if there's anything you don't understand.
It's worth noting that moving a file to itself will fail. I had a method that replaced spaces with underscores and made the file name lowercase and renamed the file to the new name. Files with only one word in the name would fail the rename as the new name would be identical on a case-insensitive file system.
The way I resolved this was to do a two step rename, first renaming the file to a temporary name and then renaming it to the intended name.
Some pseudocode explaining this:
NSString *source = #"/FILE.txt";
NSString *newName = [[source lastPathComponent] lowercaseString];
NSString *target = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newName];
[[NSFileManager defaultManager] movePath:source toPath:target error:nil]; // <-- FAILS
The solution:
NSString *source = #"/FILE.txt";
NSString *newName = [[source lastPathComponent] lowercaseString];
NSString *temp = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#-temp", newName]];
NSString *target = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newName];
[[NSFileManager defaultManager] movePath:source toPath:temp error:nil];
[[NSFileManager defaultManager] movePath:temp toPath:target error:nil];
I just wanted to make this easier to understand for a newbie. Here's all the code:
NSString *oldPath = #"/Users/brock/Desktop/OriginalFile.png";
NSString *newFilename = #"NewFileName.png";
NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] movePath:oldPath toPath:newPath handler:nil];
NSLog( #"File renamed to %#", newFilename );
here's a more recent example for iOS, the NSFileManager method is a little different:
NSString *newFilename = [NSString stringWithFormat:#"%#.m4a", newRecording.title];
NSString *newPath = [[newRecording.localPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] moveItemAtPath:newRecording.localPath toPath:newPath error:nil];
For the icing on top, a category on NSFileManager:
#implementation NSFileManager (FileManipulations)
- (void)changeFileNamesInDirectory:(NSString *)directory changeBlock:(NSString * (^) (NSString *fileName))block
{
NSString *inputDirectory = directory;
NSFileManager *fileManager = [NSFileManager new];
NSArray *fileNames = [fileManager contentsOfDirectoryAtPath:inputDirectory error:nil];
for (NSString *fileName in fileNames) {
NSString *newFileName = block(fileName);
NSString *oldPath = [NSString stringWithFormat:#"%#/%#", inputDirectory, oldFileName];
// move to temp path so case changes can happen
NSString *tempPath = [NSString stringWithFormat:#"%#-tempName", oldPath];
NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFileName];
NSError *error = nil;
[fileManager moveItemAtPath:oldPath toPath:tempPath error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
return;
}
[fileManager moveItemAtPath:tempPath toPath:newPath error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
}
}
}
#end