{"id":1909,"date":"2011-05-14T06:44:16","date_gmt":"2011-05-14T11:44:16","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/?p=1909"},"modified":"2020-11-30T17:00:53","modified_gmt":"2020-11-30T22:00:53","slug":"xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-3-parse-xml-data","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/14\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-3-parse-xml-data\/","title":{"rendered":"XCode 4 IPhone Mountains of the USA Tutorial: Lesson 3 &#8211; Parse XML Data"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><br \/>\n<a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/12\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-2-load-xml-data\/\">&lt;== Lesson 2<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/08\/xcode-4-iphone-tutorial-mountains-of-the-usa-overview\/\">Overview<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/15\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-4-add-uitableview\/\">Lesson 4 ==&gt; <\/a><\/p>\n<p>In the last lesson you loaded XML data from the web and displayed in a TextView. In this lesson you are going to parse the XML data and just show the mountain names in TextView.<img loading=\"lazy\" decoding=\"async\" class=\"alignleft\" src=\"https:\/\/lh5.googleusercontent.com\/_e5pwU0LJbN8\/TcVF8NRLevI\/AAAAAAAAF2U\/dZ3fASCSYCA\/s800\/USAMountainsBlogImage.png\" alt=\"\" width=\"160\" height=\"218\" \/><\/p>\n<figure style=\"width: 205px\" class=\"wp-caption alignright\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/lh6.googleusercontent.com\/_e5pwU0LJbN8\/Tc2ykh8SXJI\/AAAAAAAAF7E\/Lei4ZWA1SGk\/s400\/USAMountains03Screen01.png\" alt=\"\" width=\"205\" height=\"400\" \/><figcaption class=\"wp-caption-text\">Screen With Mountains Names Parsed From XML<\/figcaption><\/figure>\n<p>To do this you will implement the NSXMLParser class and modify your MainViewController to be the NSXMLParser delegate with NSXMLParserDelegate protocol. Protocols are a kind of interface. The NSXMLParser has call backs as it proceeds with the parsing and you need a class to act as the delegate for the NSXMLParser object you create.<\/p>\n<p>You also are going to create your own custom class to represent the data for one mountain. We have limited use for this class in this lesson but it will become handy in passing data around our project in this lesson and as we proceed into the next lessons.<\/p>\n<p>A note about our XML is that the data is only in attributes.<\/p>\n<p><code>&lt;mountain_item id = \"1\" name = \"Mount McKinley\" elevation = \"20320\" lat = \"63.0690\" lon = \"-151.00063\" \/&gt;<br \/>\n<\/code><br \/>\nThus this tutorial does not show you how to parse XML data that would be inside of a node. This makes the XML parsing programming much simpler to do and a great way to get introduced to the overall implementation which also facilitates extracting XML node data when you need to learn how.<\/p>\n<p>There are no UI changes. The one change you will make is in code to display the names of the Mountains in the TextView instead of displaying the XML.<\/p>\n<p><strong>Source Download<\/strong><\/p>\n<ol>\n<li><a href=\"https:\/\/www.lonhosford.com\/content\/xcode\/iphone\/USAMountainsTutorial02.zip\">Starting XCode 4 Project<\/a>. This is the lesson 2 project completed.<\/li>\n<li><a href=\"https:\/\/www.lonhosford.com\/content\/xcode\/iphone\/USAMountainsTutorial02PHP_CSV_files.zip\">PHP and CSV Files<\/a>. Script to read data file and selects by elevation and returns XML. <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/12\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-2-load-xml-data\/\"> See Lesson 2<\/a>.<\/li>\n<li><a href=\"https:\/\/www.lonhosford.com\/content\/xcode\/iphone\/USAMountainsTutorial02XML.zip\">Mountain XML Data<\/a>. Alternative to hosting PHP script &#8211; <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/12\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-2-load-xml-data\/\">See Lesson 2<\/a>.<\/li>\n<li><a href=\"https:\/\/www.lonhosford.com\/content\/xcode\/iphone\/USAMountainsTutorial03.zip\">Completed XCode 4 Project<\/a><\/li>\n<\/ol>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\n<strong>Step 1: Create the MountainItem Class<\/strong><\/p>\n<p>Download and uncompress the <a href=\"https:\/\/www.lonhosford.com\/content\/xcode\/iphone\/USAMountainsTutorial02.zip\">Starting XCode Project<\/a> file and open in XCode.<\/p>\n<p>This will add our custom class to represent the data for one mountain from the XML file.<\/p>\n<p>Select the USAMountainsTutorial02 folder. Then from the main menu choose File-&gt;New-&gt;New File<\/p>\n<figure style=\"width: 400px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/lh6.googleusercontent.com\/_e5pwU0LJbN8\/Tc5qST3SVmI\/AAAAAAAAF8w\/j6JAMYYe9jo\/s400\/USAMountains03MountainItemFileNew.png\" alt=\"\" width=\"400\" height=\"175\" \/><figcaption class=\"wp-caption-text\">MountainItem &#8211; File New<\/figcaption><\/figure>\n<p>Select Cocoa Touch from the left panel and Objective-C Class from the right panel for the Templates dialog.<\/p>\n<figure style=\"width: 400px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/lh5.googleusercontent.com\/_e5pwU0LJbN8\/Tc27kv7h14I\/AAAAAAAAF7U\/TrEe0P1N0rw\/s400\/USAMountains03MountainItemChooseTemplate.png\" alt=\"\" width=\"400\" height=\"254\" \/><figcaption class=\"wp-caption-text\">MountainItem &#8211; Objective C Class<\/figcaption><\/figure>\n<p>Your class subclasses NSObject.<\/p>\n<figure style=\"width: 400px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/lh6.googleusercontent.com\/_e5pwU0LJbN8\/Tc27kBnUo2I\/AAAAAAAAF7M\/9vgS1YRkDkw\/s400\/USAMountains03MountainItemChooseOptions.png\" alt=\"\" width=\"400\" height=\"257\" \/><figcaption class=\"wp-caption-text\">MountainItem &#8211; Options<\/figcaption><\/figure>\n<p>The file name is MountainItem. The project folder is USAMountainsTutorial02 and the group is also USAMountainsTutorial02. The target USA Mts 02 was done for you in creating the starting project. Targets have to do with deployment and is beyond the scope of this tutorial and not relevant to just using the Simulator.<\/p>\n<figure style=\"width: 386px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/lh5.googleusercontent.com\/_e5pwU0LJbN8\/Tc5qSSU9nLI\/AAAAAAAAF8s\/9W6MFd6M7o0\/s800\/USAMountains03MountainItemSaveAs.png\" alt=\"\" width=\"386\" height=\"385\" \/><figcaption class=\"wp-caption-text\">MountainItem &#8211; Save As<\/figcaption><\/figure>\n<p>You should see two files name MountainItem.h and MountainItem.m in your Project navigator window. If they are not in the USAMountainsTutorial02, just drag them in.<\/p>\n<p><strong>Step 2: MountainItem.h &#8211; Add the Instance Variables<\/strong><\/p>\n<p>Open the MountainItem.h file and add the highlighted lines.<\/p>\n<p>These are the variables that represent the data in the XML file for one Mountain.<\/p>\n<pre><pre class=\"brush: objc; highlight: [7,8,9,10,12,13,14,15]; title: ; notranslate\" title=\"\">\n\/\/\n\/\/\n\/\/\n#import &amp;amp;lt;Foundation\/Foundation.h&amp;amp;gt;\n@interface MountainItem : NSObject\n{\n    NSString *name;\n    NSString *elevation;\n    NSNumber *latitude;\n    NSNumber *longitude;\n}\n@property (nonatomic, retain) NSString *name;\n@property (nonatomic, retain) NSString *elevation;\n@property (nonatomic, retain) NSNumber *latitude;\n@property (nonatomic, retain) NSNumber *longitude;\n\n@end\n<\/pre>\n<p><strong>Step 3: MountainItem.m &#8211; Add the Properties<\/strong><\/p>\n<p>Open the MountainItem.m file and add line 7.<\/p>\n<pre><pre class=\"brush: objc; highlight: [7]; title: ; notranslate\" title=\"\">\n\/\/\n\/\/\n\/\/\n#import &quot;MountainItem.h&quot;\n\n@implementation MountainItem\n@synthesize name, elevation, latitude, longitude;\n\n@end\n<\/pre>\n<p><strong>Step 4: MainViewController.h &#8211; Add the NSXMLParser and Set the NSXMLParserDelegate Protocol<\/strong><\/p>\n<p>Select the MainViewController.h in the project navigation window on the left and add the highlighted lines.<\/p>\n<p>Line 8 makes your MainViewController a NSXMLParserDelegate for a NSXMLParser and in particular the NSXMLParser object defined on lines 17 and 27. Your xmlParser is now able make calls on NSXMLParserDelegate methods you will add to this class.<\/p>\n<p>If you are working from the Starting XCode Project, update line 4 with your url. This was covered in lesson 2.<\/p>\n<pre><pre class=\"brush: objc; highlight: [4,8,17,27]; title: ; notranslate\" title=\"\">\n\/\/\n\/\/\n\/\/\n#define kTextURL    @&quot;http:\/\/YOUR_DOMAIN\/PATH_IF_ANY_TO_SCRIPT\/PHP_SCRIPT_OR_XML_FILE&quot;\n\n#import &amp;amp;lt;UIKit\/UIKit.h&amp;amp;gt;\n\n@interface MainViewController : UIViewController &amp;amp;lt;NSXMLParserDelegate&amp;amp;gt;\n{\n    UIButton                *searchButton;\n    UIActivityIndicatorView *activityIndicator;\n    UITextView              *resultsTextView;\n\n    NSURLConnection         *urlConnection;\n    NSMutableData           *receivedData;\n\n    NSXMLParser             *xmlParser;\n\n}\n@property (nonatomic, retain) IBOutlet UIButton                 *searchButton;\n@property (nonatomic, retain) IBOutlet UIActivityIndicatorView  *activityIndicator;\n@property (nonatomic, retain) IBOutlet UITextView               *resultsTextView;\n\n@property (nonatomic, retain) NSURLConnection *urlConnection;\n@property (nonatomic, retain) NSMutableData *receivedData;\n\n@property (nonatomic, retain) NSXMLParser *xmlParser;\n\n-(IBAction) startSearch:(id)sender;\n- (void) setUIState:(int)uiState;\n@end\n\n<\/pre>\n<p><strong>Step 5: MainViewController.m &#8211; Add the NSXMLParser Object and Update Navigation Bar Title<\/strong><\/p>\n<p>Select the MainViewController.m in the project navigation window on the left and add the highlighted lines.<\/p>\n<p>Two lines, 12 and 35, you can add here are for the NSXMLParser xmlParser object.<\/p>\n<p>Then line 52 update the navigation bar title.<\/p>\n<pre><pre class=\"brush: objc; highlight: [12,35,52]; title: ; notranslate\" title=\"\">\n#import &quot;MainViewController.h&quot;\n#import &quot;MountainItem.h&quot;\n\n@implementation MainViewController\n@synthesize searchButton;\n@synthesize activityIndicator;\n@synthesize resultsTextView;\n\n@synthesize urlConnection;\n@synthesize receivedData;\n\n@synthesize xmlParser;\n\n\/\/ State is loading data. Used to set view.\nstatic const int LOADING_STATE = 1;\n\/\/ State is active. Used to set view.\nstatic const int ACTIVE_STATE = 0;\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil\n{\n    self = &#x5B;super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n    if (self) {\n        \/\/ Custom initialization\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    &#x5B;searchButton release];\n    &#x5B;activityIndicator release];\n    &#x5B;resultsTextView release];\n    &#x5B;urlConnection release];\n    &#x5B;receivedData release];\n    &#x5B;xmlParser release];\n    &#x5B;super dealloc];\n}\n- (void)didReceiveMemoryWarning\n{\n    \/\/ Releases the view if it doesn't have a superview.\n    &#x5B;super didReceiveMemoryWarning];\n\n    \/\/ Release any cached data, images, etc that aren't in use.\n}\n\n#pragma mark - View lifecycle\n\n- (void)viewDidLoad\n{\n    &#x5B;super viewDidLoad];\n    \/\/ Do any additional setup after loading the view from its nib.\n    &#x5B;self setTitle:@&quot;USA Mountains Lesson 3&quot;];\n}\n\n- (void)viewDidUnload\n{\n    &#x5B;super viewDidUnload];\n    \/\/ Release any retained subviews of the main view.\n    \/\/ e.g. self.myOutlet = nil;\n    self.searchButton = nil;\n    self.activityIndicator = nil;\n    self.resultsTextView = nil;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation\n{\n    \/\/ Return YES for supported orientations\n    return (interfaceOrientation == UIInterfaceOrientationPortrait);\n}\n\n#pragma mark - UI Interface\n\n-(IBAction) startSearch:(id)sender\n{\n    NSLog(@&quot;startSearch&quot;);\n     \/\/ Change UI to loading state\n    &#x5B;self setUIState:LOADING_STATE];\n    \/\/ Create the URL which would be http:\/\/YOUR_DOMAIN_NAME\/PATH_IF_ANY_TO\/get_usa_mountain_data.php?elevation=12000\n    NSString *urlAsString = &#x5B;NSString stringWithFormat:@&quot;%@&quot;, kTextURL ];\n\n    NSLog(@&quot;urlAsString: %@&quot;,urlAsString );\n    NSURLRequest *req = &#x5B;&#x5B;NSURLRequest alloc] initWithURL:&#x5B;NSURL URLWithString:urlAsString]];\n    \/\/ Create the NSURLConnection con object with the NSURLRequest req object\n    \/\/ and make this MountainsEx01ViewController the delegate.\n   urlConnection = &#x5B;&#x5B;NSURLConnection alloc] initWithRequest:req delegate:self];\n    \/\/ Connection successful\n    if (urlConnection) {\n        NSMutableData *data = &#x5B;&#x5B;NSMutableData alloc] init];\n        self.receivedData=data;\n        &#x5B;data release];\n    }\n    \/\/ Bad news, connection failed.\n    else\n    {\n        UIAlertView *alert = &#x5B;\n                              &#x5B;UIAlertView alloc]\n                              initWithTitle:NSLocalizedString(@&quot;Error&quot;, @&quot;Error&quot;)\n                              message:NSLocalizedString(@&quot;Error connecting to remote server&quot;, @&quot;Error connecting to remote server&quot;)\n                              delegate:self\n                              cancelButtonTitle:NSLocalizedString(@&quot;Bummer&quot;, @&quot;Bummer&quot;)\n                              otherButtonTitles:nil\n                              ];\n        &#x5B;alert show];\n        &#x5B;alert release];\n    }\n    &#x5B;req release];\n\n}\n-(void) setUIState:(int)uiState;\n{\n    \/\/ Set view state to animating.\n    if (uiState == LOADING_STATE)\n    {\n        searchButton.enabled = false;\n        searchButton.alpha = 0.5f;\n        &#x5B;activityIndicator startAnimating];\n\n    }\n    \/\/ Set view state to not animating.\n    else if (uiState == ACTIVE_STATE)\n    {\n        searchButton.enabled = true;\n        searchButton.alpha = 1.0f;\n        &#x5B;activityIndicator stopAnimating];\n    }\n}\n<\/pre>\n<p><strong>Step 6: MainViewController.m &#8211; Start the XML Parsing When Data Loading Completed<\/strong><\/p>\n<p>Once the NSURLConnection connectionDidFinishLoading method is fired, you can initiate the XML parsing. This is done on lines 162-164.<\/p>\n<p>On line 162 the NSXMLParser is created with the initWithData which conveniently takes the NSMutableData receivedData you got from the NSURLConnection.<\/p>\n<p>[ad name=&#8221;Google Adsense&#8221;]<\/p>\n<p>Line 163 sets this class as the delegate for the NSXMLParser xmlParser object that you specified in MainViewController.h. To make this work, in MainViewController.h you implemented the NSXMLParserDelegate protocol.<\/p>\n<p>The parsing is kicked of on line 164. In the next step you add one method that NSXMLParser will call.<\/p>\n<p>We are still dumping XML data to the console, so the code for converting the NSMutableData receivedData to a NSString is retained for this lesson but not necessary.<\/p>\n<pre><pre class=\"brush: objc; first-line: 127; highlight: [162,163,164]; title: ; notranslate\" title=\"\">\n#pragma mark - NSURLConnection Callbacks\n- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response\n{\n    &#x5B;receivedData setLength:0];\n}\n- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data\n{\n    &#x5B;receivedData appendData:data];\n}\n- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error\n{\n    &#x5B;connection release];\n    self.receivedData = nil; \n\n    UIAlertView *alert = &#x5B;&#x5B;UIAlertView alloc]\n                          initWithTitle:@&quot;Error&quot;\n                          message:&#x5B;NSString stringWithFormat:@&quot;Connection failed! Error - %@ (URL: %@)&quot;, &#x5B;error localizedDescription],&#x5B;&#x5B;error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]\n                          delegate:self\n                          cancelButtonTitle:@&quot;Bummer&quot;\n                          otherButtonTitles:nil];\n    &#x5B;alert show];\n    &#x5B;alert release];\n    \/\/ Change UI to active state\n    &#x5B;self setUIState:ACTIVE_STATE];\n}\n- (void)connectionDidFinishLoading:(NSURLConnection *)connection\n{\n    \/\/ Convert receivedData to NSString.\n    NSString *receivedDataAsString = &#x5B;&#x5B;NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];\n\n    \/\/ Trace receivedData\n    NSLog(@&quot;connectionDidFinishLoading %@&quot;, receivedDataAsString);\n    resultsTextView.text = @&quot;&quot;;\n    &#x5B;receivedDataAsString release];\n\n    xmlParser = &#x5B;&#x5B;NSXMLParser alloc] initWithData:receivedData];\n    &#x5B;xmlParser setDelegate:self];\n    &#x5B;xmlParser parse];\n\n    \/\/ Connection resources release.\n    &#x5B;connection release];\n    self.receivedData = nil;\n    \/\/ Change UI to active state\n    &#x5B;self setUIState:ACTIVE_STATE];\n}\n\n<\/pre>\n<p><strong>Step 7: MainViewController.m &#8211; Parse Each mountain_item In XML<\/strong><\/p>\n<p>At the end of the file you can add the didStartElement method the NSXMLParser calls when it starts a new element in the XML file.<\/p>\n<p>As a reminder here is what your XML node you need to select and parse looks like.<\/p>\n<p><code>&lt;mountain_item id = \"1\" name = \"Mount McKinley\" elevation = \"20320\" lat = \"63.0690\" lon = \"-151.00063\" \/&gt;<br \/>\n<\/code><br \/>\nThe first step on line 178 is to see if the element being processed matches your XML file&#8217;s element mountain_item.<\/p>\n<p>[ad name=&#8221;Google Adsense&#8221;]<\/p>\n<p>You could have left out lines 180 to 184 for this lesson, but I thought is was a good point to get set up for future lessons where we need to store the mountain item data in an array as a data source to a table.<\/p>\n<p>These lines show how to access an attribute in the method. Your XML file attribute names are name, elevation, lat and lon.<\/p>\n<p>The console will show the mountain names parsed with the NSLog statement on line 186.<\/p>\n<p>On line 188 we append a new line to the UITextView that is just the mountain name.<\/p>\n<pre><pre class=\"brush: objc; first-line: 172; highlight: [172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196]; title: ; notranslate\" title=\"\">\n#pragma mark - NSXMLParser Callbacks\n- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI\n qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict\n{\n    \/\/ NSLog(@&quot;%s&quot;, __FUNCTION__);\n    \/\/Is a mountain_item node\n    if (&#x5B;elementName isEqualToString:@&quot;mountain_item&quot;])\n    {\n        MountainItem *mountainItem = &#x5B;&#x5B;MountainItem alloc] init];\n        mountainItem.name = &#x5B;attributeDict objectForKey:@&quot;name&quot;];\n        mountainItem.elevation = &#x5B;attributeDict objectForKey:@&quot;elevation&quot;];\n        mountainItem.latitude = &#x5B;attributeDict objectForKey:@&quot;lat&quot;];\n        mountainItem.longitude = &#x5B;attributeDict objectForKey:@&quot;lon&quot;];\n\n        NSLog(@&quot;mountainItem.name: %@&quot;, mountainItem.name);\n\n        resultsTextView.text = &#x5B;NSString stringWithFormat:@&quot;%@%@\\n&quot;, resultsTextView.text, mountainItem.name];\n\n        &#x5B;mountainItem release];\n        mountainItem = nil;\n\n    }\n\n}\n@end\n<\/pre>\n<p><a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/12\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-2-load-xml-data\/\">&lt;== Lesson 2<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/08\/xcode-4-iphone-tutorial-mountains-of-the-usa-overview\/\">Overview<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/05\/15\/xcode-4-iphone-mountains-of-the-usa-tutorial-lesson-4-add-uitableview\/\">Lesson 4 ==&gt; <\/a><\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#xfbml=1\"><\/script><!--End mc_embed_signup--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt;== Lesson 2 || Overview || Lesson 4 ==&gt; In the last lesson you loaded XML data from the web and displayed in a TextView. In this lesson you are going to parse the XML data and just show the mountain names in TextView. To do this you will implement the NSXMLParser class and modify [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[64,69,68,62],"class_list":["post-1909","post","type-post","status-publish","format-standard","hentry","category-general","tag-iphone","tag-objective-c","tag-xcode","tag-xml"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/1909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/comments?post=1909"}],"version-history":[{"count":67,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/1909\/revisions"}],"predecessor-version":[{"id":3763,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/1909\/revisions\/3763"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=1909"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=1909"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=1909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}