1

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?

The Man
  • 1,462
  • 3
  • 23
  • 45

5 Answers5

2

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.

Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
1

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];
}
wildhemp
  • 326
  • 1
  • 4
  • the only reason it would be nil is if the contents of the file path were nil themselves, which if he archived, wouldn't be true. – CodaFi Jun 22 '12 at 15:49
  • @CodaFi There is another reason -> NSArray couldn't parse the contents of the file because they contained invalid objects or something. – borrrden Jun 23 '12 at 14:15
  • Apple documentation says the following: "Returns nil if the file can’t be opened or if the contents of the file can’t be parsed into an array." So if the file is not there, and therefore can't be opened, arrayWithContentsOfFile would return nil. – wildhemp Jun 23 '12 at 15:39
0

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];
Rengers
  • 14,911
  • 1
  • 36
  • 54
0

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

CodaFi
  • 43,043
  • 8
  • 107
  • 153
0

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];

Sulthan
  • 128,090
  • 22
  • 218
  • 270