Read/write data from a plist of dictionaries and arrays, and load different levels into a TableView

StackOverflow https://stackoverflow.com/questions/21978626

  •  15-10-2022
  •  | 
  •  

Question

I'm a little confused about working with property lists. I've read most of the other questions about this topic, but I'm still very confused since they only go in one layer, so any help would be appreciated.

I would like to load a plist that stores data somewhat like this:

enter image description here

I have three ViewControllers (two TableViewControllers and one blank) in my Storyboard that I want to display different levels of information:

  1. Categories of people (Friends, etc.)
  2. Names of the people in those categories (Bob, etc.)
  3. Information about the people (favorite color, etc.)

How do I read/write files to a plist, and how to I access that information across multiple views?

Once I read the data, how do I display the information in different TableViewControllers?

Was it helpful?

Solution

Let's say that you have a plist file like this:

plist file image

and this code:

@implementation ViewController


NSDictionary *dictionary;

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

    NSMutableArray *array=[[NSMutableArray alloc]init];
    array=[NSMutableArray arrayWithContentsOfFile:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"root.plist"]];

    dictionary = [array objectAtIndex:0];


}

- (NSString *)applicationDocumentsDirectory {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"numberOfSectionsInTableView:%lu",(unsigned long)dictionary.count);
    return dictionary.count;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return [[[dictionary allKeys] objectAtIndex:section] capitalizedString];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    NSArray *peopleArray = [dictionary objectForKey:[[dictionary allKeys] objectAtIndex:indexPath.section]];

    cell.textLabel.text = [[peopleArray objectAtIndex:indexPath.row]objectForKey:@"name"];
    cell.detailTextLabel.text = [NSString stringWithFormat:@"Color:%@ - Gender:%@",[[peopleArray objectAtIndex:indexPath.row]objectForKey:@"favorite color"],[[peopleArray objectAtIndex:indexPath.row]objectForKey:@"gender"]];

    return cell;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSString *key =[[dictionary allKeys] objectAtIndex:section];
    NSLog(@"numberOfRowsInSection:%lu",(unsigned long)[[dictionary objectForKey:key] count]);
    return [[dictionary objectForKey:key] count];
}

it will give you this output:

(Supposed you have a tableView set up with Delegate and DataSource)

Output iPhone Simulator image

I know that you asked for having the "Friends" and "Enemies" in different TableViews, but I use both in the same tableView but in different sections. But my code can get you started.

If you need extra help about the UITableView, see Apple UITableView Class Reference

If this is necessary, I used this code to generate the example plist-file in my test-project:

NSMutableArray *root=[[NSMutableArray alloc]init];
NSMutableArray *friendsarray = [[NSMutableArray alloc]init];
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setObject:@"Jill" forKey:@"name"];
[dict setObject:@"green" forKey:@"favorite color"];
[dict setObject:@"female" forKey:@"gender"];

[friendsarray addObject:dict];

NSMutableDictionary *dict2 = [[NSMutableDictionary alloc]init];
[dict2 setObject:@"Bob" forKey:@"name"];
[dict2 setObject:@"Blue" forKey:@"favorite color"];
[dict2 setObject:@"male" forKey:@"gender"];

[friendsarray addObject:dict2];

NSMutableArray *enemiesarray = [[NSMutableArray alloc]init];


NSMutableDictionary *dict3 = [[NSMutableDictionary alloc]init];
[dict3 setObject:@"Michael" forKey:@"name"];
[dict3 setObject:@"Red" forKey:@"favorite color"];
[dict3 setObject:@"male" forKey:@"gender"];

[enemiesarray addObject:dict3];

NSMutableDictionary *d = [[NSMutableDictionary alloc]init];
[d setObject:friendsarray forKey:@"friends"];
[d setObject:enemiesarray forKey:@"enemies"];


[root addObject:d];

[root writeToFile:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"root.plist"] atomically:YES];

OTHER TIPS

There are numerous examples here in Stack Overflow of reading plist and passing data between ViewControllers. Its advisable to read through them & ideally connect them together to get your solution.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top