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
Related
I have written the below code to parse RSS feeds. but i keep getting EXC_BAD_ACCESS in foundCharacter method when it tries to compare element with #"title".Any idea where am i going wrong?
NSMutableDictionary * item;
NSMutableString * title;
NSMutableString * link;
NSString *element;
NSMutableArray *feeds;
-(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]];
NSLog(#"feeds :: %#",feeds);
}
}
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([element isEqualToString:#"title"]) {
[title appendString:string];`enter code here`
}else if ([element isEqualToString:#"link"]){
[link appendString:string];
}
}
I think the mistake is in this line:
element = elementName;
You have to init the variable element. So write this one:
element = [[NSString alloc] initWithString:elementName];
Then it should work.
I am currently building an iOS RSS feed app and it will have a tableView displaying the feeds. I wish to put an ImageView in each table view cell and the image will be from the website of that RSS feed. I am currently using the NSXMLParserDelegate in my file. I just need to know how to get the image from the website... Here is just an example of the rss feed i am using. http://www.forbes.com/most-popular/feed/ Is it possible to get an image from this URL? Thanks for any help! This is my code so far.What do i need to add in order to get the image?
#import "JSSSecondViewController.h"
#import "JSSDetailViewController.h"
#import "JSSFirstViewController.h"
#interface JSSSecondViewController () {
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSString *element;
}
#end
#implementation JSSSecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://rss.cnn.com/rss/cnn_tech.rss"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
// Do any additional setup after loading the view, typically from a nib.
}
- (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"];
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.tableView2 reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView2 indexPathForSelectedRow];
NSString *string = [feeds[indexPath.row] objectForKey: #"link"];
[[segue destinationViewController] setUrl:string];
}
}
#end
This is the XML I will be parsing...
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title>CNET Gaming</title>
<link>http://www.cnet.com/#ftag=CADa872701</link>
<description>
Game on! Get the latest in gaming news, video game reviews, computer games & video game consoles.
</description>
<language>en</language>
<pubDate>Thu, 10 Apr 2014 23:23:50 GMT</pubDate>
<lastBuildDate>Thu, 10 Apr 2014 23:23:50 GMT</lastBuildDate>
<ttl>2</ttl>
<image>
<title>CNET Gaming</title>
<url>
http://i.i.cbsi.com/cnwk.1d/i/ne/gr/prtnr/CNET_Logo_150.gif
</url>
<link>http://www.cnet.com/#ftag=CADa872701</link>
</image>
<item>
<title>
Get a Moga Mobile Gaming System for Android for $13 shipped
</title>
<link>
http://www.cnet.com/news/get-a-moga-mobile-gaming-system-for-android-for-13-shipped/#ftag=CADa872701
</link>
<description>
This Bluetooth game controller sold for $49.99 when it debuted last year.<img width='1' height='1' src='http://cnet.com.feedsportal.com/c/34938/f/645455/s/38e7da50/sc/5/mf.gif' border='0'/><br clear='all'/><br/><br/><img src="http://da.feedsportal.com/r/193360522992/u/191/f/645455/c/34938/s/38e7da50/sc/5/rc/1/rc.img" border="0"/><br/><img src="http://da.feedsportal.com/r/193360522992/u/191/f/645455/c/34938/s/38e7da50/sc/5/rc/2/rc.img" border="0"/><br/><img src="http://da.feedsportal.com/r/193360522992/u/191/f/645455/c/34938/s/38e7da50/sc/5/rc/3/rc.img" border="0"/><br/><br/><img src="http://da.feedsportal.com/r/193360522992/u/191/f/645455/c/34938/s/38e7da50/sc/5/a2.img" border="0"/><img width="1" height="1" src="http://pi.feedsportal.com/r/193360522992/u/191/f/645455/c/34938/s/38e7da50/sc/5/a2t.img" border="0"/>
</description>
<pubDate>Thu, 10 Apr 2014 23:21:10 GMT</pubDate>
<guid>
http://www.cnet.com/news/get-a-moga-mobile-gaming-system-for-android-for-13-shipped/#ftag=CADa872701
</guid>
<dc:creator>Rick Broida</dc:creator>
<media:thumbnail url="http://cnet3.cbsistatic.com/hub/i/r/2014/04/02/0eeab98d-efb9-4779-a973-7b709f4fbb06/thumbnail/300x230/c7edbbac37a02b874a7bcfe373f6f9ec/moga-mobile.jpg"/>
</item>
<item>
<title>Xbox boss: Microsoft won't sell us off</title>
<link>
http://www.cnet.com/news/xbox-boss-microsoft-wont-sell-us-off/#ftag=CADa872701
</link>
This is just a snippet. It contains a reference to an image. In this case, how can i display the image in my tableView?
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];
I am making an app for my site, which I need to include images in the table view.
RSS picture I'm trying to find:
<description>
<![CDATA[
<img width="1100" height="1010" src="http://www.x86cam.com/wp-content/uploads/2013/11/twilight_sparkle_with_the_twicane_by_diamondsword11-d6vn28u.png" class="attachment- wp-post-image" alt="twilight_sparkle_with_the_twicane_by_diamondsword11-d6vn28u" style="display: none" />I will not give any links, but I just need to warn y’all. Watch out for spoilers all over sites. Source: Here
]]>
</description>
I don't know how I would find the image tag in this.
#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];
}
}
-(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"];
[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];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
I would like the app to parse the XML and find the <img> tag in the <description> and then get the src=""
Anyone willing and able to help me on this?
The image link your are looking to extract is inside a CDATA block, but rss parser ignores CDATA block.
If you need to extract the string from CDATA, you could use this block in foundCDATA:
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
NSMutableString *cdstring = [[NSMutableString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
}
now the mutablestring "cdstring" will be containing:
"img width="1100" height="1010" src="http://www.x86cam.com/wp-content/uploads/2013/11/twilight_sparkle_with_the_twicane_by_diamondsword11-d6vn28u.png" class="attachment- wp-post-image" alt="twilight_sparkle_with_the_twicane_by_diamondsword11-d6vn28u" style="display: none" />I will not give any links, but I just need to warn y’all. Watch out for spoilers all over sites. Source: Here"
now just search for src=" using stringcontainsstring and extract the link
-cheers :)
P.S: if you can ask the provider of rss feed to give it in normal block without CDATA, you can extract the link easily by using following method:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict
// In this method parameter 'attributeDict' will return you all the sub attributes of main attribute.
// In your case its 'url' of Picture.
// I hope this will help you. Check this out.
if ([element isEqualToString:#"img"]){
[attributeDict valueForKey:<#"src">]
}
Hope it helps
I'm doing a test where I'm building a news feed iOS app, using rss feeds like this one: http://www.20minutos.es/iphoneapp/feeds/home/
I'm almost done, but I can't find the link to the thumbnail. I'm doing the parsing like this and I can find some enclosure, enclosure2x, thumbnail, thumbnail2x, but they're all empty strings:
- (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];
image = [[NSMutableString alloc] init];
image2x = [[NSMutableString alloc] init];
comments = [[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:image forKey:#"image"];
[item setObject:image2x forKey:#"image2x"];
[item setObject:comments forKey:#"comments"];
[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:#"veinteminutos:numComments"]) {
[comments appendString:[string stringByReplacingOccurrencesOfString:#" " withString:#""]];
}
//NSLog(#"string: %# \nelement: %# \n\n\n", string, element);
}
It's my first time parsing rss feeds, so I don't really know what to look for in there.
Thanks
You should parse out the media:thumbnail and media:thumbnail2x nodes in the parser:didStartElement:namespaceURI:qualifiedName:attributes: delegate method and extract the thumbnail URLs from the attributeDict dictionary:
- (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];
image = [[NSMutableString alloc] init];
image2x = [[NSMutableString alloc] init];
comments = [[NSMutableString alloc] init];
} else if ([element isEqualToString:#"media:thumbnail"]) {
image = [attributeDict objectForKey:#"url"];
} else if ([element isEqualToString:#"media:thumbnail2x"]) {
image2x = [attributeDict objectForKey:#"url"];
}
}
You can do the same for the enclosures, should you need them.