Parsing XML in an iPhone App Tutorial

>>>>>>>>>>>
Update: A more recent and up to date version of this tutorial is on YouTube.

Check it out here.
http://www.youtube.com/watch?v=TG1XG45aObI&list=UUU6kI6XSmDdnnTUyvp8Pm5g&index=1&feature=plcp

It solves a couple issues. The first being the date problem where each tweet displayed the date my twitter account was created. And a second problem that had to do with scrolling and selecting a cell and having text layered on top of each other.

Alternatively you can just get the new updated version of the code here.
>>>>>>>>>>

Here’s where the older version starts.

This is a tutorial on parsing XML data in your iPhone app. I won’t be explaining things in great detail here because I assume if you are doing XML parsing you have some experience and don’t need to be shown a lot of the basics. At this point you most likely just want to see some code and implement it into your own app. If you have any questions feel free to ask.

Final App Shot

What we will be doing here is calling my Twitter account through a URL and receiving an XML of my status tweets. We’ll then parse that XML and show the tweets in a table view. This really isn’t much different than the way a Web Service will work. We are calling a URL and then receiving some data back. In this case it is Twitter that has done the web service part for us on their servers and they are kind enough to return our data in an XML format. We could be calling a Web Service that we have written on one of our own servers and then parsing the returned XML.

Anyway, here we go.

1.) Create a new Navigation-based Application named XMLParserTutorial. We will be displaying our parsed data in the UITableView.

2.) We need to create a class to hold the individual data after it’s parsed. In this case the data will be a tweet. So we will create a class named Tweet. Right click on Classes, select Add > New File … and choose Objective-C class (Subclass of NSObject) click Next and name it Tweet.

3.) Open up our Tweet header file (Tweet.h) and add two NSStrings. One for the tweet’s actual content and one for the date it was created.

#import 


@interface Tweet : NSObject 
{
	NSString	 *content;
	NSString	 *dateCreated;
	
}

@property (nonatomic, retain) NSString	 *content;
@property (nonatomic, retain) NSString	 *dateCreated;

@end

4.) Next open up the implementation file Tweet.m and synthesize our variables we just created.

#import "Tweet.h"


@implementation Tweet

@synthesize content, dateCreated;

@end

5.) We need to create our XMLParser object. Right click on Classes, select Add > New File … and choose Objective-C class (Subclass of NSObject) click next and name it XMLParser.

6.) Open up XMLParser.h. Import Tweet.h and implement the NSXMLParserDelegate protocol.

#import 
#import "Tweet.h"


@interface XMLParser : NSObject 

Declare variables for an NSMutableString, NSMutableArray, NSXMLParser and Tweet. Then set the properties for our tweets array and define a loadXMLByURL action.

#import 
#import "Tweet.h"


@interface XMLParser : NSObject 
{

	NSMutableString	*currentNodeContent;
	NSMutableArray	*tweets;
	NSXMLParser		*parser;
	Tweet			*currentTweet;
	
}

@property (readonly, retain) NSMutableArray	*tweets;

-(id) loadXMLByURL:(NSString *)urlString;


@end

7.) Open up XMLParser.m. Import our Tweet.h file, synthesize the tweets array and implement our loadXMLByURL action.

#import "XMLParser.h"
#import "Tweet.h"

@implementation XMLParser
@synthesize tweets;

-(id) loadXMLByURL:(NSString *)urlString
{
	tweets			= [[NSMutableArray alloc] init];
	NSURL *url		= [NSURL URLWithString:urlString];
	NSData	*data   = [[NSData alloc] initWithContentsOfURL:url];
	parser			= [[NSXMLParser alloc] initWithData:data];
	parser.delegate = self;
	[parser parse];
	return self;
}

We need to release the parser object we created so I am going to do that in a dealloc method that we’ll implement.

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

8.) There are three methods we need to implement that follow the NSXMLParserDelegate protocol. They are parser:didStartElement:namespaceURI:qualifiedName:attributes, parser:didEndElement:namespaceURI:qualifiedName and parser:foundCharacters.

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
	if ([elementname isEqualToString:@"status"]) 
	{
		currentTweet = [Tweet alloc];
	}
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	if ([elementname isEqualToString:@"text"]) 
	{
		currentTweet.content = currentNodeContent;
	}
	if ([elementname isEqualToString:@"created_at"]) 
	{
		currentTweet.dateCreated = currentNodeContent;
	}
	if ([elementname isEqualToString:@"status"]) 
	{
		[tweets addObject:currentTweet];
		[currentTweet release];
		currentTweet = nil;
		[currentNodeContent release];
		currentNodeContent = nil;
	}
}

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

