views:

569

answers:

6

I am using the NSXMLParser to get new RSS stories from a feed and am displaying them in a UITableView. However now I want to take ONLY the images, and display them in a UIScrollView/UIImageView (3 images side-by side). I am completely lost. I am using the following code to obtain 1 image from a URL.

   NSURL *theUrl1=[NSURL URLWithString:@"http://farm3.static.flickr.com/2586/4072164719_0fa5695f59.jpg"];
 JImage *photoImage1=[[JImage alloc] init];
 [photoImage1 setContentMode:UIViewContentModeScaleAspectFill];
 [photoImage1 setFrame:CGRectMake(0, 0, 320, 170)];
 [photoImage1 initWithImageAtURL:theUrl1];
 [imageView1 addSubview:photoImage1];
 [photoImage1 release];

This is all I have accomplished, and it works, for one image, and I have to specify the exact URL. What would you recommend I do to accomplish this?

A: 

it sounds like you need to first identify the xml tag that identifies the images in your xml document. you should be able to do this by typing whatever API call you're using into a browser address bar.

once you've done that you can make an array of image urls from the nsxmlparser delegate method that receives new data.

once you have the array of image url's you can do something similar to what you are doing above except that you would use NSURL *theUrl1=[myArray objectAtIndex:...

you can arrange the images just by changing their centre location: image.center = CGPointMake(160,240)..

hope that helps. there are apple docs for nsxmlparser.

Remover
The URL's are dynamic, as I am using feedburner, this will work with "any" rss feed? Thanks!
Matthew Saeger
Not sure what you mean by 'the url's are dynamic'. but this should work for any xml document as long as there is a tag in the xml document to identify the image urls.
Remover
By that I meant all the images are hosted different places...
Matthew Saeger
ok. the xml tag´s are not guaranteed to be the same for the image URL´s if that´s what you were wondering. it depends on what the author of the xml document system chose to implement.
Remover
A: 

You can also try dictionary implementation while fetching data from API call. First you have to identify xml tag that identifies images in xml document, then you can assign each image with its corresponding story as image's key into a dictionary. It will make sure that for particular story only its associated image will be displayed. Then u can use this information later in your application as the requirement varies.

NSMutableDictionary *mutDict = [[NSMutableDictionary allloc]init]; if([elementName isEqualToString:@"story_image"]) { [mutDict setObject:currentImage forKey:currentStory]; }

I want to suggest you to use JSON instead of xml as it is lightweight data-interchange format. It would save lot of formatting and effort also.

Kundan Pandit
I'm definitely open to giving JSON a try, however I've got no clue how do do that. lol
Matthew Saeger
You can visit this page http://code.google.com/p/json-frameIt is definitely going to help you.You have to just download the framework and then use in your application. tO get the live data you have to do same thing as in XMLParsing NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; NSDictionary *JDict = [jsonString JSONValue];or NSArray * JArr = [jsonString JSONValue];depending upon what your datafeed contains.
Kundan Pandit
A: 

You can visit this page http://code.google.com/p/json-frame

It is definitely going to help you. You have to just download the framework and then use in your application.
To get the live data you have to do same thing as in XMLParsing

    NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];


    NSDictionary *JDict = [jsonString JSONValue];

or

    NSArray * JArr = [jsonString JSONValue];

depending upon what your data-feed contains.

Kundan Pandit
I have added the JSON Framework to my project, however I don't know what I would do to pull the image from the RSS feed... Any way you can email me to eliminate the StackOverflow middleman? my address is [email protected] Thanks
Matthew Saeger
A: 

I've been using NSXMLParser myself and storing the results using CoreData. I use a version of Björn Sållarp's Parser class from his CoreData example code.

My images end up as NSData/Binary in a SQLite database, but they might just as well get put into an array of UIImage for immediate display.

Extract from Parser.m: (from Björn Sållarp)

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{    

    if ([elementName isEqualToString:@"imagetag"]) 
    {
        UIImage *newImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:currentString]]];

        NSData *imageData = UIImagePNGRepresentation(newImage);

        [currentSearchResult setImage:imageData];

        currentString = nil;
        return;
    }

Called from my view with:

NSString *searchURL = @"http://www.feedurl.com/feed/address/feed.xml";
NSURL *xmlURL = [NSURL URLWithString:searchURL];

Parser *xmlParse = [[Parser alloc] initWithContext:managedObjectContext];
[xmlParse parseXMLFileAtURL:xmlURL parseError:&parseError];

That code assumes your XML document contains image URLs with the tag format:

<imagetag>http://example.com/path/to/image.png&lt;/imagetag&gt;

Even if you're not using CoreData, working through the example at that link would be instructional for processing XML with NSXMLParser.

hjd
A: 

HI hjd-

I'm having the same issue with rss images. I see the snippet of code above. can you tell mewhere do I place the NSXMLParser statement? Currently, I have in my .m:

*- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (qName) { elementName = qName; // switch for the qName }

if ([elementName isEqualToString:@"title"]) { currentNewsArticle.headline = propertyValue; } else if ([elementName isEqualToString:@"description"]) { currentNewsArticle.content = propertyValue; } else if([elementName isEqualToString:@"item"]) { [(id)[self delegate] performSelectorOnMainThread:@selector(addNewsArticle:) withObject:currentNewsArticle waitUntilDone:NO]; } [propertyValue release]; propertyValue = nil; }*

Can you tell me where does the code to pull the rss images goes in my .m file?

Much appreciated.

CJA

cja
+1  A: 

Further to my other answer, which uses some helper classes and kinda assumes you're storing stuff with Core Data, here's a pure NSXMLParser way to do it.

In this example I'm assuming you have three UIImageViews setup with tags (100,101,102) so we can access them. First off, the code that starts the parser:

    // Set the URL with the images, and escape it for creating NSURL
    NSString *rssURLString = @"http://feeds.gettyimages.com/channels/RecentEditorialEntertainment.rss";
    NSString *escapedURL = [rssURLString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
    NSURL *rssURL = [NSURL URLWithString:escapedURL];

    // rssParser is an NSXMLParser instance variable
    if (rssParser)  [rssParser release];    
    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:rssURL]; 
    [rssParser setDelegate:self];   
    success = [rssParser parse];    // return value not used

At this point the parsing starts and NSXMLParser will fire off calls to it's delegate methods as it finds different start and end elements in the XML.

In this example I am only writing the didStartElement method:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{   
    // look for an attribute called url
    if ([attributeDict objectForKey:@"url"]) {

        currentString = [attributeDict objectForKey:@"url"];        
        NSLog(@"Image URL: %@", currentString);

        NSString* escapedURL = [currentString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
        UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:escapedURL]]];        

        UIImageView * tmpImageView = (UIImageView*)[scrollView viewWithTag:100+imageCount];
        [tmpImageView setImage:image];

        NSLog(@"images found: %d", imageCount);
        imageCount++;       
        if (imageCount>2) [rssParser abortParsing];     
    }
}

Here we look to see if the attributeDict (an NSDictionary object) contains a url attribute. If so, we grab it into currentString and then escape it, just incase it has characters that NSURL will barf on. Then we create an image from that URL and set the appropriate UIImageView image based on the tag numbers. imageCount is a counter; once we've done three images we tell the NSXMLParser to abort parsing the XML.

If your XML puts the URL inside element tags like:

<image>http://example.com/image.jpg&lt;/image&gt;

You'll need to do a bit more work with didEndElement and foundCharacters. See the quite excellent Introduction to Event-Driven XML Programming Guide for Cocoa.

I knocked together a quick and dirty app to demo this, you can grab it here.

hjd