3

ios claims the file has been written to, but the changes never actually save, as if they remain in buffer. Do I have to flush or something?

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *myFilePath = [[NSBundle mainBundle]
                            pathForResource:@"MyFile"
                            ofType:@"txt"];

    NSLog(@"\n\nPath = \n%@", myFilePath);

    NSString *myFileContents = [NSString stringWithContentsOfFile:myFilePath
                                    encoding:NSUTF8StringEncoding
                                    error:nil];


    NSLog(@"\n\nContents = \n%@", myFileContents);

    [@"This line will be written to file" writeToFile:myFilePath
        atomically:YES encoding:NSUTF8StringEncoding error:nil];

    NSString *changedContents = [NSString stringWithContentsOfFile:myFilePath
                                    encoding:NSUTF8StringEncoding
                                    error:nil];

    NSLog(@"\n\nChanged Contents = \n%@", changedContents);
}

Output:

Path = 
/Users/hamzeh/Library/Application Support/iPhone Simulator/5.1/Applications/2B318687-A745-4CD9-85BA-52A01AB76F6E/savepersistentdata_tutorial.app/MyFile.txt

Contents = 
This is a text file.
The file will be displayed on the iPhone.
That is all for now. 

Changed Contents = 
This line will be written to file

This is the output I get every time I run, so the changes don't actually get written to the file.

Thanks for the help.

peasant13337
  • 225
  • 1
  • 5
  • 8

3 Answers3

7

You can't edit files in your main bundle. You have to first save the file to the applications documents folder then make any changes.

Here's some code to maybe fix your issue:

First save the text to a directory you create:

NSString *myFilePath = [[NSBundle mainBundle]
                            pathForResource:@"MyFile"
                            ofType:@"txt"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *directory = [NSString stringWithFormat:@"%@/Some_Directory", [paths objectAtIndex:0]];

// Check if the directory already exists
if (![[NSFileManager defaultManager] fileExistsAtPath:directory]) {
    // Directory does not exist so create it
    [[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];
} 

NSData *data = [[NSData dataWithContentsOfFile:myFilePath] retain];

NSString *filePath = [[directory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", [myFilePath lastPathComponent]]] retain];



NSError *error = nil;
if (![data writeToFile:filePath options:NSDataWritingFileProtectionNone error:&error]) {
    [data writeToFile:filePath atomically:NO];
}
[data release];
[filePath release];
shabbirv
  • 8,958
  • 4
  • 33
  • 34
0

Use NO parameter

[@"This line will be written to file" writeToFile:myFilePath atomically:NO encoding:NSUTF8StringEncoding error:nil];

iOS docs says

(BOOL)useAuxiliaryFile
If YES, the receiver is written to an auxiliary file, and then the auxiliary file is renamed to path. If NO, the receiver is written directly to path. The YES option guarantees that path, if it exists at all, won’t be corrupted even if the system should crash during writing.

Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
  • That Didn't work for me but I figured it out. Instead of getting the file path the way I did above, i got it via: NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [docsDirectory stringByAppendingPathComponent:@"MyFile.txt"]; – peasant13337 May 20 '12 at 05:54
  • oh.. I missed it... yeah you write in document directory only, main bundle is read only... – Inder Kumar Rathore May 20 '12 at 06:06
0

You can not write file on main bundle, because resource bundle are read only. You can also check return of writeToFile method. Which returns false if you deploy it on device.

Abdullah Md. Zubair
  • 3,312
  • 2
  • 30
  • 39