I'm developing an iPhone application which uses a TableView to display XML data. The XML data comes from an external resource and is parsed and put into an object for use as a table dataSource. The application uses a UITabBar and multiple ViewControllers all programmatically created and using the same dataSource.
Everything is fine and dandy, but I'd like to implement a refresh button, so that a user can refresh the content (globally, so all the ViewControllers should be updated). The parser will query the XML again and create a new object. The problem I'm having is that I can't seem to repopulate the tableview with my new data. I get the updated data object. Actually updating the tableview is a problem though. I've tried to set setDataSource
and call reloadData
, but this results in a crash due to an unrecognised selector.
The XML stuff is called from my AppDelegate and all the parsing logic is in Parser.m. The refresh function is called in RootViewController.m, which implements the UITableViewDataSource protocol:
- (void)refreshXMLFeed:(id)sender {
NSArray *tableControllersData = [appDelegate getData];
[self.tableView setDataSource: tableControllersData];
[self.tableView reloadData];
}
How would I approach this issue? Should get the new data and reload the table view in the RootViewController as I have been trying to accomplish. Or should the data parsing be triggered in the AppDelegate and only the reloading of the TableView in RootViewController.
If necessary I can update my question with the necessary code, I'm not sure which parts are relevant at this point.
RootViewController.h:
#import <UIKit/UIKit.h>
@interface RootViewController : UITableViewController {
MyAppDelegate *appDelegate;
NSArray *tableDataArray;
}
@property (nonatomic, retain) NSArray *tableDataArray;
- (IBAction)refreshXMLFeed:(id)sender;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableDataSource:(NSArray*)tableData;
@end
RootViewController.m:
#import "CustomCell.h"
#import "MyAppDelegate.h"
#import "RootViewController.h"
#import "DetailViewController.h"
@implementation RootViewController
@synthesize tableDataArray;
- (void)viewDidLoad {
[super viewDidLoad];
}
//Override the default initWithNibName method
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableDataSource:(NSArray*)tableData {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
tableDataArray = [tableData retain];
}
return self;
}
-(void)viewWillAppear:(BOOL)animated {
appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewWillAppear:animated];
//Set the colour of the navigationController and add buttons
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
//Add the refresh button
UIBarButtonItem* refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshXMLFeed:)];
[self.navigationItem setLeftBarButtonItem:refreshButton animated:YES];
[refreshButton release];
}
#pragma mark Table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.tableDataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = @"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil) {
NSArray *cellNib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
for (id oneObject in cellNib) {
if ([oneObject isKindOfClass:[CustomCell class]]) {
cell = (CustomCell *)oneObject;
}
}
}
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.tableDataArray objectAtIndex:row];
cell.colorLabel.text = [rowData objectForKey:@"Type"];
cell.nameLabel.text = [rowData objectForKey:@"Name"];
UIImage *image = [UIImage imageNamed:[rowData objectForKey:@"Icon"]];
cell.image = image;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedRow = [tableDataArray objectAtIndex:indexPath.row];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
detailViewController. selectedRow = selectedRow;
[self.navigationController pushViewController:detailViewController animated:YES];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] init];
backButton.title = @"Back";
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[detailViewController release];
detailViewController = nil;
}
#pragma mark Refresh
- (void)refreshXMLFeed:(id)sender {
NSArray *tableControllersData = [appDelegate getData];
[self.tableView setDataSource: tableControllersData];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end