Hi, this is probably a very simple question to you (being a complete newbie) but basically I'm trying to create a news page where it'll read the XML file snd add to the table on load, then a 'refresh' button that'll retrieve any new content.
I've basically gathered a bunch of tutorials together but now found myself stuck.
Any help or guidance would be greatly appreciated.
hey,
I looked at your title and then looked at how many reviews you had and nil response, so for a minute i thought jee that's strange howcome for such a simple question no answers. But when i read your thread it was clear. So you might have to be very specific on which function you are having trouble calling? or piece of code exactly where you are either not understanding it or is not working? else it would be hard. Also ****-tailing the code only helps if you understand the code and exactly know what you are trying to do and what is each piece doing.
regards
mimran
the problem that I'm having is the table and the cells are trying to populate themselves from the Array 'articles' on startup. 'articles' Array is only populated when you click the UIbutton.
How do I tell the code to populate the table cells after you click the button? (when the 'articles' array is populated).
I've had 5 mins to quickly write this reply, so if it doesn't make sense still I'll write something better when I get back from the christmas decoration shop with the girlfriend!
Table view cells are not populated once and for all. Their contents is defined by the delegate methods which are called by the system framework as needed. If you create a table before their contents are available, then just return zero for the number of sections and rows. Then when new contents becomes available (like when the user taps on the button you mentioned), the you can call reloadData for the table, which will cause the delegate methods to be called again. This time, the delegate methods can return values appropriate to the new contents.
Ah! I just switched it over to a UITableViewController and added your code.
After I hit the button to retrieve the RSS I receive an 'Program received signal: “EXC_BAD_ACCESS”.' when numberOfSectionsInTableView is set to return 1
when numberOfSectionsInTableView is set to return 0. Again it receives the RSS fine but no results are displayed.
How would you set the return value on numberOfSectionsInTableView back to 1 when you hit the refresh button? Or even better, retrieve the RSS onLoad then render the Table after the RSS has returned some values?
updated code below
Code:
//
// LocalNews.m
// WCC
//
// Created by macbookpro on 04/12/2010.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "LocalNews.h"
@implementation LocalNews
#pragma mark -
#pragma mark View lifecycle
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)err {
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Validation Error"
message:err.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)err {
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Fatal Error"
message:err.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser {
[articles removeAllObjects];
}
-(void)parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
namespaceURI:(NSString *) namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
currentElement = elementName;
if ([elementName isEqualToString:@"item"])
{
itemActive = YES;
currentTitle = [[NSMutableString alloc] init];
currentGuid = [[NSMutableString alloc] init];
pubDate = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString*)string {
if (itemActive) {
NSString *fixedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([currentElement isEqualToString:@"title"])
[currentTitle appendString:fixedString];
if ([currentElement isEqualToString:@"link"])
[currentGuid appendString:fixedString];
if ([currentElement isEqualToString:@"pubDate"])
[pubDate appendString:fixedString];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"item"])
{
NSDictionary *record = [NSDictionary dictionaryWithObjectsAndKeys:
currentTitle,@"articleTitle",
currentGuid,@"articleURL",
pubDate,@"publicationDate",
nil];
[articles addObject:record];
[currentTitle release];
[currentGuid release];
[pubDate release];
itemActive = NO;
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@"%@",articles);
[self.tableView reloadData];
}
- (void)retrieveXML:(id)sender {
[parser parse];
}
- (void)createUI {
UIButton *btnShowQuickLook = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnShowQuickLook.frame = CGRectMake(50,50,120,34);
[btnShowQuickLook setTitle:@"Refresh News" forState:UIControlStateNormal];
[btnShowQuickLook addTarget:self action:@selector(retrieveXML:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btnShowQuickLook];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Local News";
articles = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:@"http://rss.cnn.com/rss/edition.rss"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser.delegate = self;
[parser parse];
NSLog(@"RSS feed recieved");
[self.tableView reloadData];
[self createUI];
}
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSLog(@"Articles Found: %@",[articles count]);
return [articles count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Cell Added");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [articles objectAtIndex:indexPath.row];
/*NSString *imageName = [NSString stringWithFormat:@"%@.png",[arrCountries objectAtIndex:indexPath.row]];
cell.imageView.image = [UIImage imageNamed:imageName];*/
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
There should be no problem returning 1 all the time for the number of sections. But the returned number of rows should accurately represent the number of elements in articles. If articles has not yet been filled, then it should be empty, and [articles count] should be zero. If you return zero for the number of rows, then that should be the end of it. The system will not ask you for any cells, and the table should display nothing, but it should not crash. If you are getting a crash then try to find out exactly which statement is crashing by using the debugger. If articles is invalid, then perhaps that is causing the crash. You should make sure that articles is created empty before creating the table. That way articles will always be valid when you access it in you cellForRowAtIndex, or your numberOfRowsInSection.