3

Pulling my hair out trying to work this out. i want to read and write a list of numbers to a txt file within my project. however [string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error] doesnt appear to write anything to the file. I can see there is the path string returns a file path so it seems to have found it, but just doesnt appear to write anything to the file.

+(void)WriteProductIdToWishList:(NSNumber*)productId {

    for (NSString* s in [self GetProductsFromWishList]) {
        if([s isEqualToString:[productId stringValue]]) {
            //exists already
            return;
        }
    }

    NSString *string = [NSString stringWithFormat:@"%@:",productId];   // your string
    NSString *path = [[NSBundle mainBundle] pathForResource:@"WishList" ofType:@"txt"];
    NSError *error = nil;
    [string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
    NSLog(@"%@", error.localizedFailureReason);


    // path to your .txt file
    // Open output file in append mode: 
}

EDIT: path shows as /var/mobile/Applications/CFC1ECEC-2A3D-457D-8BDF-639B79B13429/newAR.app/WishList.txt so does exist. But reading it back with:

NSString *path = [[NSBundle mainBundle] pathForResource:@"WishList" ofType:@"txt"];

returns nothing but an empty string.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
user987723
  • 945
  • 3
  • 12
  • 33
  • Is it any specific requirement to write the info as txt itself. It would be better if you write it as a plist for more ease of usage. – Anupdas May 10 '13 at 17:03
  • Do you want to store those files in a subdirectory relative to the project's main dir? – nzs May 10 '13 at 18:08

2 Answers2

10

You're trying to write to a location that is inside your application bundle, which cannot be modified as the bundle is read-only. You need to find a location (in your application's sandbox) that is writeable, and then you'll get the behavior you expect when you call string:WriteToFile:.

Often an application will read a resource from the bundle the first time it's run, copy said file to a suitable location (try the documents folder or temporary folder), and then proceed to modify the file.

So, for example, something along these lines:

// Path for original file in bundle..
NSString *originalPath = [[NSBundle mainBundle] pathForResource:@"WishList" ofType:@"txt"];
NSURL *originalURL = [NSURL URLWithString:originalPath];

// Destination for file that is writeable
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *documentsURL = [NSURL URLWithString:documentsDirectory];

NSString *fileNameComponent = [[originalPath pathComponents] lastObject];
NSURL *destinationURL = [documentsURL URLByAppendingPathComponent:fileNameComponent];

// Copy file to new location
NSError *anError;
[[NSFileManager defaultManager] copyItemAtURL:originalURL
                                        toURL:destinationURL
                                        error:&anError];

// Now you can write to the file....
NSString *string = [NSString stringWithFormat:@"%@:", yourString]; 
NSError *writeError = nil;
[string writeToFile:destinationURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(@"%@", writeError.localizedFailureReason);

Moving forward (assuming you want to continue to modify the file over time), you'll need to evaluate if the file already exists in the user's document folder, making sure to only copy the file from the bundle when required (otherwise you'll overwrite your modified file with the original bundle copy every time).

isaac
  • 4,867
  • 1
  • 21
  • 31
2

To escape from all the hassle with writing to a file in a specific directory, use the NSUserDefaults class to store/retrieve a key-value pair. That way you'd still have hair when you're 64.

Community
  • 1
  • 1
ott--
  • 5,642
  • 4
  • 24
  • 27
  • NSUserDefaults is a good choice. For an introductory SO help, check my accepted answer with helpful code snippets on NSUserDefaults: http://stackoverflow.com/questions/16475300/storing-results-after-screen-is-disappear/16476022#16476022 – nzs May 10 '13 at 18:03
  • NSUserDefaults could be a good choice, but the question (vaguely, to me at least) implies that the text file in the application bundle may already be populated with data. – isaac May 10 '13 at 20:25