Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 12-04-2010, 05:37 AM   #1 (permalink)
iPhone Newbie
 
Join Date: Dec 2010
Location: Worcestershire, UK
Age: 24
Posts: 66
mwyld is on a distinguished road
Question Newbie Question: RSS and Table Views

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.

Many thanks
Matt

This is my code below, Im trying to get the

Code:
#import "News.h"


@implementation News


- (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);
}

- (void)retrieveXML:(id)sender {
	
	[parser parse]; 
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	
	NSLog(@"Articles Found: %@",[articles count]);
	return [articles count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
	NSLog(@"Creating and watching for reuseable cells");
	
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] 
				 initWithStyle:UITableViewCellStyleDefault 
				 reuseIdentifier:CellIdentifier] autorelease];
		NSLog(@"Replaced Cell: %@",cell);
    }
    
	// 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;
}


- (void)createUI {
	
	UIButton *btnShowQuickLook = [UIButton buttonWithType:UIButtonTypeRoundedRect];
	btnShowQuickLook.frame = CGRectMake(100,200,120,34);
	[btnShowQuickLook setTitle:@"Retrieve XML" 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/cnn_topstories.rss"];
	parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
	parser.delegate = self;
	
	[self createUI];
	
}

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (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 {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}


@end

Last edited by mwyld; 12-04-2010 at 02:35 PM.
mwyld is offline   Reply With Quote
Old 12-04-2010, 08:02 AM   #2 (permalink)
Registered Member
 
Join Date: Nov 2010
Posts: 42
mimran is on a distinguished road
Default

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
mimran is offline   Reply With Quote
Old 12-04-2010, 09:33 AM   #3 (permalink)
iPhone Newbie
 
Join Date: Dec 2010
Location: Worcestershire, UK
Age: 24
Posts: 66
mwyld is on a distinguished road
Default

I think I just tried to be as general as I could to get any suggestions if their is a better way to do an RSS list into a table view.

Ok, basically I've managed to get an RSS feed into the Console by clicking the UIButton in the view.

Code:
- (void)createUI {
	
	UIButton *btnShowQuickLook = [UIButton buttonWithType:UIButtonTypeRoundedRect];
	btnShowQuickLook.frame = CGRectMake(100,200,120,34);
	[btnShowQuickLook setTitle:@"Retrieve XML" forState:UIControlStateNormal];
	[btnShowQuickLook addTarget:self action:@selector(retrieveXML:) 
			   forControlEvents:UIControlEventTouchUpInside];
	[self.view addSubview:btnShowQuickLook];
}
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!
mwyld is offline   Reply With Quote
Old 12-04-2010, 10:08 AM   #4 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,549
RLScott is on a distinguished road
Default

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.
RLScott is offline   Reply With Quote
Old 12-04-2010, 12:08 PM   #5 (permalink)
iPhone Newbie
 
Join Date: Dec 2010
Location: Worcestershire, UK
Age: 24
Posts: 66
mwyld is on a distinguished road
Default

Thanks RLScott, that sounds good!

Although I'm still a little unsure on how I would alter my code above to what your saying.

Thanks for your help, much appreciated!
mwyld is offline   Reply With Quote
Old 12-04-2010, 12:24 PM   #6 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,549
RLScott is on a distinguished road
Default

I'm guessing that "News" is a UITableViewController? If so, then

Code:
[self.tableView reloadData];
Done right after "articles" is populated should do it.
RLScott is offline   Reply With Quote
Old 12-04-2010, 02:23 PM   #7 (permalink)
iPhone Newbie
 
Join Date: Dec 2010
Location: Worcestershire, UK
Age: 24
Posts: 66
mwyld is on a distinguished road
Default

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

Last edited by mwyld; 12-04-2010 at 02:37 PM.
mwyld is offline   Reply With Quote
Old 12-04-2010, 03:18 PM   #8 (permalink)
Registered Member
 
Join Date: Jun 2009
Location: Ypsilanti, Michigan
Age: 63
Posts: 1,549
RLScott is on a distinguished road
Default

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.
RLScott is offline   Reply With Quote
Reply

Bookmarks

Tags
refresh news, table view, xml feed

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 368
6 members and 362 guests
chemistry, daudrizek, HemiMG, Kirkout, MarkC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,665
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, daudrizek
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:51 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0