views:

664

answers:

3

Hi,

I have a main dictionary where each entry is a dictionary. I need to save this to a plist and then later retrieve its contents.

This is what I am doing to save the dictionary

// create a dictionary to store a fruit's characteristics
NSMutableDictionary *fruit = [[NSMutableDictionary alloc] init];
[fruit setObject:quantity forKey:@"quantity"];
[fruit setObject:productID forKey:@"productID"];
[fruit setObject:nameID forKey:@"nameID"];

// create a dictionary to store all fruits
NSMutableDictionary *stock = [[NSMutableDictionary alloc] init];
[stock setObject:fruit forKey:@"nameID"];

... after adding all fruits to the stock dictionary, write the stock to a plist

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"stock.plist"];

NSMutableDictionary *stock = [NSMutableDictionary dictionaryWithContentsOfFile:path];
[stock writeToFile:path atomically:YES];

... to restore the dictionary, I use

NSMutableDictionary *stock = [NSMutableDictionary dictionaryWithContentsOfFile:path];

... but this is not saving anything to the file... what am I missing?

thanks for any help.

+2  A: 

dictionaryWithContentsOfFile doesn't save, it reads a file. I don't see any code which writes to the file.

You are going to need something like this in your save code:

[stock writeToFile:path atomically:YES];
marcc
+1  A: 

You're (re-)creating stock with the contents of the file immediately before writing it. Since the file doesn't exist, the dictionary is now nil. When you attempt to write that out, it doesn't produce anything. Instead, you should use the version of stock that you already populated.

(Assuming the saving bit is in the same scope, just delete the line starting NSMutableDictionary *stock above the call to writeToFile.)

(Although, come to think of it, it can't be in the same scope or the compiler would have complained in the first place.)

walkytalky
+2  A: 

You write:

... after adding all fruits to the stock dictionary, write the stock to a plist

but your code is reading from disk before you write the stock dictionary to disk. So with the assumption that stock.plist doesn't actually exist at that path, you've just set stock to nil, so after that you're sending the writeToFilePath message to nil.

try this:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"stock.plist"];
// write plist to disk
[stock writeToFile:path atomically:YES];

// read it back in with different dictionary variable
NSMutableDictionary *savedStock = [NSMutableDictionary dictionaryWithContentsOfFile:path];
if( savedStock==nil ){
    NSLog(@"failed to retrieve dictionary from disk");
}

Finally, what data types are quantity and productID? you cannot serialize non-object data types, so if quantity is an integer, you would need to wrap it like so:

[fruit setObject:[NSNumber numberWithInt:quantity] forKey:@"quantity"];

Spend some time reading about property list serialization.

wkw
thanks!!! will this line [stock writeToFile:path atomically:YES];serialize and save a dictionary of dictionaries to a file? and will the dictionaryWithContentsOfFile read the same structure back?
Digital Robot