Reading data from a plist file - iphone

I'm trying to implement a Save State for my iPhone App.
I've got a plist file called SaveData.plist and I can read it in via the following
NSString *pListPath2 = [bundle pathForResource:#"SaveData" ofType:#"plist"];
NSDictionary *dictionary2 = [[NSDictionary alloc] initWithContentsOfFile:pListPath2];
self.SaveData = dictionary2;
[dictionary release];
The Plist file has members
SavedGame which is a Boolean to tell the app if there really is valid data here (if they did not exit the app in the middle of a game, I don't want their to be a Restore Point.
Score which is an NSNumber.
Time which is an NSNumber
Playfield which is a 16 element array of NSNumbers
How do I access those elements inside of the NSDictionary?

Try [NSDictionary objectForKey:]
Where Key is the name of the member in the plist.
For example:
BOOL save = [[dictionary2 objectForKey:#"SavedGame"] boolValue];
will store the object stored in the plist for the key SavedGame into a new BOOL named save.
I imagine that your SavedGame Boolean is actually stored in the NSDictionary as an NSNumber, hence the use of boolValue to get the Boolean Value of the NSNumber.
Try this documentation: Apple NSDictionary Reference.

For Setting Bool Value You can Use :
[Dictionary setBool:TRUE forKey:#"preference"];
For Getting Bool value you can use :
[Dictionary boolForKey:#"preference"];

Related

How to retrieve String from NSDictionary in objective C?

I am trying to retrieve the value for a key in a NSDictionary. The dictionary has been initialised with key value pairs both of type string. The trouble is, I cannot seem to retrieve the value with I call objectForKey or valueForKey.
I am able to iterate over the dictionary and print both keys and values.
Can someone point out where im going wrong? Here is my code...
//Set up dictionary with options
keys = [NSArray arrayWithObjects:#"red", #"blue", nil];
values = [NSArray arrayWithObjects:#"1.7", #"2.8", nil];
conversionOptions = [NSDictionary dictionaryWithObject:values
forKey:keys];
Then this is called on the select row in a picker
NSLog(#"... %#", [keys objectAtIndex:row]); //prints out the key
NSString *theString = [keys objectAtIndex:row]; //save it as a string
NSLog(#"The string is... %#", theString); //print it out to make sure im not going crazy
NSLog(#"the value is : %#",[conversionOptions objectForKey:theString]); // I just get NULL here
//NSLog(#"the value is : %#",[conversionOptions valueForKey:theString]); // This doesn't work either, I just get NULL
You're creating a dictionary with an array as the only key and an array for its value! You want the dictionaryWithObjects:forKeys: (plural) factory, not dictionaryWithObject:forKey: (singular) so that each element of the keys array will be used as a distinct key for the respective element of the values array.
I find the dictionaryWithObjectsAndKeys: factory to be more useful most of the time, e.g.:
conversionOptions = [NSDictionary dictionaryWithObjectsAndKeys:#"1.7", #"red", #"2.8", #"blue", nil];
This is how you retrieve a string from a dictionary object
NSString * string = [dictionary objectForKey:#"stringKey"];
Use objectForKey: not valueForKey:.
Make sure conversionOptions is non-nil when you call objectForKey: (which is the right method).
And, yeah, derp -- I missed that the wrong factory method was used. You could do dictionaryWithObjects:andKeys: or do what pmjordan said said.
You absolutely must use objectForKey:, though. valueForKey: is specific to KVC.

How to read all NSDictionary objects for a key to an array

I have a dictionary "playerDict" that reads data from a plist where there is names (myKey) with nine associated objects to each key.
I am trying to read all objects for a specific key (myKeys) into an NSMutableArray (theObjects). I have read the class reference and search internet but cannot figure our this, probably very simple, problem.
Among all other test i have done I have tried the following but that returns the key into theObjects and not the objects.
theObjects = [playerDict objectForKey:myKeys];
Anyone that could give a hint?
Here is the code that created the dict, i stripped it:
NSArray *objs = [NSArray arrayWithObjects:[NSNumber numberWithBool:playerObject.diffHard],[NSNumber numberWithBool:playerObject.diffMedium],
[NSNumber numberWithBool:playerObject.diffEasy],[NSNumber numberWithBool:playerObject.currentGame],
[NSNumber numberWithInt:playerObject.currentGameQuestion],[NSNumber numberWithInt:playerObject.currentGameRightAnswer],
[NSNumber numberWithInt:playerObject.currentGameType],[NSNumber numberWithInt:playerObject.nrOfType0Games],
[NSNumber numberWithInt:playerObject.type0Result], nil];
NSDictionary *newPlayerDict = [NSDictionary dictionaryWithObjectsAndKeys:objs, keyString, nil];
Try valueForKey:
You can only store one item per key in an NSDictionary. If you need story multiple items for the same key, you need to first add each of the items to an NSArray (or NSSet) that you instead then set as an object in your dictionary.
If might be useful if you posted the code that creates the dictionary.
Update: It looks like you are already doing this. So:
NSArray *myObjs=[playerDict objectForKey:keyString];
will get you your array. And this:
BOOL diffHard=[[myObjs objectAtIndex:0] boolValue];
BOOL diffMedium=[[myObjs objectAtIndex:1] boolValue];
Will get you the value you stored in the first and second objects of the array. Repeat it for the rest.

Retrieving data from a NSDictionary

I am not quite sure I understand how to do the following.
If I wanted to add e.g. an author and a title (key, value) to a dictionary. Fill that dictionary with data, then have another dictionary for say e.g. k = genre v = artist name and fill it with data.
Then I want to add the dictionaries to an array.
Firstly how is that done? and secondly, what if I allow the user to log their own entries. So I have to textfields on screen, when the user is done, it stores the fields as key value pair in a new dictionary e.g. user's dictionary.
What will I do later when trying to fill a tableview with the users entered data, I dont know the keys or values in that dictionary so how could I retrieve that data?
I mean let's say I want to load the user's dictionary from array index 2 and fill a tableview's cells with each dictionary entry, how is this done? Maybe a method like on an array(get entry.title at index blah blah ), get Key value in dictionary?
How else can one actually get loaded user entered data that they arent aware of the values?
Regards
Add author and title to a dictionary (assuming they're objects that already exist - likely NSString instances in your case):
NSMutableDictionary *books = [[NSMutableDictionary alloc] initWithCapacity:10];
[books setObject:title forKey:author];
Same thing for genre/artist:
NSMutableDictionary *music = [[NSMutableDictionary alloc] initWithCapacity:10];
[books setObject:artist forKey:genre];
Then put them in an array:
NSArray *theArray = [NSArray arrayWithObjects:books, music, nil];
Then to read out the stuff at array index 2:
id key;
NSDictionary *theDictionary = [theArray objectAtIndex:2];
id value;
for (key in [theDictionary allKeys])
{
value = [theDictionary objectForKey:key];
// do something with the value
}
You can get an NSArray of keys in the dictionary using allKeys. Then you can retrieve the values using objectForKey:
for (id key in [myDict allKeys]) {
NSLog(#"key: %#, value: %#", key, [dictionary objectForKey:key]);
}

NSUserDefaults won't save NSDictionary

I'm writing an application which uses NSUserDefaults as the data storage mechanism, and am hitting a problem when trying to save data (that conforms to the Property List protocols):
+ (BOOL)storeAlbum:(Album *)album
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *albums = (NSMutableDictionary *)[prefs objectForKey:#"my_adventure_book_albums"];
NSLog(#"Existing albums: %#",albums);
if (!albums)
albums = [NSMutableDictionary dictionaryWithObject:album forKey:#"album"];
else
[albums setObject:album forKey:#"album"];
NSLog(#"%#",album);
[prefs setObject:albums forKey:#"my_adventure_book_albums"];
return [prefs synchronize];
}
I get this output:
2010-06-29 17:17:09.929 MyAdventureBook[39892:207] Existing albums: (null)
2010-06-29 17:17:09.930 MyAdventureBook[39892:207] test
2010-06-29 17:17:09.931 MyAdventureBook[39892:207] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
album = test;
}' of class 'NSCFDictionary'.
The description method of Album looks like:
- (NSString *)description
{
// Convert to a NSDictionary for serializing
if (!title) title = #"";
if (!date) date = [NSDate dateWithTimeIntervalSinceNow:0];
if (!coverImage) coverImage = #"";
if (!images) images = [[NSArray alloc] initWithObjects:#"",nil];
//NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,date,coverImage,images,nil] forKeys:[NSArray arrayWithObjects:#"title",#"date",#"coverImage",#"images",nil]];
//NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:title,nil] forKeys:[NSArray arrayWithObjects:#"title",nil]];
//return [dict description];
return #"test";
}
All of the commented-out lines have the same result, so I just decided to see if the NSString "test" would work, which it (of course) doesn't.
But the object you put inside the dictionary, an Album* is most likely not a property list object, is it? Every object, all the way down, needs to be a property list object for this to work. A description method isn't good enough to make this happen.
As a workaround, you can use NSCoding and an NSKeyedArchiver to write out your dictionary to an NSData, which you can store among the preferences.
You can only put basic foundation types into a property list. NSUserDefaults writes preferences out as a property list. See here for property list allowed types. In a nutshell, it is numbers, strings, data, dates, and arrays and dictionaries of those. Dictionaries must have string keys.
NSUserDefaults always returns immutable objects, so you can't just cast them to mutable. Do [prefs objectForKey:#"my_adventure_book_albums"] mutableCopy] (and remember to release it when finished).

Looping through values in NSDictionary throws fault

I have a plist file that I am loading into an NSDictionary *setDictionary that contains a set of fields, pictureDesc1, pictureDesc2, etc.
Once the NSDictionary is loaded, I can retrieve a value using
[setDictionary objectForKey:#"pictureDesc1"];
But I cannot do a loop like this:
for (int i=1; i<=numberOfPictures; i++) {
NSString *keyName = [NSString stringWithFormat:#"pictureDesc%d",i];
NSString *description = [NSString stringWithFormat:#"%#", [setDictionary objectForKey:keyName]];
}
Is there a different way to dynamically call keys from within an NSDictionary?
If you keys fit a numerical pattern, then it would be easier and more robust to simply store them in a array. You could even store an array as a value in the dictionary with the key of "pictureDescription".
Then when you wanted to loop through them just use a simple numerical loop:
NSArray *pictArray=[setDictionary valueForKey:#"pictureDescription"];
NSString *description;
for (i=0;i<[pictArray count];i++){
description=[pictArray objectAtIndex:i];
//... do whatever
}
If you find yourself shoehorning the functionality of an array into a dictionary or vice versa you probably should back out and just use an array or dictionary in the first place. When using a dictionary, just use an enumerator to step through the values.