The Man
The Man

Reputation: 1462

Saving Array To File Objective C

I've been stuck on this for ever and I finally figured it out and now just out of the blue it stopped working again...

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/scoreCards.dgs",documentsDirectory];

NSMutableArray *savedArrayOfScorecards = [[NSMutableArray alloc]init];
savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
[savedArrayOfScorecards addObject:currentScoreCard];

[savedArrayOfScorecards writeToFile:filePath atomically:YES];

The file scoreCards.dgs is not even getting created...

What am I doing wrong?

Upvotes: 1

Views: 5959

Answers (5)

Sulthan
Sulthan

Reputation: 130092

The correct answers are already here, just adding a better solution:

NSFileManager* fileManager = [NSFileManager defaultManager];
NSMutableArray* array;

if ([fileManager fileExistsAtPath:filePath]) {
    array = [NSMutableArray arrayWithContentsOfFile:filePath];

    NSAssert(array != nil, @"Invalid data in file.");
}
else {
    array = [[NSMutableArray] alloc] init];
}

[array addObject:currentScoreCard];
[array writeToFile:filePath atomically:YES];

Upvotes: 0

CodaFi
CodaFi

Reputation: 43330

NSMutableArray is not a property-list-compliant format. You must use an NSArchiver to make it plist compliant.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/scoreCards.dgs",documentsDirectory];

NSMutableArray *savedArrayOfScorecards = [[NSMutableArray alloc]init];
savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
[savedArrayOfScorecards addObject:@"ALLLAALLAAALLA"];

NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archive = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
[archive encodeObject:savedArrayOfScorecards forKey:@"Scorecards"];
[archive finishEncoding];

BOOL result = [data writeToFile:filePath atomically:YES];

NSLog(result ? @"YES" : @"NO");

enter image description here

Upvotes: 0

wildhemp
wildhemp

Reputation: 326

Your problem is, that although you create an array, before reading the file it is getting nil-ed on your call to:

savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];

So, because this savedArrayOfScorecards is now nil, your call to write it to a file is not doing anything. You should load the array to another variable, and check it being nil, and create the new array only if the one read from the file is nil. Something like this:

NSMutableArray *savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
if (!savedArrayOfScorecards) {
    savedArrayOfScorecards = [[NSMutableArray alloc]init];
}

Upvotes: 1

Michael Dautermann
Michael Dautermann

Reputation: 89509

There could be a couple things going wrong here.

1) The kind of data you're storing in the array might not be encodable or archive-able to a file. And the code snippet you included doesn't give a good hint as to what kind of data you're trying to save. If you have custom objects in your array (i.e. things that are not NSString, NSNumber, NSDate, etc.), then that's definitely the problem. There are plenty of questions here on StackOverflow that might help you solve this issue.

2) Your array's filepath could be bogus. For example, you're not checking to see if "documentsDirectory" is nil or valid or writeable.

3) Also possible, but not likely, "savedArrayOfScorecards" might be a nil array. You should do error checking to make sure "savedArrayOfScorecards" was instantiated and that there is more than one object in the array.

Upvotes: 2

Rengers
Rengers

Reputation: 15218

Are you sure the file exists when loading it?

savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];

This line creates a new NSMutableArray from the file. If the file does not exist, it returns nil. writeToFile is then sent to nil and nothing would happen.

Add a check to see if it's nil and create a new array if it is:

NSMutableArray *savedArrayOfScorecards = [NSMutableArray arrayWithContentsOfFile:filePath];
if(savedArrayOfScorecards == nil) savedArrayOfScorecards = [NSMutableArray array];
[savedArrayOfScorecards addObject:currentScoreCard];

[savedArrayOfScorecards writeToFile:filePath atomically:YES];

Upvotes: 0

Related Questions