I know the element name we are looking for because I have taken a peek at the XML that we will be parsing. If we were parsing a different XML we would need to know the names of the nodes in that XML we wanted to parse.

9.) Open up RootViewController.h. Import XMLParser.h and add our XMLParser and a UIImageView. The UIImageView is really just for cosmetics.

#import 
#import "XMLParser.h"

@interface RootViewController : UITableViewController 
{
	XMLParser *xmlParser;
	
	UIImageView *customImage;
}


@property (nonatomic, retain) UIImageView *customImage;

@end

10.) Now open up the implementation file (RootViewController.m). We need to import our Tweet.h file and synthesize our variable. Then in our viewDidLoad method we are going to access my twitter status tweets as XML and load it into our XML Parser. And just because I like to keep things aesthetically pleasing, we’ll set the title to “Tweets”.

#import "RootViewController.h"
#import "Tweet.h"


@implementation RootViewController

@synthesize customImage;

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad 
{
    
	xmlParser = [[XMLParser alloc] loadXMLByURL:@"http://api.twitter.com/1/statuses/user_timeline/KentFranks.xml"];
	
	
	[super viewDidLoad];
	
	self.title = @"Tweets";
	
}

11.) Let’s set up our table to display the tweets. I’ve set the number of sections to 1.

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

12.) I’m using the tweets array to set the number of rows in the sections.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    return [[xmlParser tweets] count];
}

13.) And then all the real work will get done in the tableView:cellForRowAtIndexPath method.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    
	UIImage	 *twitterLogo = [[UIImage imageNamed:@"twitter-logo.png"]autorelease];
	
	Tweet *currentTweet = [[xmlParser tweets] objectAtIndex:indexPath.row];
	
	CGRect imageFrame = CGRectMake(2, 8, 40, 40);
	self.customImage = [[[UIImageView alloc] initWithFrame:imageFrame] autorelease];
	self.customImage.image = twitterLogo;
	[cell.contentView addSubview:self.customImage];
	
	CGRect contentFrame = CGRectMake(45, 2, 265, 30);
	UILabel *contentLabel = [[[UILabel alloc] initWithFrame:contentFrame] autorelease];
	contentLabel.numberOfLines = 2;
	contentLabel.font = [UIFont boldSystemFontOfSize:12];
	contentLabel.text = [currentTweet content];
	[cell.contentView addSubview:contentLabel];
	
	CGRect dateFrame = CGRectMake(45, 40, 265, 10);
	UILabel *dateLabel = [[[UILabel alloc] initWithFrame:dateFrame] autorelease];
	dateLabel.font = [UIFont systemFontOfSize:10];
	dateLabel.text = [currentTweet dateCreated];
	[cell.contentView addSubview:dateLabel];
	
	
	
    return cell;
}

We are setting the current tweet to the object in our tweets array that matches indexPath.row.

Tweet *currentTweet = [[xmlParser tweets] objectAtIndex:indexPath.row];

Most of the rest of the code in here is just customizing the look of our cells. I’m not explaining this in detail because I’m assuming if you are mostly interested in parsing the XML. If you want to know more about customizing the table view cells you can take a look at the tutorial.

I have included one graphic in the display that you will need to add to your project “twitter-logo.png”. You can download the graphic from here, and then just right click on Resources and select Add > Existing Files … navigate to where you downloaded the file, then choose to copy the file into your project.

14.) The only other thing I’ve done here is set the height of our rows in the tableView:heightForRowAtIndexPath method. And the release our xmlParser object in dealloc.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	return 55;
}

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

That’s all there is to it. Make sure everything is saved, click Build and Run.

Simulator Shot


Here’s the code.



This entry was posted in Data and tagged , , , , , , , , , , , . Bookmark the permalink.

