2
\$\begingroup\$

Below is the code that I would like to refactor in order to avoid if-else statements in cellForRowAtIndexPath and numberOfRowsInSection.

Depending upon what user selects, section order and numberOfSections will differ each time. numberOfRowsInSection will also vary.

I do need it to keep track of each cell (didSelectRowAtIndexPath) and trigger appropriate methods. Since I'm limited to the number of characters here, I have posted the entire .m on [GitHub][1].

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    //+2 for Recipient & Transport
    NSInteger numberOfSections = (planDate.numberOfCells +3);
    return numberOfSections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0)
    {
        planDate.sectionZeroLabel = @"Recipient";
        return 1;
    }

    else if (section == 1)
    {
        planDate.sectionOneLabel = @"Let's Meet at:";
        return 3;
    }

    // +2 instead of 3 is to account for -1 (section 0)
    else if (section == (planDate.numberOfCells+2))
    {
        NSInteger transportCells;
        transportCells = 0;
        planDate.sectionTransportationLabel = transportationSection;
        lastSection = transportationSection;
        if (planDate.pickupSelectedCell != NULL)
        {
            transportCells = transportCells +1;
        }

        if ((planDate.pickUpOwnSuggestion != NULL) && (![planDate.pickUpOwnSuggestion isEqual: @""]))
        {
            transportCells = transportCells +1;
        }

        if (planDate.dropOffSelectedCell != NULL)
        {
            transportCells = transportCells +1;
        }

        if ((planDate.dropOffOwnSuggestion != NULL) && (![planDate.dropOffOwnSuggestion isEqual: @""]))
        {
            transportCells = transportCells +1;
        }

        return transportCells;
    }

    else if (section == 2)
    {
        if ([planDate.sceneFour isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionTwoLabel = coffeeDrinkSection;
            sectionTwo = coffeeDrinkSection;
            return 2;
        }

        else if ([planDate.sceneFour isEqual: @"pdLunch"])
        {
            planDate.sectionTwoLabel = lunchSection;
            sectionTwo = lunchSection;
            return 2;
        }
        else if ([planDate.sceneFour isEqual: @"pdDinner"])
        {
            planDate.sectionTwoLabel = dinnerSection;
            sectionTwo = dinnerSection;
            return 2;
        }
        else if ([planDate.sceneFour isEqual: @"pdMovies"])
        {
            planDate.sectionTwoLabel = movieSection;
            sectionTwo = movieSection;
            return 3;
        }
        else if ([planDate.sceneFour isEqual: @"pdActivity1"])
        {
            planDate.sectionTwoLabel = activity1Section;
            sectionTwo = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
        else if ([planDate.sceneFour isEqual: @"pdActivity2"])
        {
            planDate.sectionTwoLabel = activity2Section;
            sectionTwo = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
        else if ([planDate.sceneFour isEqual: @"pdActivity3"])
        {
            planDate.sectionTwoLabel = activity3Section;
            sectionTwo = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
    }
    else if (section == 3)
    {
            if ([planDate.sceneFive isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionThreeLabel = coffeeDrinkSection;
            sectionThree = coffeeDrinkSection;
            return 2;
        }
        else if ([planDate.sceneFive isEqual: @"pdLunch"])
        {
            planDate.sectionThreeLabel = lunchSection;
            sectionThree = lunchSection;
            return 2;
        }
        else if ([planDate.sceneFive isEqual: @"pdDinner"])
        {
            planDate.sectionThreeLabel = dinnerSection;
            sectionThree = dinnerSection;
            return 2;
        }
        else if ([planDate.sceneFive isEqual: @"pdMovies"])
        {
            planDate.sectionThreeLabel = movieSection;
            sectionThree = movieSection;
            return 3;
        }
        else if ([planDate.sceneFive isEqual: @"pdActivity1"])
        {
            planDate.sectionThreeLabel = activity1Section;
            sectionThree = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
        else if ([planDate.sceneFive isEqual: @"pdActivity2"])
        {
            planDate.sectionThreeLabel = activity2Section;
            sectionThree = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
        else if ([planDate.sceneFive isEqual: @"pdActivity3"])
        {
            planDate.sectionThreeLabel = activity3Section;
            sectionThree = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
    }
    else if (section == 4)
    {    
        if ([planDate.sceneSix isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionFourLabel = coffeeDrinkSection;
            sectionFour = coffeeDrinkSection;
            return 2;
        }
        else if ([planDate.sceneSix isEqual: @"pdLunch"])
        {
            planDate.sectionFourLabel = lunchSection;
            sectionFour = lunchSection;
            return 2;
        }

        else if ([planDate.sceneSix isEqual: @"pdDinner"])
        {
            planDate.sectionFourLabel = dinnerSection;
            sectionFour = dinnerSection;
            return 2;
        }

        else if ([planDate.sceneSix isEqual: @"pdMovies"])
        {
            planDate.sectionFourLabel = movieSection;
            sectionFour = movieSection;
            return 2;
        }

        else if ([planDate.sceneSix isEqual: @"pdActivity1"])
        {
            planDate.sectionFourLabel = activity1Section;
            sectionFour = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneSix isEqual: @"pdActivity2"])
        {
            planDate.sectionFourLabel = activity2Section;
            sectionFour = activity1Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneSix isEqual: @"pdActivity3"])
        {
            planDate.sectionFourLabel = activity3Section;
            sectionFour = activity1Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
    }

    else if (section == 5)
    {    
        if ([planDate.sceneSeven isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionFiveLabel = coffeeDrinkSection;
            sectionFive = coffeeDrinkSection;
            return 2;
        }

        else if ([planDate.sceneSeven isEqual: @"pdLunch"])
        {
            planDate.sectionFiveLabel = lunchSection;
            sectionFive = lunchSection;
            return 2;
        }

        else if ([planDate.sceneSeven isEqual: @"pdDinner"])
        {
            planDate.sectionFiveLabel = dinnerSection;
            sectionFive = dinnerSection;
            return 2;
        }

        else if ([planDate.sceneSeven isEqual: @"pdMovies"])
        {
            planDate.sectionFiveLabel = movieSection;
            sectionFive = movieSection;
            return 3;
        }

        else if ([planDate.sceneSeven isEqual: @"pdActivity1"])
        {
            planDate.sectionFiveLabel = activity2Section;
            sectionFive = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneSeven isEqual: @"pdActivity2"])
        {
            planDate.sectionFiveLabel = activity2Section;
            sectionFive = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneSeven isEqual: @"pdActivity3"])
        {
            planDate.sectionFiveLabel = activity3Section;
            sectionFive = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
    }

    else if (section == 6)
    {

        if ([planDate.sceneEight isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionSixLabel = coffeeDrinkSection;
            return 2;
        }

        else if ([planDate.sceneEight isEqual: @"pdLunch"])
        {
            planDate.sectionSixLabel = lunchSection;
            return 2;
        }

        else if ([planDate.sceneEight isEqual: @"pdDinner"])
        {
            planDate.sectionSixLabel = dinnerSection;
            return 2;
        }

        else if ([planDate.sceneEight isEqual: @"pdMovies"])
        {
            planDate.sectionSixLabel = movieSection;
            return 3;
        }

        else if ([planDate.sceneEight isEqual: @"pdActivity1"])
        {
            planDate.sectionSixLabel = activity1Section;
            sectionSix = activity1Section;NS
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneEight isEqual: @"pdActivity2"])
        {
            planDate.sectionSixLabel = activity2Section;
            sectionSix = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneEight isEqual: @"pdActivity3"])
        {
            planDate.sectionSixLabel = activity3Section;
            sectionSix = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

    }

    else if (section == 7)
    {

        if ([planDate.sceneNine isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionSevenLabel = coffeeDrinkSection;
            return 2;
        }

        else if ([planDate.sceneNine isEqual: @"pdLunch"])
        {
            planDate.sectionSevenLabel = lunchSection;
            return 2;
        }

        else if ([planDate.sceneNine isEqual: @"pdDinner"])
        {
            planDate.sectionSevenLabel = dinnerSection;
            return 2;
        }

        else if ([planDate.sceneNine isEqual: @"pdMovies"])
        {
            planDate.sectionSevenLabel = movieSection;
            return 3;
        }

        else if ([planDate.sceneNine isEqual: @"pdActivity1"])
        {
            planDate.sectionSevenLabel = activity1Section;
            sectionSeven = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneNine isEqual: @"pdActivity2"])
        {
            planDate.sectionSevenLabel = activity2Section;
            sectionSeven = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneNine isEqual: @"pdActivity3"])
        {
            planDate.sectionSevenLabel = activity3Section;
            sectionSeven = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

    }
    else if (section == 8)
    {    
        if ([planDate.sceneTen isEqual: @"pdCoffeeDrinks"])
        {
            planDate.sectionEightLabel = coffeeDrinkSection;
            return 2;
        }

        else if ([planDate.sceneTen isEqual: @"pdLunch"])
        {
            planDate.sectionEightLabel = lunchSection;
            return 2;
        }

        else if ([planDate.sceneTen isEqual: @"pdDinner"])
        {
            planDate.sectionEightLabel = dinnerSection;
            return 2;
        }

        else if ([planDate.sceneTen isEqual: @"pdMovies"])
        {
            planDate.sectionEightLabel = movieSection;
            return 3;
        }

        else if ([planDate.sceneTen isEqual: @"pdActivity1"])
        {
            planDate.sectionEightLabel = activity1Section;
            sectionEight = activity1Section;
            if (planDate.activity1CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneTen isEqual: @"pdActivity2"])
        {
            planDate.sectionEightLabel = activity2Section;
            sectionEight = activity2Section;
            if (planDate.activity2CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }

        else if ([planDate.sceneTen isEqual: @"pdActivity3"])
        {
            planDate.sectionEightLabel = activity3Section;
            sectionEight = activity3Section;
            if (planDate.activity3CommentsField != NULL)
            {
                return 5;
            }
            else return 4;
        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 30.0;
}

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)];
    if (section == 0)
    {
        label.text = planDate.sectionZeroLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];

    }
    else if (section == 1)
    {
        label.text = planDate.sectionOneLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == (planDate.numberOfCells+2))
    {
        label.text = planDate.sectionTransportationLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 2)
    {
        label.text = planDate.sectionTwoLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 3)
    {
        label.text = planDate.sectionThreeLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 4)
    {
        label.text = planDate.sectionFourLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 5)
    {
        label.text = planDate.sectionFiveLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 6)
    {
        label.text = planDate.sectionSixLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 7)
    {
        label.text = planDate.sectionSevenLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    else if (section == 8)
    {
        label.text = planDate.sectionEightLabel;
        label.backgroundColor = [UIColor clearColor];
        [label setFont:[UIFont boldSystemFontOfSize:16]];
        label.textColor = [UIColor whiteColor];
    }
    [headerView addSubview:label];
    return headerView;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
    cell.textLabel.numberOfLines = 1;
    cell.textLabel.adjustsFontSizeToFitWidth = YES;
    cell.textLabel.minimumScaleFactor = .5;

    if (indexPath.section == 0)
    {
        cell.textLabel.text = planDate.recipientUserName;
    }

    else if(indexPath.section == 1)
    {
        [self meetupCell:indexPath :cell];
    }
    if(indexPath.section == 2)
    {    
        if (sectionTwo == coffeeDrinkSection)
        {
            [self coffeeDrinksCell:indexPath:cell];
        }

        else if (sectionTwo == lunchSection)
        {
            [self lunchCell:indexPath:cell];
        }

        else if (sectionTwo== dinnerSection)
        {
            [self dinnerCell:indexPath :cell];
        }

        else if (sectionTwo == movieSection)
        {
            [self movieCell:indexPath :cell];
        }
        else if (sectionTwo == activity1Section)
        {
            [self activity1Cell:indexPath :cell];
        }
        else if (sectionTwo == activity2Section)
        {
            [self activity2Cell:indexPath :cell];
        }
        else if (sectionTwo == activity3Section)
        {
            [self activity3Cell:indexPath :cell];
        }
    }
    else if (indexPath.section == (planDate.numberOfCells+2))
    {
        [self transportationCell:indexPath :cell];
    }
    else if(indexPath.section == 3)
    {    
        if (sectionThree == coffeeDrinkSection)
        {
            [self coffeeDrinksCell:indexPath:cell];
        }

        else if (sectionThree == lunchSection)
        {
            [self lunchCell:indexPath:cell];
        }

        else if (sectionThree == dinnerSection)
        {
            [self dinnerCell:indexPath :cell];
        }

        else if (sectionThree == movieSection)
        {
            [self movieCell:indexPath :cell];
        }
        else if (sectionThree == activity1Section)
        {
            [self activity1Cell:indexPath :cell];
        }
        else if (sectionThree == activity2Section)
        {
            [self activity2Cell:indexPath :cell];
        }
        else if (sectionThree == activity3Section)
        {
            [self activity3Cell:indexPath :cell];
        }
    }

    else if(indexPath.section == 4)
    {
        if (sectionFour == coffeeDrinkSection)
        {
            [self coffeeDrinksCell:indexPath:cell];
        }

        else if (sectionFour== lunchSection)
        {
            [self lunchCell:indexPath:cell];
        }

        else if (sectionFour == dinnerSection)
        {
            [self dinnerCell:indexPath :cell];
        }

        else if (sectionFour == movieSection)
        {
            [self movieCell:indexPath :cell];
        }

        else if (sectionFour == activity1Section)
        {
            [self activity1Cell:indexPath :cell];
        }
        else if (sectionFour == activity2Section)
        {
            [self activity2Cell:indexPath :cell];
        }
        else if (sectionFour == activity3Section)
        {
            [self activity3Cell:indexPath :cell];
        }
    }

    else if(indexPath.section == 5)
    {
        if (sectionFive == coffeeDrinkSection)
        {

            [self coffeeDrinksCell:indexPath:cell];
        }
        else if (sectionFive== lunchSection)
        {

            [self lunchCell:indexPath:cell];
        }
        else if (sectionFive == dinnerSection)
        {    
            [self dinnerCell:indexPath :cell];
        }

        else if (sectionFive == movieSection)
        {    
            [self movieCell:indexPath :cell];
        }

        else if (sectionFive == activity1Section)
        {
            [self activity1Cell:indexPath :cell];
        }
        else if (sectionFive == activity2Section)
        {
            [self activity2Cell:indexPath :cell];
        }
        else if (sectionFive == activity3Section)
        {
            [self activity3Cell:indexPath :cell];
        }
    }
    return cell;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ I haven't done programming on ios but this looks like C. So I'll put a comment instead of putting an answer. In your (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section it seems that the 2nd to 4th statement(label's backgroundColor to label's textcolor) is the same in virtually every if-block. Wouldn't it be much simpler to put them out of the blocks? That alone can take out something like 27 lines of redundant code if you put them outside the if-else. Also isn't there a switch statement? It looks like your code can be much better using switch cases. \$\endgroup\$ – Aseem Bansal Aug 24 '13 at 15:08
1
\$\begingroup\$

In reviewing the code I've identified issues with architecture, code repetition, and code style.

The canonical architecture for iOS apps is the Model - View - Controller pattern. Further reading specific to iOS available here. One of the primary issues I see here is a fuzzing of responsibilities between model and controller. The PlanDate core data entity maintains a number of properties about the sections that will be displayed from it - sectionTwoLabel and so on. This is an inappropriate assignment of responsibilities to the model layer - these should be in the view or controller layer, generally (with iOS view controllers usually straddling these layers, although that's controversial). I'm unsure what the various scene... and transport... attributes of the PlanDate are, but I'm suspicious that they should be their own entities in the model, as well. A rough UML diagram of what I mean:

enter image description here

SceneDetail represents the data that's unique to each scene, that for instance is causing the coffee scene to require 2 cells, and so on. As I have an incomplete understanding of the application it's possible that some type of polymorphism on Scene would be appropriate. The Scene name could be an internal ID that you translate to something human readable, or just something human readable to begin with, such as "Coffee". A consequence of having the scenes and transportation options represented as relationships means that we can greatly simplify the table view code by relying on the collection behavior in the relationship, instead of checking if (sceneTwo != nil) and so on. We should order the relationships so that they will be represented by NSOrderedSet instances and the model will preserve the sorting for us. We can start to refactor our table view methods to take advantage of this.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSUInteger numberOfScenes = [planDate.scenes count];
    return numberOfScenes + 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger rows = 0;

    if (section == 0) {
        rows = 1;
    }
    else if (section == 1) {
        rows = 2;
    }
    else if (section == [self transportSection]) {
        rows = [planDate.transportOptions count];
    }
    else {
        Scene *sceneForSection = [self sceneForSection:section];
        rows = [sceneForSection.sceneDetails count]; //scene details contains info displayed in rows
    }

    return rows;
}

- (Scene *)sceneForSection:(NSInteger)section
{
    Scene *sceneForSection = planDate.scenes[section - 2];
    return sceneForSection;
}

- (NSInteger)transportSection
{
    return ([planDate.scenes count] + 2);
}

This vastly simplifies the calculation of the number of rows in the section. We now rely on the count of the relationships rather than inspecting flags on the object and maintaining complex state within our controller. Similar improvements are seen in generating the header view:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)];
    label.backgroundColor = [UIColor clearColor];
    [label setFont:[UIFont boldSystemFontOfSize:16]];
    label.textColor = [UIColor whiteColor];

    if (section == 0) {
        label.text = @"Recipient";
    }
    else if (section == 1) {
        label.text = @"Let's meet at:";
    }
    else if (section == [self transportSection]) {
        label.text = @"Transport";
    }
    else {
        Scene *scene = [self sceneForSection:section];
        label.text = scene.name;
    }

    [headerView addSubview:label];
    return headerView;
}

We rely on information the model knows about itself, namely count and ordering and names, to generate the properties for the section headers. You'd want to go on and refactor tableView:cellForRowAtIndexPath: to take advantage of these characteristics as well, instead of relying on storing which section is which.

As I said earlier, I see code repetition issues in this code. I've extracted small methods like transportSection and sceneForSection to avoid those. I also moved label configuration out of the if statements and into the main method. Keep alert for small changes you can do similar to this, where blocks of code are replaced with method calls to reduce duplication. If you're re-writing the same chunk of code for the second, or at very most the third time, extract it into a method or function.

Finally, some notes on style. Compare object values not to NULL but to nil so other programmers know that the value is an object. Don't ever write methods without each parameter named - so no more coffeeCell:: but instead something like configureCoffeeCell:atIndexPath:. That is a big one in my own, and many other Objective-C developer's, views. There is in fact only a single Apple API that I'm aware of that doesn't follow that convention. I'd also suggest avoiding having so many return statements in each method. It makes debugging easier, I find.

To sum up, address your architecture issues by applying MVC and single responsibility principle. Delegate to the model the maintenance of information about its state, and just have the controller translate that information to the view. Look for opportunities to extract repeated chunks of code into their own methods. And follow good Objective-C style practices and guidelines.

\$\endgroup\$
  • \$\begingroup\$ Hey! Thank you so much for your detailed explanation and pointers. I also spotted code repetition but decided to change the code all at once. I didn't, however, know about writing methods without each parameter named! I did an update on the question to give you a better understanding of the app. It's basically an app for couples to schedule a date. I have a simple data class that I pass around between the viewControllers called planDate (an instance of STPDDataClass). \$\endgroup\$ – user1107173 Aug 26 '13 at 20:07
  • \$\begingroup\$ It isn't until the end when I save the object I map the variables to coreData entity variables as you probably saw under - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex. Do you still recommend relationships? If so, I think it will be to-many? \$\endgroup\$ – user1107173 Aug 26 '13 at 20:07
  • \$\begingroup\$ So, following your advice on polymorphism, I guess I'm struggling with how would I know what all options the user selected and how to map them to the entity after the user decides to save the object. \$\endgroup\$ – user1107173 Aug 26 '13 at 20:08
  • 1
    \$\begingroup\$ Thanks for the feedback. I'll try to review these in the next few days and respond - it's a bear of a week! \$\endgroup\$ – Carl Veazey Aug 27 '13 at 16:09
  • 1
    \$\begingroup\$ I did a bit of reading and it appears that maybe ordered relationships aren't what you want - instead of a normal relationship and sort by some display order, instead. I don't have the links handy I'll try to add them if I can dig them back up. \$\endgroup\$ – Carl Veazey Sep 3 '13 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.