Multiple, very similar VCs or all in one?

Discussion in 'iOS Programming' started by Scott90, May 25, 2012.

  1. Scott90 macrumors 6502

    Joined:
    Jul 14, 2008
    #1
    I'm creating an app that has four or five table views that all get their data from Core Data. They are very similar, so I would like to only use one view controller to manage these views, and then use if/else statements to differentiate them. For example, one table has a UISearchBar, the others don't. Another table has different cell prototypes, which are easy to use too. Still another table has some other things that make it different from the others. Of course, the NSFetchRequests are different for all 4/5 tables.

    It would be a lot easier to put the code for all these tables in one, since they are all presented and popped the same way. I've considered creating a super class, and then subclasses for each table, but that's still some extra work.

    What would be my best course of action in this situation?
     
  2. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #2
    Funny you should mention this. Months ago I started looking at my code and seeing I had a lot of redundant code and VC's. Then I finally sank in what my teachers talked about with "abstraction". Keep thing watered and simple so lots of things can use them.

    One thing I learned recently when pushing new VC on the stack. You can push information to them when they instantiate. So if you have NSString *clientName in your VC that you are pushing on the stack you can instantiate that like myVC *vc =[MyVC alloc] init]; then vc.clientName = @"Sam";

    I use to save information to a plist and then reload the plist until I discovered you can instantiate it with preassigned variables. So if you have 4 different VC's and you can add all the code you need into the VC then maybe all you have to do is to push a string for the settings you want to the new controller and then as it launches it checks what string it is and sets up your VC appropriately for your needs?
     
  3. Scott90 thread starter macrumors 6502

    Joined:
    Jul 14, 2008
    #3
    Yes, that is how I would do it. And although it makes it a little bit easier for me, I feel like it's not very good MVC coding, which is why I'm asking what the best way to do this is.
     
  4. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #4
    As I practice and learn I have developed habits. Almost all of my projects use some similar Methods. So in this last project I started to create a reusable Class that had my go to Methods that I seem to use a lot. For instance I use plists a lot and I always seemed to have many Methods that were identical like the one bellow that would return the path to a preference.plist

    Code:
    - (NSString *) dataFileToUpdatePrefs
    {
        NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [path objectAtIndex:0];
        
        return [documentsDirectory stringByAppendingPathComponent:[B]@"preferences.plist"[/B]];
    }
    
    
    After writing many projects and using this code over and over I thought, why don't I just write this Method 1 time and have it take an argument like bellow

    Code:
    -(NSString *)returnPath:(NSString *)[COLOR="Red"]incomingString[/COLOR]{
        NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [path objectAtIndex:0];
        
        return [documentsDirectory stringByAppendingPathComponent:[COLOR="Red"]incomingString[/COLOR]];
    }
    
    
    Now instead of having a few Methods around that returned a specific paths to a property list I had only 1 that I could feed the final destination. This I believe was a good way of adding abstraction and less code to my projects. It then became a method I added to a Class that I import in to every project to use.

    I hope some of this is on target of what you were looking for. I thought I would answer your question because I have been wondering the same thing too.
     
  5. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #5
    Scott90

    I'd consider looking at placing much of that logic into one or more UITableViewDataSource subclasses, and then simply instantiate the appropriate one and assign it to the dataSource of the table view. This will create an abstraction from the ViewController and UITableView that will allow those to focus on their roles, perhaps, based on your description & desire, bring your count of each down to one.

    UITableViewDataSource is another delegate of a UITableView. You can place your CoreData work into there also, burying that logic from your higher level views.

    I haven't worked with CoreData and don't know your project, but this seems reasonable to me based on other experience. Perhaps someone who has combined both will speak up.

    NSFetchedResultsController also sounds like something you should be looking into. I just found that before hitting the submit reply button.


    larswik,

    That returnPath: method you mention has no need to be an instance method. I suggest it should be a class method because it uses no outside resources except what you pass to it. If all your methods for that class followed this convention, then a small bonus is that you wouldn't even need to instantiate an object. Another bonus is that by just recognizing the + sign when looking at your code, you'd recognize no instance variables are being used, which could save you time when looking through your code.

    BTW, I've done a similar thing for file management. As you've found out, it makes programming easier and more enjoyable when you recognize such reuse cases and implement some nice helper code. :)
     
  6. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    Thanks xStep. I had not thought of that. I will try it out.
     
  7. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #7
    What we do in cases like this, is create our custom Init method like
    myVC *vc = [[MyVC alloc] initWithClient:enumarationType];

    if you define an enum, you can check in your code, if enum = blah, send that delegation pattern to the ViewController.
    Don't really want to get more into dept with this, but this is a good pointer, you're thinking wisely, seperate your viewControllers from your data, have 1 viewController, and just get other info, even with a enum, you could load other custom cells in the same cellForRowAtIndexPath.
    Hope that made sense.

    Noxx.
     

Share This Page