99 Responses to Parsing XML in an iPhone App Tutorial

  1. stephen says:

    dude dats one great tutorial…could u make a tutorial on webservices using plist..since its less memory overhead…thanks in advance

  2. Brad says:

    Hi Guys

    I’ve been trying to use this tutorial to integrate with my tab bar application, i can get the xmlparser to get the information from my url and i’ve output the elements to console using nslog to make sure they are being populated which they are but when i go back to the tableviewcontroller to try and output some content to the console or populate the tableview i get nothing.

    I was also having trouble at the beginning with when i compile the app this throws back an error “cannot find protocol declaration” and i had to remove it for the app to build, could this be something to do with why the app wont populate the table even though the elements populate?

    Any help would be appreciated.

    Thanks
    Brad

    • Kent says:

      Have you set the dataSource and delegate for the UITableView in Interface Builder? That’s kind of a guess without seeing exactly what’s going on. Feel free to give more specifics or post some code.

  3. David B. Bitton says:

    Thanks for the info! However, what would make this tutorial better would be code samples that aren’t images. Take a look at this:

    http://scottdensmore.typepad.com/blog/2011/04/objective-c-syntax-highlighter-reboot.html

    • Kent says:

      Thanks for the link I’ll look into it.

      • Kent says:

        Okay I’ve implemented a syntax highlighter for the code, but honestly I’m not totally thrilled with it. If anyone has a suggestion for another syntax highlighter you have experience with throw it my way.

        Thanks

  4. Matt says:

    I’m a beginning iPhone developer and this tutorial has helped me greatly. Nice and simple and it works, so thanks for this.

    However, I’m getting some serious memory leaks from this script. Sometimes it even quits with a EXC_BAD_ACCES signal, which definitely points to a leak.

    When using Analyze, it points to this line:
    xmlParser = [[XMLParser alloc] loadXMLByURL:@”http://rss.cnn.com/rss/edition.rss”];

    Tried releasing the allocated object, as it seems you haven’t, but that doesn’t work. Maybe the leak is coming from within the XMLParser class.

    Did you check it for leaks when you wrote this? Or am I missing something here? I would love for this to work without issues.

    Thanks!

    • Kent says:

      I actually don’t check much for leaks in the tutorials. For the most part they are just quick examples of some type of functionality and not fully functioning apps meant to run on their own, though most certainly can.

      I’ll try and take a look at the memory leak when I can and post what I find.

      Thanks for pointing it out.

    • Kent says:

      Matt, you were on the right track.

      The problem was when I set a retain property on xmlParser in the header file, it increased the retain count to 1, then when I alloc’d it in the implementation file, it increased the retain count to 2. So when you released the object it only took the retain count back to 1 because I hadn’t done any release on it.

      So here’s the fix. That variable doesn’t need properties set on it in the header file so just delete this line,
      @property (nonatomic, retain) XMLParser *xmlParser;
      and don’t synthesize it in the implementation file either. Then it will be at retain count of only 1 after we alloc it. We do need to add a release statement like you did. I’ll put it in the dealloc method and update my code here.

      I found a couple other problems too.
      In XMLParser.m the didStartElement method. Remove this line,
      currentNodeContent = [[NSMutableArray alloc] init];
      It was causing a leak as well because we also set it in the foundCharacters method which orphaned the first block of memory set aside for it.

      Finally we need to release our NSXMLParser object. I have added the dealloc method to the class and released it there.
      - (void) dealloc
      {
      [parser release];
      [super dealloc];
      }

      I think that covers it. I have made these changes and re-posted the code. Let me know if you have any questions.

      Thanks

      • Matt says:

        Thanks for taking the time to figure out the leaks. I have made the changes and it does not crash anymore and seems much more stable, so thanks! Learned something new.

        However (here we go again), I’m still getting leaks. They are minor this time around and I have located them using the Instruments tool.

        The current leaks are coming from initWithContentsOfUrl used by the parser within the XMLParser.m class. Very strange. I’ve been searching around trying to find a fix and it seems more people have had this problem. I’ve also read somewhere that this bug is known by Apple.

        Like I said, it’s a minor leak, but it still annoys me as I appreciate a clean app :)

        • Kent says:

          Okay, after doing some reading I see that this is a known bug that has been around for quite some time.

          Of course there are no shortage of people giving hack fixes, none of which are a good idea in my opinion. The right solution is not a hack at all, but a nice little work-around. The leak is indeed coming from the initWithContentOfUrl method of NSXMLParser. So the solution is not to use that method but instead init the xmlParser object with initWithData instead.

          I did this and ran it five times in Instruments never seeing the leak again. I’ve updated the tutorial and the code. Check out step 7 above.

          Let me know if this fixes it for you Matt, good luck.

          • Matt says:

            initWithData indeed fixed it, I’m seeing no more leaks, nice job.

            Good luck with this blog! I’ll be keep my eye on it.

  5. Moi says:

    Thank you this was very useful!

  6. Pingback: Array in RootViewController is not equal to the Array in XML Parser - iPhone Dev SDK Forum

  7. Rony says:

    Hello,

    Great tutorial :) I was wondering if you could possibly make a tutorial on fetching Youtube Content and have it update…

    I would really appreciate this :)

    Thanks in advance.
    Rony

    • Kent says:

      Hi Rony,

      You want to Fetch a YouTube video and play it in your app, is that what you are looking to do?
      I wasn’t clear on what you wanted to update after fetching video from YouTube.

  8. Harry Mulligan says:

    Hi Kent

    This is a great tutorial and so nearly does what I’m looking for….but not quite. I’m trying to parse html and I can see how to parse xml by pointing at the element(s) that you want to start and end at but I can’t see a way to get the text from html when all the html tags are named is the same way. Can I ask you to do a tutorial showing html parsing to get me started on this please. Any help at all that you can give me would be greatly appreciated.

    Thanks in anticipation

    • Kent says:

      That should be fairly easy for me to do a tutorial on. In the meantime (because I can’t guarantee when I’ll get to it), have you tried putting all the elements in an array and then cycling through it. In other words every time you get to a

      tag you put the value in an array. Then where ever you want to use it you go through the array and find what you need. Hard to know exactly what you are trying to do.
      Are you creating the html, or is it something you don’t have control over?
      If you can give me some more details I might be able to help more.
      • Harry Mulligan says:

        Hi Kent

        I saw the tutorial you put together in response to my comment and I thank you for that. I’m sorry I didn’t get back to you sooner than this but in answer to your questions. The html I’m trying to parse is something I don’t have control over. What I’m trying to do is parse text from wikipedia pages and present them in a table something like the Game of Thrones Companion app. Again, any help you can give me will be gratefully recieved, what you have provided so far is excellent and certainly a starter point for me at least, greatly appreciated and thanks again.

        Best Regards

        Harry

        • Kent says:

          Shouldn’t be too difficult, just find the tags that the text is in and parse those out to either an array or even a dictionary or something. Then you can display that text in any way you wish.

  9. Pingback: Parsing XML |

  10. Harry Mulligan says:

    Hi Kent

    Thank you again for all your help in this. I’m going to give it a try now and I’ll let you know how things go.

    Best Regards

    Harry

  11. wcten says:

    I am trying to parse xml data with thumbnail image, to combine with your tutorial on table view (p=353). I am able to get the title and desc on the right hand side of the table, but not the image on the left.

    I google around, and found all tutorials on xml parsing are about getting the text, non can fetch media thumbnail. I just wonder if it is really impossible to get the media thumbnail?

    Below are the xml that I am trying to parse:

    Stricker leads at dramatic US PGA

    American Steve Stricker equals the lowest round in major history with a stunning 63 to take the lead on day one of the 93rd US PGA Championship in Atlanta.
    http://news.bbc.co.uk/go/rss/-/sport2/hi/golf/14499302.stm
    http://news.bbc.co.uk/sport1/hi/golf/14499302.stm
    Fri, 12 Aug 2011 05:22:05 GMT
    Golf

    • Kent says:

      I’m not sure what you are trying to do. The xml probably has a url to the thumbnail and you can parse that, but you won’t be parsing the image itself. If you are trying to retrieve the image, then just create a UIImageview and link it to the url of the image.

      Make sense? If not let me know exactly what you are trying to accomplish and I’ll try putting an example together for you.

      Good luck!

  12. wcten says:

    Sorry, the xml for the thumbnail look like this:

  13. nash says:

    Again! Great Tutorial. However I do not know if everyone is getting the following. I parsed my own tweet feeds and the following things happen:

    1. The Twitter feed is incomplete
    2. When you select one, it shows words on top of the others
    3. The orders is from oldest to most recent. How can u invert the order to show first the most recent tweets?

    Thanks in advance!

    • Kent says:

      Nash, the twitter feed on returns 20 tweets. I’m not sure why this is. It has nothing to do with our code, plug that URL into a browser and you’ll see the same result. Could be that we could change the URL and get the complete feed, but I was never concerned with that since the tutorial was about parsing the feed and 20 results was enough to demonstrate that.

      You can fix the selection bit by putting all the cell layout stuff in the if block of cellForRowAtIndexPath.


      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {

      static NSString *CellIdentifier = @"Cell";

      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil)
      {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
      UIImage *twitterLogo = [[UIImage imageNamed:@"twitter-logo.png"]autorelease];

      Tweet *currentTweet = [[xmlParser tweets] objectAtIndex:indexPath.row];

      CGRect imageFrame = CGRectMake(2, 8, 40, 40);
      self.customImage = [[[UIImageView alloc] initWithFrame:imageFrame] autorelease];
      self.customImage.image = twitterLogo;
      [cell.contentView addSubview:self.customImage];

      CGRect contentFrame = CGRectMake(45, 2, 265, 30);
      UILabel *contentLabel = [[[UILabel alloc] initWithFrame:contentFrame] autorelease];
      contentLabel.numberOfLines = 2;
      contentLabel.font = [UIFont boldSystemFontOfSize:12];
      contentLabel.text = [currentTweet content];
      [cell.contentView addSubview:contentLabel];

      CGRect dateFrame = CGRectMake(45, 40, 265, 10);
      UILabel *dateLabel = [[[UILabel alloc] initWithFrame:dateFrame] autorelease];
      dateLabel.font = [UIFont systemFontOfSize:10];
      dateLabel.text = [currentTweet dateCreated];
      [cell.contentView addSubview:dateLabel];
      }

      return cell;
      }

      And finally, when I run it I do get the most recent tweet at the top? But in any event I’m sure you could reverse the order of the array before getting the elements.

      Hope this helps, good luck.

  14. stephen says:

    I m parsing this particular feed…http://rss.marshillchurch.org/mhcvision…i m parsing the following tags everything works fine, i m able to populate the table view.clicking on the row of the table view takes you to detail view that contains a webview where data from the tag content:encoded are displayed .everything works fine.The problem is the image size is too big which makes me to scroll the detail view horizontally ..how to make the image fit perfectly in the webview…..below is the screen shot of the my simulator output …
    http://www.skytel.mobi/stepheniphone/iphone/rss.png

  15. daan says:

    When running the app I get a SIGABRT on: return [[xmlParser tweets] count; (rootviewcontroller.m)

    any idea why this is, and a solution?

  16. Peter says:

    Hi some great tutorials on here. Have been looking at the XML parsing but would like to know how to select the table row and for it to open a details view that will display the item. I was going to build a webservice that would give me a XML of places and then when I open the details view it will get a new XML but for the place selected

  17. Pingback: [Bg] Parsing XML with Twitter in Projects | Devsenses รับทำ App iPhone iPad Application Mobile Website Design

  18. Kevin says:

    Thanks so much for this Good Sir, this really helps me. I’m a newbie and really wanting to parse an rss feed with accompanying thumbnails. Can you point me in a good direction how to start with this? I sincerely appreciate your time.

    • Kent says:

      Do you have a sample of the RSS you’ll be parsing? If so it should be pretty simple to change the parser to look for the correct nodes. The thumbnails is a different story, you’ll probably just be getting a name of url of am image and not the image itself.

  19. Devraj says:

    hello.That was 1 great tutorials..
    I am new to iphone and i am developing a login app fro my i phone.
    i am giving to inputs i.e a user name nd password.
    when i press a login button i want to compare the user name and password wit the data base in the webserver nd give the result as successful or failure. plz help..
    Thanks in advance.

  20. Sonny says:

    When I ran this on my own feed, text with a single quote is getting cut off. So if I have a title like so:

    “Hello, my name’s Sonny.”

    The only thing that shows up in the app is:

    “s Sonny”

    Any thoughts?

  21. Josefin says:

    Hi, I really like this tutorial, but I have one problem though. I have tried to use my own Twitter xml feed, but the text just won’t fit into the table view. I can only see the end of the Twitter status in the table view.

    The problem seems to be that I am writing my Tweets in Swedish, because it’s only those tweets that are affected. I think it’s because of the special characters å, ä, ö. Is there something I can do to make it work with special characters?

  22. Ohm says:

    Hi Kent

    Thanks for your tutorial but I just wondering that if I want to add the network activity indicator(the spinner on the status bar beside the 3G/Wifi indicator) that because my XML was on a server and just wanna show the user that my app currently get the data from server. What should I do ?? Thanks

  23. dylan says:

    Hi,
    i understand that you parse the xml in the view did load method thus the content appears in the table cells.

    Let just say some event occurs and i want to parse a new twitter xml. How do i go around doing it ? The table reload doesn’t seems to work

    • Kent says:

      When the event occurs are you calling the web service again and reloading the xml to parse?

      • dylan says:

        Hi I manage to get reload the table already.

        Right now, I am parsing youtube xml.

        http://gdata.youtube.com/feeds/api/videos?max-results=2&alt=rss&q=westlife

        I want to extract the title, author and link element.

        I did a slight test trying to extract the title and author element first.
        The app launch and the table could display the title and author for a second before the app crashes. I have no idea what is the problem.

        Do you have an example of parsing youtube xml ?

        • Kent says:

          I’m not sure I understand. When I hit that url I don’t get XML back, it keeps asking me to subscribe even after I already have.

          Okay did a little reading and found how to get the XML for a specific video

          gdata.youtube.com/feeds/api/videos/VIDEO_ID

          Is that what you are trying to do? Retrieve one video at a time?

  24. dylan says:

    it seems that when i return more than 1 result the app will crash

  25. Kent says:

    Try running/debugging in instruments. Could be a memory management issue.

  26. James says:

    hi,

    firstly great tutorial, one question. the twitter xml actually has 2 created_at values. one for when the tweet was created and one for when the account was created. for some reason this code brings up the second. if you look at your image you’ll see that all the dates are the same. how can you get the value for when the tweet was created?

    james

  27. Bhuru says:

    Nice tutorial, it realy help me alot.
    thanks.

  28. Rob says:

    Hi, I’m wondering how one would adapt this tutorial for xCode 4.2. I’m just learning objective C and iOS development so it’s not completely clear to me, but I’m guessing this tutorial might have some memory management stuff that we could eliminate by using the Automatic Reference Counting in xCode 4.2. (i.e. maybe the dealloc method could be removed?) Is there any chance you have interest (and the time) to update the tutorial for xCode 4.2?

    Thanks – great tutorial!
    Rob

  29. Rick says:

    Hi,

    First of all, I would like to congratulate you on your tutorial, it has been a joy to follow!

    I have a question, I am currently working on a project which utilises an XML Parser. I am parsing an XML menu with a parent element and with several child elements with the same name, . I know I need to store them in an array, but trying to have them all displayed has proven to be a nightmare. Do you know how I would go about doing that based on your example? Any help would be appreciated!

    Keep up the good work!
    Rick

  30. Rick says:

    Yeah, its the display part which I am having difficulty with. due to the number of child element with the same name, “ingredient”, displaying them all from an ingredientArray to a string has been difficult. The xml structure is shown below;

    Antipasti
    anchovies
    cheese
    garlic
    olives
    5.00

    bruschetta
    tomato
    basil
    garlic
    vinegar
    olive oil
    4.00

    siciliana pizza
    tomato
    mozzarella
    capperi
    olives
    anchovies
    12.00

    I have the ingredient populating a NSMutableArray – ingredientArray in an object which holds the name, ingredientArray and price. When I do a NSLog on ingredientArray I see all the necessary ingredients in the array, but can’t for the life of me display it all out in a label.text string cell. I have tried the following

    cell.label.text = [[currentDish ingredientArray] objectAtIndex:indexPath.row];
    and
    cell.label.text = [[currentDish ingredientArray] objectAtIndex:indexPath.section];
    and
    cell.label.text = [[currentDish ingredientArray] objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];

    Any help will be appreciated!

    Cheers!
    Rick

    • Kent says:

      Rick, sorry not to get back to you sooner. Did you get this figured out? You need to use.

      cell.textLabel.text = [[currentDish ingredientArray]objectAtIndex:indexPath.row];

      I have small working example if you need it. But the above line should do the trick for you.

      Good Luck,
      Kent

      • Rick says:

        Hi Kent, sorry about the late reply. When I used your method the ingredientArray only displayed the first indexed value.

        I tried it with:

        [NSString stringWithFormat: @" %@, %@, %@, %@, [currentDish.ingredientArray objectAtIndex:0], [currentDish.ingredientArray objectAtIndex:1], [currentDish.ingredientArray objectAtIndex:2], [currentDish.ingredientArray objectAtIndex:3]];

        But thats only as good if all objects contained that number of values in the array. If one has one or more or less then it wont work.

        To clarify i have an object called Dish, which contains attributes name, price and an array called ingredientArray to hold all the different ingredients.

        As usual thanks for the help!
        Rick

  31. girish says:

    hey kent…nice post man…i luvd it…but it would be great if u could have provided with some explanation for this code..that would be helpful for new learner like me…will u plz tell me ..why did u used loadbyXML function…i know question is sounding like stupid but still…..hope u wont ignore this….till then cheerssss….. :)

    • Kent says:

      The loadByXML function initializes some of the variables and most importantly kicks off the whole parsing process by calling [parser parse]; The parse method is in the NSXMLParser object which the NSXMLParserDelegate is declared in.

      It really sounds and look more complicated than it really is. Check out the youTube video link at the beginning of this tutorial, it may help you understand things a little better. And you can ask specific questions here when ever you want.

      Good luck.

      • girish says:

        thnx for reply kent..i need your help kent..right now m doing with one task where i want to pull only few parameters from this api. the thing is like i have created one text feild on interface bulder where m entering the city name & when i enter the city name elements of should be displayed from this api
        http://www.google.com/ig/api?weather.
        need your help kent…& can i have your email id so i can get touch with you directly…

        • Kent says:

          you can email me at

          kent
          @
          theappcodeblog
          .com

          But you need to have a specific question. The app you mentioned would be easy to adapt from the tutorial. You take the text enter in the UITextField and append it to a string for the url. Then you parse the xml just as is done here.

  32. SirSheko says:

    thanks for upper posts & i appreciate them alot. but i wonder that “what if i want to send a single message between the iphone & a server i have developped, how can i parse xml in my code ?:S” its my graduation project & i need any help to this please.
    thanks

    • Kent says:

      This tutorial is all about parsing XML in your code. I’m not sure I understand. I’m happy to help, but what exactly are you having a problem with?

  33. RhezAnn says:

    This is awesome tutorial! Thanks for posting it here. A Great help to us!

  34. Blackwood Dev says:

    Hi,

    Is there an easy way to reorder the array? e.g. Order it in reserve date order?

    I ask because i have an app that reads in xml and would like to order buy a NSNumber.

    thanks

  35. Pingback: Parsing XML in an iPhone App Tutorial « G@ur@v Borole

  36. Rick says:

    Hey love the tutorial. One thing your tweets are cut off. How can I add a detailview to open a new view with the full tweet in it?

    I have spent 5 hours on this today to no avail. :(

  37. Rohit Yadav says:

    Hi,
    this is an awsme tuttorial i learn many things in this…so thnx alotz

  38. Alan Jay says:

    Hi Kent,

    First a great tutorial. one of the few times I have been able to follow a tutorial get it to work. Modify it to use with my XML and still get it to work. Well done!

    I did have one question. I can’t get my head around how your code loops around to collect each of the 20 tweets in the feed?

    In my case the feed I have been provided with has two levels of iteration “location” and “day of week” it provides menus for locations and days of week at those locations.

    I can easily enough extract the days of the week from one location “monday” “tuesday” etc but am wondering about the second level with the locations (just to confuse and annoy the xml locations are divided by “west” “east” “north” “south” and not a consistent status for each element.

    Any thoughts or insights would be gratefully received.

  39. Diogo says:

    Thanks, your tutorial helped me a lot!

  40. diogo says:

    Hi,

    this is a great tutorial, but i have a question:

    can i create a new method loadXMLByURL, or pass a string for this method? I need extract different xml files from different url with different elements.

    • Kent says:

      Yes you should be able to do this.

      • diogo says:

        can i repeat
        – (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

        - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

        - (void) parser:(NSXMLParser *)parser /*para:(NSString *)chamada*/ didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

  41. Keith says:

    Kent, I was wondering how to load more than 40 items into my tableview. I’ve made a MySQL database and it currently has 754 rows of data in one of its tables…using your tutorial I was able to access the information using PHP to echo the proper XML into a tableview. I obviously don’t want to load all 754 items at once, but there are times where i would like to parse about 100 items at a time. Do you know how to break the content into pages? For example, if i parse the 100 items of interest, can break the information up into groups of 25 or 50, where the bottom cell is actually a button that loads the next block of information (similar to the email app)?

    Currently the table view defaults at only 40 items, even though I’m trying to push everything to the table, just to see if it works. Also, I would like to eventually like to add sections to my table and make it searchable (searching the tableview seems quite involved, and I’ve only found examples of searchcontrollers that search static arrays). As far as the sections, I have a node in the XML that is labeled that is currently being parsed, but not used. It contains a number from 1-12 ( I was going to use a switch statement to give each a text value). Is there anything you can do to help?

    Thank you for your time.

    Keith

  42. Shan says:

    i have an internal Xml file to do parsing & display it in tableview.In my first viewController i need to create my own protocol and delegates and then do parsing,store the values in an array and display it in another viewController by using our own protocols and delegates.

  43. Nathan says:

    Hello,

    I am trying to figure out how to call a local file through your code provided. I understand how to call it through NSBundle, but I can’t get it to work. Here what I am trying to do.

    xmlParser = [[XMLParser alloc] loadXMLByURL:[[NSBundle mainBundle] pathForResource:@”filename” ofType:@”xml”];

    I also tried to create an NSString. Like this…

    NSString *myString = [[NSBundle mainBundle] pathForResource:@”filename” ofType:@”xml”]
    xmlParser = [[XMLParser alloc] loadXMLByURL:myString];

    Neither of these solutions are working. Any thoughts on how to accomplish this?

    Thanks.
    Nathan

  44. hello

    Thank you for the tutorial very informative and just what I need. I am new to the IOS app world
    I am having issue loading the image logo from a url also if you have a sample when you click on a record you can pull a separate page with passing the data to it in my case i will have a list of tv channels then you click will pull a separate view with video player that will stream from the the data passed to it
    thank you so much for your information

  45. Bobby Cloutier says:

    Excellent Tutorial,

    i was able to walk through it and get it working. But now i have a challening (for me at least) situation.

    My XML looks like this

    S10
    13034 Ballantyne Corporate Place,Charlotte,NC United States
    text

    S12
    CONT.48330text

    I am able to retrieve from one node, say address. but what i would like to do is retrieve
    val from branch__key as well and use it in what would be “date created” in your demo.

    i have tried several approaches and i’m stuck. Any ideas?

    Thanks

  46. sabarish says:

    hi kent, Nice tutorial helped be lot and hope you are watching this tutorials comments. I tried the same code with some point of view like instead showing image in table view i tried to show it in imageview. i used the same line Tweet *currentTweet = [[xmlParser tweets] objectAtIndex:indexPath.row]; inside viewDidLoad() but it shown error like ” Use of undeclared identifier ‘indexPath’; did you mean ‘NSIndexPath’? ”
    how can i solve this kindly suggest me an idea.

  47. Jairo says:

    Hi,

    If you are spanish people, there is another tutorial to parse XML files with NSXMLParser for iOS:
    http://www.apprendemos.com/tutoriales/ios/parser-xml-recorrer-iphone

    I hope it help you

  48. Gangadhar says:

    Excellent Tutorial!!!

  49. Dave says:

    I’m trying to implement your code in my first app I was able to modify the majority of it without any error until I run the app. When I run the simulator it closes then goes back to xcode with the following error.

    2013-01-08 18:19:04.623 TheDoorCFC[7726:c07] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Could not load NIB in bundle: ‘NSBundle (loaded)’ with name ‘DCHomeViewController”
    *** First throw call stack:
    (0×1801012 0x11c6e7e 0x1800deb 0x329fac 0x1eee37 0x1ef418 0x1ef648 0x1ef882 0x13ea25 0x13edbf 0x13ef55 0x147f67 0x2c35 0x10b7b7 0x10bda7 0x10cfab 0x11e315 0x11f24b 0x110cf8 0x1ccadf9 0x1ccaad0 0x1776bf5 0×1776962 0x17a7bb6 0x17a6f44 0x17a6e1b 0x10c7da 0x10e65c 0x296d 0×2895)
    libc++abi.dylib: terminate called throwing an exception

    Can you please help? Thanks.

    Using storyboard on Xcode 4.5.2

  50. Pingback: XML Parsing / WebAPIRequist | Dev iPhone SDK

  51. Micky says:

    Nice one. I got exactly what I need.
    Do more………

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>