Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Depress

macrumors newbie
Original poster
Jun 22, 2009
4
0
Hi guys,

I try to write contents of a dictionary to a file. I use the following code. The paths checkout to be valid. But the functions returns a no.
Could it be that the file Storage.dat not is created yet.. Because i can't access my device filesystem. On the simulator it also doesn't work.

What am i doing wrong; i have the following code:
Code:
- (int) saveData:(NSString*)EntityName :(NSString*)EntityData
{
	NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];
	NSString* location = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingString:@"/Storage.dat"]];
	NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithContentsOfFile: location];
	[data setObject:EntityData forKey: EntityName];
	if(![data writeToFile: location atomically: YES])
		return 0;
	return 1;
}

Please help:cool:
 
There are some restrictions on the kinds of data that can be in a dictionary or array in order for it to be able to be written out to a file. I think the restriction is that it has to implement NSCoding. Does your EntityData implement NSCoding? What happens if you just read in the dictionary from the file and write it out without adding EntityData?
 
There are some restrictions on the kinds of data that can be in a dictionary or array in order for it to be able to be written out to a file. I think the restriction is that it has to implement NSCoding. Does your EntityData implement NSCoding? What happens if you just read in the dictionary from the file and write it out without adding EntityData?

Both are declared as NSString in the method signature so they should be OK.
 
As a side note, that code is going to leak:

Code:
NSString* location = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingString:@"/Storage.dat"]];
	NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithContentsOfFile: location];

should be:

Code:
NSString *location = [documentsDirectory stringByAppendingString:@"/Storage.dat"];
NSMutableDictionary *data = [NSMutableDictionary dictionaryWithContentsOfFile:location];

On the other hand, if you don't want to use autoreleased objects, you'll need to explicitly release the objects instead.
 
Even if the path is valid, I would use stringsByAppendingPathComponent instead of stringByAppendingString so that you don't have to deal with the forward slash.
 
So I'm not sure if you got this already, but the reason this doesn't work is because "data" is nil after the call to - [NSDictionary initWithContentsOfFile]. (This is because the file doesn't yet exist.)

So then the rest of the calls to [data whatever] don't do a thing.

Hope that helps.
 
So the file doesn't exists yet, how should i create the file then? With a string object it is also not going to work, since there is still no file.

How do i create that (empty) file?
 
So the file doesn't exists yet, how should i create the file then? With a string object it is also not going to work, since there is still no file.

How do i create that (empty) file?


Create an empty NSMutableDictionary on the first run/when the load from file creates a nil reference and use that instead of the load from file:

Code:
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithContentsOfFile: location];
if (data == nil)
{
	data = [NSMutableDictionary dictionary];
}
[data setObject:EntityData forKey: EntityName];
if(![data writeToFile: location atomically: YES])
	return 0;
return 1;
 
A minor niggle but its probably not a good idea to conditionally set the data pointer to either an autoreleased or non-autoreleased object; for consistency I'd make the initial dictionary loaded from the file autoreleased (I'm pretty sure there is a convenience class method dictionaryWithContentsOfFile) too.

Apart from that, that's exactly how you want to do it.
 
A minor niggle but its probably not a good idea to conditionally set the data pointer to either an autoreleased or non-autoreleased object; for consistency I'd make the initial dictionary loaded from the file autoreleased (I'm pretty sure there is a convenience class method dictionaryWithContentsOfFile) too.

Apart from that, that's exactly how you want to do it.

Sure, I'd agree with that.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.