View Full Version : Write Dict to a File
Depress
Jun 22, 2009, 07:16 AM
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:
- (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:
robbieduncan
Jun 22, 2009, 07:28 AM
I can't see any obvious errors with that. Have you tried changing the parameter atomically: to NO?
PhoneyDeveloper
Jun 22, 2009, 10:11 AM
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?
robbieduncan
Jun 22, 2009, 10:45 AM
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.
Luke Redpath
Jun 22, 2009, 11:02 AM
As a side note, that code is going to leak:
NSString* location = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingString:@"/Storage.dat"]];
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithContentsOfFile: location];
should be:
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.
kainjow
Jun 22, 2009, 11:05 AM
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.
eddietr
Jun 22, 2009, 04:08 PM
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.
Depress
Jun 23, 2009, 01:41 AM
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?
robbieduncan
Jun 23, 2009, 01:45 AM
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:
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;
Luke Redpath
Jun 23, 2009, 06:09 AM
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.
robbieduncan
Jun 23, 2009, 06:43 AM
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.
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.