Link to home
Start Free TrialLog in
Avatar of Strongs
Strongs

asked on

plist extraction of data

I am attempting to develop an iPad app that requires a sectioned table to be populated with data within a plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Groups</key>
	<array>
		<dict>
			<key>Name</key>
			<string>Aerosols</string>
			<key>Details</key>
			<dict>
				<key>Item 1</key>
				<array>
					<string>Description</string>
					<string>Sub Title</string>
					<string>Yes</string>
					<string>No</string>
					<string>Notes</string>
				</array>
				<key>Item 2</key>
				<array>
					<string>Description</string>
					<string>Sub Title</string>
					<string>Yes</string>
					<string>No</string>
					<string>Notes</string>
				</array>
			</dict>
		</dict>
		<dict>
			<key>Name</key>
			<string>Alcohol</string>
			<key>Details</key>
			<dict>
				<key>Item 1</key>
				<array>
					<string>Description</string>
					<string>Sub Title</string>
					<string>Yes</string>
					<string>No</string>
					<string>Notes</string>
				</array>
				<key>Item 2</key>
				<array>
					<string>Description</string>
					<string>Sub Title</string>
					<string>Yes</string>
					<string>No</string>
					<string>Notes</string>
				</array>
				<key>Item 2 - 2</key>
				<array>
					<string>Description</string>
					<string>Sub Title</string>
					<string>Yes</string>
					<string>No</string>
					<string>Notes</string>
				</array>
			</dict>
		</dict>
	</array>
</dict>
</plist>

Open in new window

The section titles are taken from the Name key. The number of rows in section will be taken from the Details key, the sum of which will be the row count for each section. The row text labels will be populated with the Description field from each array within the corresponding Details dictionary.

I have managed to get the section title ok but i am struggling with the remaining issues. Moreover, when the user selects a row within a section, all remaining fields will be sent to a presenting view to populate labels.

I am not sure if it is the structure of the plist that is the issue?

Any help gratefully received.
Avatar of Strongs
Strongs

ASKER

So, after much trial and error and a couple of sleepless nights, this is what i have successfully completed.

I changed the structure of the plist to:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Groups</key>
	<array>
		<dict>
			<key>Name</key>
			<string>Aerosols</string>
			<key>Details</key>
			<array>
				<dict>
					<key>Main text</key>
					<string>Aerosols 1</string>
					<key>Subtitles</key>
					<string>subtitles</string>
					<key>uK</key>
					<string>Yes</string>
					<key>Abroad</key>
					<string>No</string>
					<key>Notes</key>
					<string>Item 1</string>
				</dict>
				<dict>
					<key>Main text</key>
					<string>Aerosols 2</string>
					<key>Subtitles</key>
					<string>subtitles</string>
					<key>uK</key>
					<string>No</string>
					<key>Abroad</key>
					<string>No</string>
					<key>Notes</key>
					<string>Item 2</string>
				</dict>
			</array>
		</dict>
		<dict>
			<key>Name</key>
			<string>Alcohol</string>
			<key>Details</key>
			<array>
				<dict>
					<key>Main text</key>
					<string>Alcohol 1</string>
					<key>Subtitles</key>
					<string>subtitles</string>
					<key>uK</key>
					<string>Yes</string>
					<key>Abroad</key>
					<string>No</string>
					<key>Notes</key>
					<string>Item 1</string>
				</dict>
				<dict>
					<key>Main text</key>
					<string>Alcohol 2</string>
					<key>Subtitles</key>
					<string>subtitles</string>
					<key>uK</key>
					<string>No</string>
					<key>Abroad</key>
					<string>No</string>
					<key>Notes</key>
					<string>Item 2</string>
				</dict>
				<dict>
					<key>Main text</key>
					<string>Alcohol 3</string>
					<key>Subtitles</key>
					<string>subtitles</string>
					<key>uK</key>
					<string>No</string>
					<key>Abroad</key>
					<string>No</string>
					<key>Notes</key>
					<string>Item 2</string>
				</dict>
			</array>
		</dict>
	</array>
</dict>
</plist>

Open in new window


in the viewDidLoad method:
- (void)viewDidLoad
{
    NSString *str = [[NSBundle mainBundle]pathForResource:@"Prohibited Items" ofType:@"plist"]; //get path to plist
    
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:str]; //assign file to dictionary
    
    self.groups = [dict objectForKey:@"Groups"]; //populate groups dictionary with all values in Groups key
    
    NSMutableArray *keyArray = [[NSMutableArray alloc]init]; //init a new array
    
    [keyArray addObjectsFromArray:[[self.groups valueForKey:@"Name"]sortedArrayUsingSelector:@selector(compare:)]];//add the Names key values
    
    self.names = keyArray; //assign to the names array

    [super viewDidLoad];

}

Open in new window


In the numberOfSectionsInTableView method:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    
    return [self.names count];//return the count of the names array
}

Open in new window


in the titleForHeaderInSection method:
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    //check for valid array object
    if (self.names == 0) {
        return 0;
    }
    
    else
        
    {
    
        NSString *name = [self.names objectAtIndex:section]; //return each name in the names array
    
        return name;
    }
    
}

Open in new window


in the numberOfRowsInSection method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
    // Return the number of rows in the section.
    if (self.groups == 0) {
        return 0;
        
    }
    
    else
        
    {
        self.keys = [self.groups valueForKey:@"Details"]; //get all values for the key Details
        
        NSArray *details = [self.keys objectAtIndex:section];//assign to array
    
        return [details count]; //return the count of the array
    }
    
}

Open in new window


Finally in the cellForRowAtIndexPath method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section]; //get the index number for the current section in the table
    
    self.currSection = [self.keys objectAtIndex:section]; //assign the dictionary objects at current section index to a dictionary
    
    NSArray *main = [self.currSection valueForKey:@"Main text"];//assign the value of Main text to an array
    //NSLog(@"CurrSection %@",self.currSection);
    
    NSString *key = [main objectAtIndex:indexPath.row]; //get the value of the current entry within the array at current indexpath
    
    static NSString *CellIdentifier = @"itemCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
    // Configure the cell...
    cell.textLabel.text = key;//assign string value to the current cell label
    
    return cell;
}

Open in new window


The only issue left outstanding is how to pass the values for the selected dictionary to the presenting view.

I have tried to do this in prepareForSegue method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"details"]) {
        
        self.detailView = [segue destinationViewController];
        
        NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow];
        NSLog(@"Index path %i",selectedRow.row);

        
        NSUInteger section = [selectedRow section];
        NSLog(@"Section %i",section);
        
        
        NSDictionary *dict = [self.keys objectAtIndex:section];//dictionary of all Detail objects
        
        self.subtitles = [dict valueForKey:@"Subtitles"];//array of subtitles for the dictionary objects for the selected section
        
        self.subtitle = [self.subtitles objectAtIndex:selectedRow.row];
        
        NSLog(@"Subtitle %@",self.subtitle);
        
    }
}

Open in new window


But the section and row returned are always 0.

This is the last piece of the puzzle, so anyone out there with the knowledge...
ASKER CERTIFIED SOLUTION
Avatar of Strongs
Strongs

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Strongs

ASKER

As no one has offered a more elegant solution I am accepting this as the answer.