The idea here is to parse the XML response from a Wunderground Data Feed Web Service, which provides information for current weather conditions. The conceptual part of target XML follows. More details about XML and available weather API can be found on the Wunderground Data Feed site.
<current_observation>
<credit>Weather Underground NOAA Weather Station</credit>
<credit_URL>http://wunderground.com/</credit_URL>
<image>
<url>http://icons.wunderground.com/graphics/wu2/logo_130x80.png</url>
<title>Weather Underground</title>
<link>http://wunderground.com/</link>
</image>
+<display_location></display_location>
+<observation_location></observation_location>
<station_id>KSFO</station_id>
<observation_time>Last Updated on July 14, 9:56 AM PDT</observation_time>
...
<local_time>July 14, 10:01 AM PDT</local_time>
...
<local_epoch>1247590877</local_epoch>
<weather>fog</weather>
<temperature_string>52 F (11 C)</temperature_string>
<temp_f>52</temp_f>
<temp_c>11</temp_c>
<relative_humidity>76%</relative_humidity>
...
<icon>fog</icon>
...
</current_observation>
For processing this XML we decided to use DOM parser for the following reasons:
The DOM presents an XML document as a tree-structure. The parser creates a tree object out of the document. The user accesses data by traversing the tree. The API allows for constructing, accessing and manipulating the structure and content of XML documents (Figure 2).
For our implementation we use a very simple and effective parser - XMLTreeParser/XMLTreeNode. The implementation consists of two classes: XMLTreeParser and XMLTreeNode. It uses NSXMLParser to read the document and for every one <element> tag creates a XMLTreeNode object. That way, it creates the tree that contains nodes of type XMLTreeNode.
To create a parser, simply instantiate the XMLTreeParser class:
XMLTreeParser* parser = [[XMLTreeParser alloc] init];
After that start parsing – call the parse method and provide the XML data:
<strong>XMLTreeNode* root = [parser parse:xmlData];
Now you can traverse through the tree manually looking for things.
NSArray* items = [stuffindChildren:@"icon"];
The DOM model is easiest to understand. On Figure 3, a basic architecture of an XML application using DOM is presented:
So here’s what happens: A parser reads the XML file and builds a DOM document to match the XML file. From that point until a save is performed, all interaction between the application and XML hits the DOM document rather than the corresponding XML file. It’s interesting to note that almost all XML parsers use SAX. Before you build a DOM document you must detect events such as the start of an element (start tag encountered), end of an element (end tag encountered) and/or a new attribute (name followed by equal sign followed by quoted string encountered). DOM can be thought of as an extra abstraction to lessen the programmer’s workload, at the expense of memory usage.
Modifications are made directly to the DOM document. Elements can be added, deleted, renamed, and rearranged. Text nodes can be added, delete,d or changed. Elements can be moved either within the same level, or promoted or demoted to different levels.
Choosing the appropriate pattern is a critical step. The Dynamic Document architectural pattern was used in our case. This pattern contains XML not typed by DTD or schema, but follows assessors for underlying program objects. It allows for unlimited extension by multiple, uncoordinated parties at the cost of lack of type-checking, and it’s simple to implement.
The DOM API is used to read information from an XML document. There is an easier way of getting around using DOM for modifying and saving the XML data — creating an object model for the information in the document. You can create this object model by giving it a DOM object that holds all the XML document information. That is, the XML document should be mapped to an object model.
Figure 4 shows how to map the Current Observation XML document to a set of related classes (object model). The <current_observation> element is mapped to the CurrentObservation class; the <display_location> element is mapped to the DisplayLocation class. The <observation_location> element is mapped to the ObservationLocation class. Single elements (without sub elements or others attributes) are mapped to the parent element class properties. Each class can be instantiated using a method or Factory implementation by providing a part of XML tree, with root – class element. In this the exampleinit method was used -(id)initWithData:(NSData *)data;.
Here is a partial code listing from CurrentObservation.h:
@interface WUCurrWeather : NSObject {
NSString *credit;
...
Image *image;
DisplayLocation *displayLocation;
...
NSString *icon;
...
}
@property(nonatomic, retain) NSString *credit;
@property(nonatomic, retain) Image *image;
@property(nonatomic, retain) DisplayLocation *displayLocation;
...
@property(nonatomic, retain) NSString *icon;
...
- (id)initWithData:(NSData *)data;
-(NSString *)description;
@end;
@interface Image : NSObject {
NSString *url;
NSString *title;
NSString *link;
}
@property(nonatomic, retain) NSString *url;
@property(nonatomic, retain) NSString *title;
@property(nonatomic, retain) NSString *link;
- (id)initWidthData:(XMLTreeNode *)root;
- (NSString *) description;
@end
Below is an example of a View Based iPhone Application that calls a Wunderground Data Feed Web Service to get current weather conditions. The update button repeats the call and refreshes the screen when new data arrives. The screenshots below visualize the application’s behavior:
![]() |
![]() |
![]() |
In the provided source code you can find all these steps implemented.
Facebook Application Response Timeout
Have you ever gotten the message The URL [your application url here] did not respond. even when everything seems to be working on your side?
One probable reason is that Facebook has a certain response timeout – approximately 12 seconds. If your page fails to respond in this time, Facebook will leave it and display an error message. I used a few simple tricks and managed to work around this issue. Try them out:
Make the Facebook application lighter:
Speed up your Facebook app:
AJAX calls have the same timeout issue (although the timeout here is approximately 13 seconds). Additionally all AJAX calls pass through the Facebook server which slows them down. The result is the following JavaScript error: “error”:1349011,”errorSummary”:”Failed to fetch app Ajax” .
I found a simple solution to avoid it: Use FBJS AJAX and a timer to abort the request when it reaches the time limit and send a new one.
Facebook API Response Time and Error Count
The Facebook API itself sometimes has latency issues causing your app pages to be fetched slower, increasing the risk of reaching the response timeout. Errors in request to their servers are also known to happen. You should always be informed about the Facebook Platform Status.
Syntax Limitations in FQL
The Facebook API allows you to make your own queries using a query language similar to SQL. There is a list of tables you can access (you can only view information; you are not allowed to update the information in any of these tables). You can easily make your own queries, but you should keep in mind that you cannot do a number of normal (for SQL) things such as join tables, use ‘distinct’, ‘limit’, ‘group by’, etc., or use “from” against more than one table. You can easily do these operations in the code, however. Combined with the use of the multiquery functionality, things should work almost as fast as if you were using pure SQL.
Facebook API Changes
As you may guess, the Facebook API still is in development, so you should keep yourself up to date with the constant changes in its platform. Some of these changes are potentially breaking, some features are being deprecated or changed, and some cool new things are being added. It is useful to read the Facebook Developer Roadmap to be informed for the specific changes that have been planned and when to expect them. Here are some of the upcoming ones:
Until recently, some of the API changes, even when prepared for them, had unexpected effects on some applications (in some cases, bugs appeared) and there was nothing we could do about it.
In late February, Facebook introduced a tool to help us prepare for the changes – the Migrations tool. When Facebook announces a new feature or fix, you can first do some testing before going to the Migrations tab in your application settings and choosing to enable it (it is disabled by default).
In conclusion, I can assure you that whatever problems you may stumble upon there is a huge community of developers willing to help you out. Just go to the Facebook Developers Forum. There is also lots of documentation and useful tips in the Facebook Developers Wiki. Have fun!