Programmatically create tabbar hierarchy

I try and avoid using Interface Builder in my projects as much as possible as it's just not as flexible as I'd like it to be. I end up with some setting being defined in IB and some being defined in code which then makes the code trickier to maintain. Below is my implementation of how to programmatically create and populate a tabbar.

In comes in two parts:

  1. plist defining the hierarchy
  2. Method read plist and create hierarchy

Plist Structure - ApplicationHierarchy

<plist version="1.0">
<array>
    <dict>
        <key>TabBarTitle</key>
        <string>HOME_TAB</string>
        <key>TabBarImage</key>
        <string>tabbar_home_icon.png</string>
        <key>RootViewController</key>
        <string>HomeViewController</string>
    </dict>
</array>
</plist>

Method without using a xib

-(void)createApplicationHierarchy{

    NSString *applicationHierarchyPlistFilePath = [[NSBundle mainBundle] pathForResource:@"ApplicationHierarchy" ofType:@"plist"];

    if (applicationHierarchyPlistFilePath != nil) {
        NSArray *applicationHierarchy = [[NSArray arrayWithContentsOfFile:applicationHierarchyPlistFilePath] retain];

        NSMutableArray *navigationElements = [[[NSMutableArray alloc]init] autorelease];

        for (int x = 0; x < [applicationHierarchy count]; x++) {

            NSDictionary *tabbarDictionary = [applicationHierarchy objectAtIndex:x];

                        //Create tabbar's element's root viewcontroller
            Class rootViewControllerClass = NSClassFromString ([tabbarDictionary objectForKey:@"RootViewController"]);
            id rootViewController = [[rootViewControllerClass alloc]init];
            UINavigationController *tabRootViewNavigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];
            [rootViewController release];

                        //Give tab bar element a title
            NSString *tabBarTitle = NSLocalizedString([tabbarDictionary objectForKey:@"TabBarTitle"], @"");

                        //Give tab bar element an image
            UIImage *tabBarImage = [UIImage imageNamed:[tabbarDictionary objectForKey:@"TabBarImage"]];

                        //create tabbar item and pass it configuration defined aboce
            UITabBarItem *tabBarItem = [[UITabBarItem alloc]initWithTitle:tabBarTitle image:tabBarImage tag:x];
            tabRootViewNavigationController.tabBarItem = tabBarItem;
                        [tabBarItem release];
            [navigationElements addObject:tabRootViewNavigationController];
            [tabRootViewNavigationController release];

        }

        [applicationHierarchy release];

        self.tabBarController.viewControllers = [NSArray arrayWithArray:navigationElements]; //this "tabBarController" is attached to MainWindow.xib

    }

}

Method with a xib

-(void)createApplicationHierarchy
{  

    NSString *applicationHierarchyPlistFilePath = [[NSBundle mainBundle] pathForResource:@"ApplicationHierarchy" ofType:@"plist"];  

    if (applicationHierarchyPlistFilePath != nil) {  
        NSArray *applicationHierarchy = [[NSArray arrayWithContentsOfFile:applicationHierarchyPlistFilePath] retain];  

        NSMutableArray *navigationElements = [[[NSMutableArray alloc]init] autorelease];  

        for (int x = 0; x < [applicationHierarchy count]; x++) {  

            NSDictionary *tabbarDictionary = [applicationHierarchy objectAtIndex:x];  

            //Create tabbar's element's root viewcontroller  
            Class rootViewControllerClass = NSClassFromString ([tabbarDictionary objectForKey:@"RootViewController"]);  
            id rootViewController = [[rootViewControllerClass alloc]initWithNibName:[tabbarDictionary objectForKey:@"RootViewController"] bundle:nil];  
            UINavigationController *tabRootViewNavigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];  
            [rootViewController release];  

            //Give tab bar element a title  
            NSString *tabBarTitle = NSLocalizedString([tabbarDictionary objectForKey:@"TabBarTitle"], @"");  

            //Give tab bar element an image  
            UIImage *tabBarImage = [UIImage imageNamed:[tabbarDictionary objectForKey:@"TabBarImage"]];  

            //create tabbar item and pass it configuration defined aboce  
            UITabBarItem *tabBarItem = [[UITabBarItem alloc]initWithTitle:tabBarTitle image:tabBarImage tag:x];  
            tabRootViewNavigationController.tabBarItem = tabBarItem;  
            [tabBarItem release];  
            [navigationElements addObject:tabRootViewNavigationController];  
            [tabRootViewNavigationController release];  

        }  

        [applicationHierarchy release];  

        self.tabBarController.viewControllers = [NSArray arrayWithArray:navigationElements]; //this "tabBarController" is attached to MainWindow.xib  

    }  

} 

The beauty of either approach is that in order to add/remove tabs in your application you just alter the elements to the plist.