Question

This is the documentation provided by Yahoo: http://developer.yahoo.com/weather/

At the moment this is my code:

NSString *location =  @"Palermo";
NSString *temperatureUnit = @"c";
NSString *address = @"http://weather.yahooapis.com/forecastrss?w=";
NSString *request = [NSString stringWithFormat:@"%@%@&u=%@",address,location, temperatureUnit];
NSURL * URL = [NSURL URLWithString:request];
NSXMLParser * doc = [[NSXMLParser alloc] initWithContentsOfURL:URL];

I'd like to know how to get the temperature value using NSXMLParser

Was it helpful?

Solution

You create your parser, but you don't parse. Let's assume you created your parser like so:

NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];

You then need to set the delegate and initiate the parse:

parser.delegate = self;
[parser parse];

You then have to write your NSXMLParserDelegate methods. (For more information on NSXMLParser, see the Event-Driven XML Programming Guide.) E.g., if you only need temperature, you could write a didStartElement method:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"yweather:condition"])
    {
        // do whatever you want with `attributeDict`, perhaps saving it in some class property; I'm just going to log it

        NSLog(@"current condition = %@", attributeDict); 
    }           
}

Note, the city should be a WOEID. (See the API description.) So, instead of a location of:

NSString *location =  @"Palermo";

You should use (for Palermo in Italy):

NSString *location =  @"719846";

By the way, I agree with Caleb that you should either do this initWithContentsOfURL in a background queue, or you should otherwise retrieve the NSData using some asynchronous mechanism.

For example, you could do:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString *location = @"719846";
    NSString *temperatureUnit = @"c";
    NSString *address = @"http://weather.yahooapis.com/forecastrss?w=";
    NSString *request = [NSString stringWithFormat:@"%@%@&u=%@",address,location, temperatureUnit];
    NSURL *URL = [NSURL URLWithString:request];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    parser.delegate = self;
    [parser parse];
});

If you do this in the background queue, make sure to dispatch UI updates back to the main queue, e.g.:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"yweather:condition"])
    {
        // UI updates should be dispatched back to the main queue, e.g.:
        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *temp = attributeDict[@"temp"];
            self.tempLabel.text = temp;
        });
    }
}

OTHER TIPS

You'll need to create an URL request from that URL, make the request withNSURLConnection, and receive the response. There are a number of good examples in Apple's documentation, so no need to repeat them here. Or, you can use initWithContentsOfURL: as you're doing above, but don't do that in the main thread as it'll cause your app to freeze until the response is received; if the server takes too long to respond, iOS will kill your app. Once you have the response, you'll parse it with the XML parser -- you'll need to create a delegate so that the parser can hand you the data as it encounters it during parsing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top