Melih Mucuk
Melih Mucuk

Reputation: 7066

Accessing NSMutableArray Objects For Using On TableView

I started develop an app which is using WCF service with JSON data. I got the data from WCF service but I didn't use it as I want.

here is the JSON data:

{"MenuDoldurAndroidResult":[
{"menu_description":"Turkish Pizza","menu_title":"L Pizza","menu_price":"26 TL"},{"menu_description":"Italiano Pizza","menu_title":"L Pizza","menu_price":"27 TL"},{"menu_description":"Extravaganza","menu_title":"L Pizza","menu_price":"29 TL"},{"menu_description":"Pepporoni Pizza","menu_title":"L Pizza","menu_price":"28 TL"},{"menu_description":"Turkish Pizza","menu_title":"S Pizza","menu_price":"12 TL"},{"menu_description":"Italiano Pizza","menu_title":"S Pizza","menu_price":"13 TL"},{"menu_description":"Extravaganza","menu_title":"S Pizza","menu_price":"15 TL"},{"menu_description":"Pepporoni Pizza","menu_title":"S Pizza","menu_price":"14 TL"}
]}

What I want:

If there are 2 title here, there must be 2 section in table view. Every item must be in their section.

Like this:

-L Pizzas

-S Pizzas

How can I access this item and display like this ?

- (void)viewDidLoad
{
    [super viewDidLoad];

//I posted request to service here. I didn't write these parts of code.

NSDictionary* json = [NSJSONSerialization
                              JSONObjectWithData:data
                              options:NSJSONReadingMutableContainers
                              error:&error];

        NSMutableArray *array= [json objectForKey:@"MenuDoldurAndroidResult"];

        menu = [[NSMutableArray alloc] initWithCapacity:3];

        NSString *descriptionTemp;
        NSString *titleTemp;
        NSString *priceTemp;
        for(int i=0; i< array.count; i++)
        {
            NSDictionary *menuList= [array objectAtIndex:i];
            titleTemp = [menuList objectForKey:@"menu_title"];
            descriptionTemp = [menuList objectForKey:@"menu_description"];
            priceTemp = [menuList objectForKey:@"menu_price"];
            [menu addObject:[NSArray arrayWithObjects:titleTemp,descriptionTemp,priceTemp,nil]];

        }
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 2;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 2;
}

-(NSString *)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section{

    if (section==0) {
        return @"L Pizzas";
    }
    else{
        return @"S Pizzas";
    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    cell.textLabel.text = [menu objectAtIndex: indexPath.row];
    return cell;
}

Upvotes: 1

Views: 773

Answers (2)

Anupdas
Anupdas

Reputation: 10201

If your content is static you can try using the answer by Sunny. But if is dynamic it's better to store the data in a different way. Obviously L pizza and S pizza seems to be a category and the rest are like category items.

You need to make a collection of the categories. Demo Project Source Code

- (void)viewDidLoad
{
    [super viewDidLoad];

//I posted request to service here. I didn't write these parts of code.

NSDictionary* json = [NSJSONSerialization
                              JSONObjectWithData:data
                              options:NSJSONReadingMutableContainers
                              error:&error];

NSMutableArray *allPizzas = [json[@"MenuDoldurAndroidResult"] mutableCopy];

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"menu_price"
                                                                 ascending:YES
                                                                  selector:@selector(compare:)];
[allPizzas sortUsingDescriptors:@[sortDescriptor]];

NSMutableArray *pizzaCategories = [@[]mutableCopy];
//Find unique categories in all the pizzas
NSSet* categories = [NSSet setWithArray: [allPizzas valueForKey:@"menu_title"]];

//Enumerate to form a new reformatted category array
for (NSString *categoryTitle in categories)
{
    //Predicate is used to find the items that come under current category
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"menu_title == %@",categoryTitle];
    NSArray *categoryItems = [allPizzas filteredArrayUsingPredicate:predicate];
    //New dictionary with name of category and category items are formed 
    NSDictionary *categoryDict = @{@"menu_title":categoryTitle,@"pizzas":categoryItems};
    [pizzaCategories addObject:categoryDict];

}

//Assign the new formatted category array to the instance variable for holding categories.
self.categories = pizzaCategories;
}

Modify the datasource of tableView for the new structure

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   //The count of categories will give number of sections
    NSUInteger sections = [self.categories count];
    return sections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //The number of items in a category is calculated
    NSDictionary *category = self.categories[section];
    return [category[@"pizzas"] count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    //Title for the category
    NSDictionary *category = self.categories[section];
    return category[@"menu_title"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    NSDictionary *category      = self.categories[indexPath.section];
    NSArray *categoryItems      = category[@"pizzas"];
    NSDictionary *categoryItem  = categoryItems[indexPath.row];

    cell.textLabel.text = categoryItem[@"menu_description"];
    cell.detailTextLabel.text = categoryItem[@"menu_price"];

    return cell;
}

Upvotes: 4

Matt
Matt

Reputation: 2411

You can also use the free Sensible TableView framework to fetch the data from the web service and automatically display it in your table view.

Upvotes: 0

Related Questions