6
votes

I am trying to write a very basic text string to my documents directory and work from there to later save other files etc.

I am currently stuck with it not writing anything into my Documents directory

(In my viewDidLoad)

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];

NSString *textPath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];
NSString *text = @"My cool text message";

[[NSFileManager defaultManager] createFileAtPath:textPath contents:nil attributes:nil];
[text writeToFile:textPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
NSLog(@"Text file data: %@",[[NSFileManager defaultManager] contentsAtPath:textPath]);

This is what gets printed out:

2011-06-27 19:04:43.485 MyApp[5731:707] Text file data: (null)

If I try this, it also prints out null:

NSLog(@"My Documents: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL]);

What have I missed or am I doing wrong while writing to this file? Might it be something I need to change in my plist or some frameworks/imports needed?

Thanks

[EDIT] I passed a NSError object through the writeToFile and got this error:

Error: Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x12aa00 {NSFilePath=/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/Documents/file1.txt, NSUnderlyingError=0x14f6b0 "The operation couldn’t be completed. Not a directory"}

[EDIT 2] This works fine on the simulator but not on my phone :/

5
First thing you should do is see if your write operation is producing any errors. In the call to writeToFile:, pass in an NSError object and check for errors after the call.keno
Try [text writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:NULL];. Note the difference here is you are doing an atomic write. Have a look at the Apple Docs for [NSString writeToFile:atomically:encoding:error:] to see the reasoning behind it. Also, since the error is complaining about a directory, debug you app on the device to see what the path for the file looks like.keno
I also did try changing the atomic value but it made no difference.Pangolin
Well, I just tried your code as is on my machine and on an iPad and both work :-/. Not sure what to tell you, except maybe try the same code on another device and see if you get the same results. From the error, it seems the problem is the file path can't be accessed. If you can find some way to access the file system directly to verify the structure that might help (programmatically or otherwise). I googled and found Phone Disk. I have not tried this so don't flame me if it screws up your device :) ... If you do find a solution do post the answer to help others.keno

5 Answers

2
votes

Instead of using NSFileManager to get the contents of that file, try using NSString as such:

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];
NSError *error = nil;
NSString *str = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
    NSLog(@"There was an error: %@", [error description]);
} else {
    NSLog(@"Text file data: %@", str);
}

Edit: Added error checking code.

1
votes

How are you getting documentsDirectory?

You should be using something like this:

NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

NSString *documentsDirectory = [pathArray lastObject];
0
votes

Put an NSLog statement after every line where you are setting a variable's value, so that you can inspect those values. This should help you quickly pinpoint where things start to go wrong.

0
votes

The problem got solved by setting a non standard Bundle ID in die info.plist

I used the Bundle ID from iTunes Connect for this specific app. Now everything works perfectly.

0
votes

You can also use NSFileHandle for writing data in file and save to document directory:

Create a variable of NSFileHandle

NSFileHandle *outputFileHandle;

use the prepareDataWrittenHandle function with passing file name in parameter with file extension

-(void)prepareDataWrittenHandle:(NSString *)filename
{
    //Create Path of file in document directory.
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:filename];

    //Check file with above name is already exits or  not.
    if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath] == NO) {
        NSLog(@"Create the new file at outputFilePath: %@", outputFilePath);

        //Create file at path.
        BOOL suc = [[NSFileManager defaultManager] createFileAtPath:outputFilePath
                                                           contents:nil
                                                         attributes:nil];
        NSLog(@"Create file successful?: %u", suc);
    }

    outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:outputFilePath];
}

then write the string value to file as:

//Create a file
[self prepareDataWrittenHandle:@"file1.txt"];

//String to save in file
NSString *text = @"My cool text message";

//Convert NSString to NSData to save data in file.
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]

//Write NSData to file
[_outputFileHandle writeData:data];

//close the file if written complete
[_outputFileHandle closeFile];

at the end of file written you should close the file.

You can also check the content written in file as NSString for debug point of view as mention above by @Glenn Smith:

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:@"file1.txt"];

NSError *error;
NSString *str = [NSString stringWithContentsOfFile:outputFilePath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
    NSLog(@"There was an error: %@", [error description]);
} else {
    NSLog(@"Text file data: %@", str);
}