Matthew Saeger
Matthew Saeger

Reputation: 51

iPhone Development: Get images from RSS feed

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?

Upvotes: 5

Views: 3160

Answers (5)

hjd
hjd

Reputation: 870

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</image>

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.

Upvotes: 3

hjd
hjd

Reputation: 870

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</imagetag>

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

Upvotes: 0

Kundan Pandit
Kundan Pandit

Reputation: 412

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.

Upvotes: 0

Kundan Pandit
Kundan Pandit

Reputation: 412

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.

Upvotes: 0

Remover
Remover

Reputation: 1638

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.

Upvotes: 0

Related Questions