Access a dictionary key from another dictionary in plist - ios

I want to have access to the dealer name from the plist.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Cars" ofType:#"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
NSMutableArray *dealers = [[NSMutableArray alloc] init];
for (NSDictionary *object in array) {
Dealer *dealer = [[Dealer alloc] initWithDictionary:object];
[dealers addObject:dealer];
}
self.dealers = dealers;
From this, i access just the first dictionary from plist

The first NSDictinonary in you plist has Item 0 key that store Dealer NSDictinonary. Change your string code
Dealer *dealer = [[Dealer alloc] initWithDictionary:object];
to this
Dealer *dealer = [[Dealer alloc] initWithDictionary:object[#"Dealer"]];

i recommend you check the variables-array,object

Related

Dictionary from plist

i have 3 plist files with named level0, level1, level2, all of this plist have the same structure, it consist of number variable and array. I init my app with data from this plist.
+(instancetype)levelWithNum:(int)levelNum; {
NSString* fileName = [NSString stringWithFormat:#"level%i.plist", levelNum];
NSString* levelPath = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:fileName];
NSDictionary *levelDic = [NSDictionary dictionaryWithContentsOfFile:levelPath];
NSAssert(levelDic, #"level no loaded");
Level *l = [[Level alloc]init];
l.coinsPerLvl = [levelDic[#"coinsPerLvl"] integerValue];
l.words = levelDic[#"words"];
return l;
}
Now i decide to use only one plist and add in it 3 dictionary. How can i read only one dictionary from plist like in example above where i use plist files.
Tanks for any help!
you only need an intermediate variable thats represents the root dictionary and extract the level dictionary from the root dictionary, e.g:
+(instancetype)levelWithNum:(int)levelNum; {
NSString *levelsPlist = [[NSBundle mainBundle] pathForResource:#"levels" ofType:#"plist"];
NSDictionary *rootDict = [NSDictionary dictionaryWithContentsOfFile: levelsPlist];
NSString *levelKey = [NSString stringWithFormat:#"level%i", levelNum];
NSDictionary *levelDic = rootDict[levelKey];
NSAssert(levelDic, #"level no loaded");
Level *l = [[Level alloc]init];
l.coinsPerLvl = [levelDic[#"coinsPerLvl"] integerValue];
l.words = levelDic[#"words"];
return l;
}
Hope it help.
make your plist root as an array (like below). that way you can get levels info easily.
sample code
+(void)levelWithNum:(int)levelNum {
NSString* fileName = #"level.plist";
NSString* levelPath = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:fileName];
NSArray *levelsArray = [NSArray arrayWithContentsOfFile:levelPath];
NSAssert(levelsArray, #"level no loaded");
Level *l = [[Level alloc]init];
l.coinsPerLvl = [[levelsArray objectAtIndex:levelNum][#"coinsPerLvl"] integerValue];
l.words = [[levelsArray objectAtIndex:levelNum][#"words"] integerValue];
return l;
}
sample plist screen shot

Lazy load plist dictionary element(s)

The usual method for loading data from a dictionary contained in a plist is as below:
NSString *path = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
NSDictionary *data= [NSDictionary dictionaryWithContentsOfFile:path];
Is there a way to import only the element(s) specified in a key / set of keys, like:
NSDictionary *data= [NSDictionary dictionaryWithContentsOfFile:path forKey:key];
The idea is to perform lazy loading of dictionary contents by key.
So based on my comment above, you could add a class method to the NSDictionary via a category. You could do something like (not tested BTW).
+ (NSDictionary *)dictionaryWithContentsOfFile:(NSString *)path forKeys:(NSArray *)keys
{
NSMutableDictionary *newDictionary = nil;
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:path];
if (dictionary) {
newDictionary = [NSMutableDictionary dictionary];
for (id key in dictionary.allKeys) {
if ([keys containsObject:key]) {
newDictionary[key] = dictionary[key];
}
}
}
return [newDictionary copy];
}
If you did this, you'd see your spike in memory, but it should subside once dictionary is freed.
Alternatively, take a look at YAJL (https://github.com/lloyd/yajl). I've used this when dealing with very large JSON files. This was mainly the stream it in chunks. It is event driven, so you should be able to stream it in and detect the keys you want (hopefully).
please try the below method.
- (void)viewDidLoad
{
NSMutableArray *arry;
arry = [[NSMutableArray alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Catalog" ofType:#"plist"];
NSDictionary *dic = [menuArray objectAtIndex:indexPath.row];
lblName.text = [dic objectForKey:#"MenuName"];
}

Adding score and current date to plist

I have to retain the score and current date for a game in a plist . I created a dictionary with two arrays:
- (void)viewDidLoad
{
[super viewDidLoad];
dateArray=[[NSMutableArray alloc]init];
scoreArray=[[NSMutableArray alloc]init];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
[self getDate];
NSString *path = [[NSBundle mainBundle] pathForResource:#"score" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
int lastItemIndex = scoreArray.count;
[scoreArray insertObject:[dict objectForKey:#"scoreElements"] atIndex:lastItemIndex];
}
-(IBAction) saveData
{
NSString *plistPath =[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"Score.plist"];
NSMutableArray* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
[plistDict setValue:self.scoreLabel.text forKey:#"scoreElements"];
[plistDict writeToFile:plistPath atomically: YES];
}
This code is good only for the last game played, but I want to fill the tableView with the old scores as well. How can I do it?
Instead of using
[scoreArray insertObject:[dict objectForKey:#"scoreElements"] atIndex:lastItemIndex];
why don't you use
[scoreArray addObject: dict["scoreElements"];
Also when you are saving using below code, it will always set new value to "scoreElements" overriding old ones.... so you have to use array as well.
[plistDict setValue:self.scoreLabel.text forKey:#"scoreElements"];
You could use NSUserDefaults to store stuff and retrieve it later on.
Check out the reference about this class at Apple :
nsuserdefault apple

how to load plist data into array in IOS property list

NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"]];
NSDictionary *dict = [[NSDictionary alloc] initwithContentOfFile:path];
NSArray *textData=[NSArray new];
textData = [dict objectForkey:#"TableData"];
textData is my array name,
recipes is plist name
after excuting my text data is being empty...
where is the mistake.
The problem is that you converting .plist to dictionary in the wrong way. Check dict property, it should be nil. Code to create NSDictionary from .plist file is listed below:
CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
(__bridge CFDataRef)propertyListData,
kCFPropertyListImmutable, NULL);
NSDictionary *settings = (__bridge NSDictionary *)plist;
Try this:
textData = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"]];
Anyways, you may can take a look of this tutorial:
http://ios-blog.co.uk/tutorials/how-to-populate-a-uitableview-from-a-plist-property-list/

Load data from plist to tableview [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to populate UITableView with plist
I save data to plist like this:
- (IBAction)save:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"data.plist"];
NSMutableArray *data = [NSMutableArray arrayWithContentsOfFile:plistPath];
if (nil == data) {
data = [[NSMutableArray alloc] initWithCapacity:0];
}
else {
[data retain];
}
NSMutableDictionary *array = [[NSMutableDictionary alloc]init];
[array setObject:label1.text forKey:#"Test1"];
[array setObject:label2.text forKey:#"Test2"];
[array setObject:label3.text forKey:#"Test3"];
[array setObject:label4.text forKey:#"Test4"];
NSLog(#"%#", array);
[data addObject:array];
[array release];
[data writeToFile:plistPath atomically: TRUE];
[data release];
}
NSLog:
2012-07-01 18:52:19.566 testapp[22651:707] {
Test1 = 40;
Test2 = 102;
Test3 = 153;
Test4 = 255;
}
How can I load saved data to uitableview?
To read it, do this:
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
You should then be able to read the values for all the keys like this:
NSString *myValue = [plistDict objectForKey:#"someKey"];
edit:
After rereading your code it seems like you might be doing something you don't want to do. Your current plist structure is a top level array that adds a dictionary to itself every time you invoke "save". Is this what you're trying to do? If so, what represents a cell in your table, an index in the array?
If so, then you want to do
// top level array
NSMutableDictionary* plistArray = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
// individual dictionary at one array index (such as indexPath.row in cellForRowAtIndexPath)
NSMutableDictionary *dictionary = [plistArray objectAtIndex:yourIndex];
In any case, the object you have named "array" is actually a dictionary so you should rename it (or change it to be an array if that's what you want).

Resources