iOS - Enclosure URL being detected, but not shown for different items - ios

I am currently trying to get images to be displayed in my Table View. But, it looks like when it gets the last image, it sets all of the images to that.
The image is from my first blog post.
Here's my code for the RSS detection:
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return feeds.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
NSString *textFiltered = [[feeds objectAtIndex:indexPath.row] objectForKey: #"description"];
cell.detailTextLabel.text = [textFiltered stringByConvertingHTMLToPlainText];
//cell.detailTextLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"pubDate"];
//NSString *imageURLString = [[feeds objectAtIndex:indexPath.row] objectForKey: #"enclosure"];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
cell.imageView.image = [UIImage imageWithData:imageData];
return cell;
}
#pragma mark - parsing of RssFeed Values
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc]init];
title = [[NSMutableString alloc]init];
link = [[NSMutableString alloc] init];
desc = [[NSMutableString alloc] init];
image = [[NSMutableString alloc] init];
pubDate = [[NSMutableString alloc] init];
feedEnclosure = [[NSMutableString alloc] init];
encodedContent = [[NSMutableString alloc] init];
//imageURL = [[NSURL alloc] init];
}if ([element isEqualToString:#"enclosure"]){
NSString *imageStr = [NSString stringWithString:[attributeDict objectForKey:#"url"]];
imageURL = [NSURL URLWithString:imageStr];
}
}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:desc forKey:#"description"];
[item setObject:pubDate forKey:#"pubDate"];
[item setObject:feedEnclosure forKey:#"enclosure"];
[item setObject:encodedContent forKey:#"content:encoded"];
[item setObject:imageURL forKey:#"url"];
[feeds addObject:[item copy]];
}
}
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([element isEqualToString:#"title"]) {
[title appendString:string];
}else if ([element isEqualToString:#"link"]){
[link appendString:string];
}else if ([element isEqualToString:#"description"]){
[desc appendString:string];
}else if ([element isEqualToString:#"pubDate"]){
[pubDate appendString:string];
}else if ([element isEqualToString:#"content:encoded"]){
[encodedContent appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
Do you people have an idea on how I could get this working?

You are using the ivar imageURL to set the image of each row in the table. This of course means every row will have the same image. You need to store the individual image URLs for each row in the row-specific data.
You seem to be setting the url key in your row-specific data. Use that instead of imageURL when setting up each cell.
Also note that it is a very bad idea to be loading the NSData object on the main thread for each cell. This will make your UI very choppy and unresponsive if the Internet connection is slow at all. There are many solutions to loading the images in the background.
Update:
Try this:
NSURL *url = feeds[indexPath.row][#"url"];
NSData *imageData = [NSData dataWithContentsIfURL:url];

Related

Fetch image from description in XML (RSS Feed)

I am having a hard time fetching the image from my RSS feed to Xcode. I have been able to get the date, title, even the category. The image is however in the first line of the description, as seen in the RSS feed below:
<item>
<title>Stevie Wonder Tribute</title>
<link>http://celebirious.com/bey/?p=6925</link>
<comments>http://celebirious.com/bey/?p=6925#comments</comments>
<pubDate>February 17, 2015</pubDate>
<dc:creator>
<![CDATA[ Haley ]]>
</dc:creator>
<category>
<![CDATA[ Uncategorized ]]>
</category>
<guid isPermaLink="false">http://celebirious.com/bey/?p=6925</guid>
<description>
<![CDATA[
<img src="http://i2.wp.com/celebirious.com/bey/wp-content/uploads/2015/02/normal_Tribute-004.jpg?fit=1024%2C1024" class="attachment-large wp-post-image" alt="normal_Tribute-004" />Beyonce performed during the Stevie Wonder: Songs In The Key Of Life – An All-Star GRAMMY Salute held at Nokia Theatre L.A. Live on February 10, 2015. Watch her performance below!
]]>
</description>
[..]
</item>
The XCode looks like this.
#interface APPMasterViewController () {
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *pubDate;
NSMutableString *category;
NSMutableString *link;
NSMutableString *description;
NSString *element;
}
Then I'm using SDWEBImage to try and outsource the image:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
carecell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.thetitle.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
NSString * imageURL = [[feeds objectAtIndex:indexPath.row] objectForKey: #"description"];
[cell.theimage sd_setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:#"candid-02.jpg"]];
return cell;
}
Lastly:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
pubDate = [[NSMutableString alloc] init];
category = [[NSMutableString alloc] init];
description = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:pubDate forKey:#"pubDate"];
[item setObject:category forKey:#"category"];
[item setObject:description forKey:#"description"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
}
if ([element isEqualToString:#"pubDate"]) {
[pubDate appendString:string];
}
if ([element isEqualToString:#"category"]) {
[category appendString:string];
}
if ([element isEqualToString:#"description"]) {
[description appendString:string];
}
else if ([element isEqualToString:#"link"]) {
[link appendString:string];
}
}
I feel like there is something missing, can someone please help?
I inserted an enclosure tag instead so I was about to get it working with this: Xcode Get image url from rss feed

self.tableview reload not working after app connects to the internet

I know that it has been many times stated this question but it seems i can't find a solution with my case. I have an application which has inside a view controller a container view controller which is a table view controller. In this table view are loaded some rss feeds. When i open my app with no internet connection my data are not appearing, but after i connect my app to the internet my table should be reloaded after i pull down the table, but it doesn't. I tried many things but i can't find a solution. I am posting my code so if anyone could help i would appreciate it. Thank you.
- (void)viewDidLoad {
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://url"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
self.tableView.dataSource = self;
self.tableView.delegate = self;
if (networkStatus == NotReachable)
{
number = 0;
}
else{
number = 1;
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
num = 5;
}
else{
num = feeds.count;
}}
These are my main methods for calling the table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return number;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(feeds.count > num){
return num + 1;
}
return num;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.userInteractionEnabled = YES;
// Set up the cell
[cell.textLabel setFont:[UIFont fontWithName:#"Verdana" size:15]];
[cell.textLabel setNumberOfLines:2];
[cell.detailTextLabel setFont:[UIFont fontWithName:#"Verdana" size:12]];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
}
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
} else if ([element isEqualToString:#"link"]) {
[link appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
This is where i reload my data after pulling down
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGPoint targetPoint = *targetContentOffset;
CGPoint currentPoint = scrollView.contentOffset;
if (targetPoint.y > currentPoint.y) {
[self.tableView reloadData];
}}
Did you declare the class that implements scrollViewWillEndDragging as implementing UIScrollViewDelegate? Try putting a break point inside that event handler and see if your code is getting executed when you pull down the list.
EDIT: You are only updating the number variable when the view loads for the first time and you are initializing it to 0 whenever there is no internet present. Hence, you are never going to get any rows because there are no sections to display it from.

Load UITableViewCell images using parsing

I followed a tutorial of JSON parsing and modified my rss feed to post featured image in a tag if xxxxxxxx and now i need to assign each image link to it's corresponding row next to it's title.
I saved links in a nsmutablestring and used it's url to assign it to my image like this
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[feeds objectAtIndex:indexPath.row] objectForKey: #"thumbnail"]]]];
but it's not working , this is the only piece of my application left, please help me through it
Here is my code
#import "APPMasterViewController.h"
#import "APPDetailViewController.h"
#interface APPMasterViewController () {
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSMutableString *thumbnail;
NSString *element;
}
#end
#implementation APPMasterViewController
- (void)viewDidLoad {
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://icuore.ly/feed"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return feeds.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[feeds objectAtIndex:indexPath.row] objectForKey: #"thumbnail"]]]];
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
thumbnail = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:thumbnail forKey:#"thumbnail"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
} else if ([element isEqualToString:#"link"]) {
[link appendString:string];
}
else if ([element isEqualToString:#"thumbnail"]) {
[thumbnail appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *string = [feeds[indexPath.row] objectForKey: #"link"];
[[segue destinationViewController] setUrl:string];
}
}
#end
The reason your image isn't showing is because your image hasn't finished downloading before cellForRowAtIndexPath: is called. Remember this method is responsible for displaying the cells of your UITableView. When setting your cells with data from the Internet, it's important to reload the data of your UITableView after it finishes downloading. I recommend accomplishing this using NSURLSession to download your image as it has delegates that handle download updates. For example, one of these delegates is:
URLSession:downloadTask:didFinishDownloadingToURL:
Once this delegate is implemented, it will be called after your session download has finished. Hypothetically, in the said delegate, you would update your image view and call [tableView reloadData].
i found the right way
//cell image set
NSString *imageStr = [[feeds objectAtIndex:indexPath.row] objectForKey: #"thumbnail"];
NSString *trimmedString = [imageStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *string1=[trimmedString stringByReplacingOccurrencesOfString:#"/n" withString:#""];
NSURL *url = [NSURL URLWithString:string1];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *newImage = [UIImage imageWithData:data];
cell.imageView.image = newImage;
return cell;
i hope it helps you all

How do I parse in a background thread?

I basically used this tutorial to make a RSS reader. I think this one is not multithreaded.
I also took a look at raywenderlich's tutorial which should be multithreaded, but I couldn't use this because it is out of date and the library doesn't work anymore.
The first tutorial loads the content pretty fast. But I try to load it in a pageview. So I have 5 pages each loading a different RSS.
In the tutorial (and so in my code) parsing happens in ViewDidLoad :
- (void)viewDidLoad
{
[super viewDidLoad];
//initialize
images = [[NSMutableArray alloc] init];
feeds = [[NSMutableArray alloc] init];
currentRssUrl = [NSURL URLWithString:self.rssUrl];
parser = [[NSXMLParser alloc] initWithContentsOfURL:currentRssUrl];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
Now it start with me not completely understanding the code but I think [parser parse] does the parsing.
here is the rest of my code.
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return feeds.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.numberOfLines = 2;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
NSString *yt = #"videos";
NSString *videoCheck = [currentRssUrl absoluteString];
if(images.count > 0)
{
NSURL *imgUrl = [NSURL URLWithString:images[indexPath.row]];
NSData *data = [[NSData alloc] initWithContentsOfURL:imgUrl];
UIImage *tmpImage = [[UIImage alloc] initWithData:data];
cell.imageView.image = tmpImage;
}
else if ([videoCheck rangeOfString:yt].location != NSNotFound)
{
NSString *ytLink = [feeds[indexPath.row] objectForKey: #"link"];
NSArray *stringArray = [ytLink componentsSeparatedByString:#"/"];
NSString *ytId = stringArray[stringArray.count-1];
ytId = [ytId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *ytThumbUrl = [NSString stringWithFormat:#"http://img.youtube.com/vi/%#/default.jpg", ytId];
NSURL *imgUrl = [NSURL URLWithString:ytThumbUrl];
NSData *data = [[NSData alloc] initWithContentsOfURL:imgUrl];
UIImage *tmpImage = [[UIImage alloc] initWithData:data];
cell.imageView.image = tmpImage;
}
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
element = elementName;
if ([element isEqualToString:#"item"])
{
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
enclosure = [[NSMutableString alloc] init];
}
if(![elementName isEqual:#"enclosure"])
return;
NSString *urlTitle = #"app_thumb";
//als de title gelijk is aan app_thumb
if([[attributeDict objectForKey:#"title"] isEqual:urlTitle])
{
//lees de url attribute uit
NSString * name = [attributeDict objectForKey:#"url"];
// voeg de url toe aan images
[images addObject:name];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"item"])
{
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:enclosure forKey:#"enclosure"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"])
{
[title appendString:string];
}
else if ([element isEqualToString:#"link"])
{
[link appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tableView reloadData];
}
So how can I make the parsing in a background thread. Also when is it best to load. In my android version I started a AsyncTask when the page became visible.
I find this very hard but as far as this question goes. I want to know how to do the parsing in a background thread, any extra multithreading tips are appreciated.
Try with the GCD :
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Background running Code
/*
//initialize
images = [[NSMutableArray alloc] init];
feeds = [[NSMutableArray alloc] init];
currentRssUrl = [NSURL URLWithString:self.rssUrl];
parser = [[NSXMLParser alloc] initWithContentsOfURL:currentRssUrl];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
*/
});
Then update the result in the Main Thread:
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
dispatch_sync(dispatch_get_main_queue(), ^{
// [self.tableView reloadData];
});
}
Here is the good tutorial.

empty tableview rows when parsing with NSXMLPaerser using ASIHTTPRequest

I'm pretty new iPhone development and i have a problem.
After several hours of searching and digging in the code I could understand the source of the problem (hope) but do not know how to solve it.
the problem is that the tableView cells loads before the parser is finish so the "[array count]" is nil.
When I set the 'number of rows in section' manually, the table does appear, but only after a few sec and scrolling up and down.
i have 2 classes, one for XMLParser and one for show the tableView.
According to what I read before I opened this question is that i need to reload the tavleview data but becuase i have 2 various classes i dont know how to do that.
any ideas?
Thanks in davance!
here is my XMLParser code:
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
self.titles = [[NSMutableArray alloc]init];
self.descriptions = [[NSMutableArray alloc]init];
self.links = [[NSMutableArray alloc]init];
self.pubDate = [[NSMutableArray alloc]init];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
}
BOOL isItem = NO;
BOOL isTitle = NO;
BOOL isDesription = NO;
BOOL isImg = NO;
BOOL isPubDate = NO;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"item"]) {
isItem = YES;
}
if ([elementName isEqualToString:#"title"]) {
isTitle=YES;
self.titlesString = [[NSMutableString alloc]init];
}
if ([elementName isEqualToString:#"description"]) {
isDesription = YES;
self.descriptionString = [[NSMutableString alloc]init];;
self.data = [NSMutableData data];
}
if ([elementName isEqualToString:#"pubDate"]) {
isPubDate = YES;
self.pubDateString = [[NSMutableString alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if(isItem && isTitle){
[self.titlesString appendString:string];
}
if (isItem && isDesription) {
[self.descriptionString appendString:string];
}
if (isItem && isPubDate) {
[self.pubDateString appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
if (self.data)
[self.data appendData:CDATABlock];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"item"]) {
isItem = NO;
[self.titles addObject:self.titlesString];
[self.descriptions addObject:self.descriptionString];
[self.pubDate addObject:self.pubDateString];
NSLog(#"%#,%#,%#,",self.titlesString,self.descriptionString,self.pubDate);
}
if ([elementName isEqualToString:#"title"]) {
isTitle=NO;
}
if ([elementName isEqualToString:#"description"]) {
isDesription = NO;
if ([self.data length] > 0)
{
NSString *htmlSnippet = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
NSString *imageSrc = [self firstImgUrlString:htmlSnippet];
[self.links addObject:imageSrc];
}
self.data = nil;
}
if([elementName isEqualToString:#"pubDate"])
isPubDate = NO;
}
- (NSString *)firstImgUrlString:(NSString *)string
{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult *result = [regex firstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
if (result)
return [string substringWithRange:[result rangeAtIndex:2]];
return nil;
}
and here's my show tableView code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:#selector(toggleLeftView)];
NSURL *url;
if (!self.isGetLink)
url = [NSURL URLWithString:#"http://www.ynet.co.il/Integration/StoryRss2.xml"];
else
url = [NSURL URLWithString:self.linkForParsingString];
if (!self.xmlParser) {
self.xmlParser = [[XMLparser alloc]init];
[self.xmlParser LoadXMLWithURl:url];
}
self.isGetLink = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
{
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.xmlParser.titles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.lblTitle.text = [self.xmlParser.titles objectAtIndex:indexPath.row];
cell.lblTitle.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.xmlParser.links objectAtIndex:indexPath.row]]];
cell.imgView.image = [UIImage imageWithData:data];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 82;
}
#pragma mark - Table view delegate
NSString *curnentDes;
NSString *currentTitle;
NSString *currentPubDate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReadViewController *rvc = [[ReadViewController alloc]initWithNibName:#"ReadViewController" bundle:nil];
curnentDes = [self.xmlParser.descriptions objectAtIndex:indexPath.row];
currentTitle = [self.xmlParser.titles objectAtIndex:indexPath.row];
currentPubDate = [self.xmlParser.pubDate objectAtIndex:indexPath.row];
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc]init];
[inputFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss Z"];
NSDate *inputDate = [inputFormatter dateFromString:currentPubDate];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc]init];
[outputFormatter setDateFormat:#"dd/MM/yyyy HH:mm"];
NSString *outputDate = [outputFormatter stringFromDate:inputDate];
rvc.description = curnentDes;
rvc.stitle = currentTitle;
rvc.pubDate = outputDate;
[self.navigationController pushViewController:rvc animated:YES];
}
Pretty simple reload the table after your parsing is done, you are good to go. The reason your data comes after scrolling is your array is updated at a later point and then cellForRowAtIndex is called and array has content so you see rows.
Note: cellForRow is called for every row (hope you know that).
Using notification:
In your parser class
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[[NSNotificationCenter defaultCenter ]postNotificationName:#"parsingComplete" object:nil];
}
In ViewDidLoad of your table view class add this code and add the other functions anywhere in ur class:
your viewDidLoad(edited)
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(parsingComplete) name:#"parsingComplete" object:nil];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:#selector(toggleLeftView)];
NSURL *url;
if (!self.isGetLink)
url = [NSURL URLWithString:#"http://www.ynet.co.il/Integration/StoryRss2.xml"];
else
url = [NSURL URLWithString:self.linkForParsingString];
if (!self.xmlParser) {
self.xmlParser = [[XMLparser alloc]init];
[self.xmlParser LoadXMLWithURl:url];
}
self.isGetLink = NO;
}
//Function to handle notification:
-(void)parsingComplete
{
NSLog(#"parsing results: %#",self.xmlParser.titles);
//change your tableViewName
[yourTableView reloadData];
}
//removing notification:
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Reload the table once parsing is completed. Use delegate methods to reload the table view from didEndElement method. Try some think like this.
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"Final Element"])
{
// Reload your table View using delegates
}
}

Resources