access plist data - objective-c

i have a plist which goes like this:
<dict>
<key>11231654</key>
<array>
<string>hello</string>
<string>goodbye</string>
</array>
<key>78978976</key>
<array>
<string>ok</string>
<string>cancel</string>
</array>
i've load the plist using this:
NSString *path = [[NSBundle mainBundle] pathForResource:
#"data" ofType:#"plist"];
// Build the array from the plist
NSMutableArray *array3 = [[NSMutableArray alloc] initWithContentsOfFile:path];
how can i access each element of my plist?
i want to search for a matching key in the plist and than search with its child. how can i do this? any suggestion?
thks in advance!

Arrays are indexed. If you wanted to access the first object in an NSArray, you’d do the following:
id someObject = [array objectAtIndex:0];
If you know the object type, you could do it like this:
NSString *myString = [array objectAtIndex:0];
EDIT: You need to use an NSDictionary for the data that you have—note that it starts with a <dict> tag, not an <array> tag (though there are arrays as values).
NSString *path = [[NSBundle mainBundle] pathForResource:
#"data" ofType:#"plist"];
// Build the array from the plist
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *value = [dict valueForKey:#"11231654"];
Now you can do whatever you want with your array.

Here is a link to a discussion that provided a very good example of how to access your data and which type of storage schemes would be more beneficial under certain circumstances. #Jeff Kelley's solution is on target, I just thought this question would add an additional resource. Hope this helps!

This is how you need to create plist
Set root to array instead of dictionary , this will give you results in sequence.
With below lines of code you can fetch complete plist.
NSString *pathOfPlist = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
arrPlistValue = [[NSArray alloc]initWithContentsOfFile:path];
NSLog(#"Plist Value : %#",arrPlistValue);
After that you can fetch any specific content with below code:
NSString *strName = [[arrTempValue objectAtIndex:0] objectForKey:#"name"];
NSString *strImage = [[arrTempValue objectAtIndex:0] objectForKey:#"image"];
int idValue = [[[arrTempValue objectAtIndex:0] objectForKey:#"id"] integerValue];
BOOL isSubCat = [[[arrTempValue objectAtIndex:0] objectForKey:#"isSubCategory"] boolValue];
With this code you can fetch integer , string , boolean from plist.!

Related

Accessing a second NSDictionary in the plist?

I was wondering how I could access the second NSDictionary in my plist other then the root dictionary, what I would like is to have a string in the second dictionary to show up in the console right now I'm getting all of them. Here's my code, console and plist.
My Plist. (its name is Multi.plist)
My code.
NSString *pathForPlist = [[NSBundle mainBundle] pathForResource:#"Multi" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:pathForPlist];
NSLog(#"%#", [dict objectForKey:#"Abs"]);
And what my console is spitting out right now.
So after looking at that, I'll explain again what I would like, instead of having all of the contents of the Abs NSDictionary being in the console, I would like just to show the title string which lies within the Dictionary. Any help would be greatly appreciated.
Thanks
The Abs entry is a dictionary itself, so all you have to do is :
NSDictionary * abs = dict[#"Abs"];
NSLog(#"%#", abs[#"title"]);
NSDictionary *absDict = [dict objectForKey:#"Abs"]);
NSString *title = [absDict objectForKey:#"title"]);
NSLog(#"Title: %#", title);

Objective C - Using an integer value to identify data in a plist

I would like to start off by saying that I am a bit new to coding in general, but I am excited to learn. I am trying to get a label to cycle through the first four letters of the alphabet, which are stored as strings in a .plist file. The value will switch each time a button is pushed.
Here is the source code of the plist:
<dict>
<key>0</key>
<string>A</string>
<key>1</key>
<string>B</string>
<key>2</key>
<string>C</string>
<key>3</key>
<string>D</string>
I made the keys integers so that i can easily cycle through the values using the following code:
- (void)buttonPressed:(id)sender {
int x = 0;
NSString *path = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
theLabel_.text = [dict objectForKey:x];
x++;
}
This is not working at all. I suspect that the issue is in the line where I change the label's text. I do not believe I am using the "objectForKey" statement correctly with my integer value. How am I supposed to use an integer as a key to access plist data?
Property list dictionaries use strings as keys so you'd have to make strings out of your integer indexes:
theLabel_.text = [dict objectForKey:[NSString stringWithFormat:#"%d", x]];
A better way might be to use an array instead (also a plist object). Then all you'd have to change would be the access method:
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
theLabel_.text = [array objectAtIndex:x];
Your plist file would look like:
<array>
<string>A</string>
<string>B</string>
<string>C</string>
<string>D</string>
</array>

Reading from plist to NSArray

I am trying to read and I also need to write to a plist.
So far I am trying to simply read the contents in.
Here is my appSettings.plist:
NSBundle* bundle = [NSBundle mainBundle];
NSString* plistPath = [bundle pathForResource:#"appSettings" ofType:#"plist"];
NSDictionary *tmp = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
I tried to do this:
NSArray *mruItems = [[NSArray alloc] initWithArray:[tmp objectForKey:#"lastSearches"]];
But it throws an error. A check I did on the [tmp objectForKey:#"lastSearches"] type revealed this is not an NSArray...
How can I read the contents into my NSArray?
Thanks!
(I would love to have some info on writing too)
If you look at the screenshot above you see that it's pretty clear that "lastSearches" is a Dictionary, not a list. You can try to switch the type there to a Array type instead and it should work for you.
Another solution would be to iterate over the keys in that dictionary:
NSDictionary *lastSearches = [tmp objectForKey:#"lastSearches"];
for (NSString *key in lastSearches.allKeys)
{
NSString *value = [lastSearches objectForKey:key];
}
Note that this would not be in order, and you probably would have to sort before iterating over it.
Indeed it's not an array but a dictionary (look at your image).

Editing a plist in NSDictionary

I'm importing a plist into an NSDictionary object and want to change the contents of the plist once in the dictionary to lowercase. I have tried several different ways with no luck. Maybe I am supposed to edit the strings that are inside the NSDictionary, but then I don't know how to do that.
What I have currently imports the plist correctly, but the lowercaseString line effectively does nothing.
NSString *contents = [[NSBundle mainBundle] pathForResource:#"Assets/test" ofType:#"plist"];
NSString *newContents = [contents lowercaseString];
NSDictionary *someDic = [NSDictionary dictionaryWithContentsOfFile:newContents];
for (NSString *someData in someDic) {
NSLog(#"%# relates to %#", someData, [someDic objectForKey:someData]);
}
I NSLog'd the "content" string and it gave me a path value, so obviously changing that to a lowercaseString wouldn't do anything. I'm feeling like I have to access the strings within the dictionary.
This line
NSString *newContents = [contents lowercaseString];
is change the path string returned from
NSString *contents = [[NSBundle mainBundle] pathForResource:#"Assets/test" ofType:#"plist"];
so you will end up with something like ../assets/test.plist
you will need to walk through the contents of someDic an create a new dictionary based on the old turning strings into lowercase, if you are only concerned about values directly in someDic you can do something like
for( NSString * theKey in someDic )
{
id theObj = [someDic objectForKey:theKey];
if( [theObj isKindOfClass:[NSString class]] )
theObj = [theObj lowercaseString];
[theNewDict setObject:theObj forKey:theKey];
}

Write an array on.plist

I have a problem. I have this file dictionary .plist:
<plist version="1.0">
<dict>
<key>2</key>
<array>
<string>a</string>
<string>b</string>
<string>c</string>
</array>
</dict>
</plist>
So now I read this file in this way:
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"dictionary" ofType:#"plist"];
NSMutableDictionary *contentArray = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
NSMutableArray *dic = [contentArray objectForKey:#"2"];
NSLog(#"Numero di elementi del dictionary corrispondente a 2: %i", [dic count]);
for (int i = 0; i < [dic count]; ++i) {
NSString *temp = [dic objectAtIndex:i];
NSLog(#"Stringa = %#\n", temp);
}
Now I want to modify the array:
[dic replaceObjectAtIndex:0 withObject:#"ok"];
and I want to write it on the dictionary.plist and I try this:
[contentArray writeToFile:plistPath atomically:YES];
[contentArray release];
But this code doesn't work, and I receive an error, how can I do this?
Thanks
Since you didn't provide the error, I assume the problem might be that
NSMutableDictionary * contentArray = [NSMutableDictionary dictionaryWithContentsOfFile: plistPath];
only creates a mutable container (you can change the content of contentArray, but not the objects (leaves) inside of it.
If you want mutable leaves, use NSPropertyListSerialization instead:
NSMutableDictionary * contentArray = [NSPropertyListSerialization propertyListFromData: [NSData dataWithContentsOfFile: plistPath] mutabilityOption: NSPropertyListMutableContainersAndLeaves format: nil errorDescription: nil];