Hi Eric,

On Wed, Jan 6, 2010 at 9:46 PM, Philip Vallone
<[email protected]> wrote:
> Hi.
>
> I would recommend LibXML. This post is excellent and the the author created 
> an Objective C Wrapper.
>
> http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html
>
> Regards,
>

I can see you have already got two recommendation for using other lib
and wrapper and some for fixing your NSXMLParser delegate issue,

Answering your original question:
#1
Yahoo! api will always return only two days in forecast: day for which
current forecast was released (not necessary today locally, yes?) and
next day:
http://developer.yahoo.com/weather/#item

#2
example of (nearly) full implementation of
NSURLConnection+delegate/NSXMLParser+delegate for your specific use
case could be written as below sample (please read from top to bottom)
and could be started from e.g. UI controller method (main thread).
Please note that NSXMLParser implementation is very, very simple in
your specific use case (parsing only two days forecast from received
feed):


- (void)fetchRecentForecastForCode:(NSString *)weatherCode
{
    static NSString *feedURLString =
@"http://weather.yahooapis.com/forecastrss?w=%@&u=c";;
    NSURL *feedURL = [NSURL URLWithString:[NSString
stringWithFormat:feedURLString, weatherCode]];
    NSURLRequest *feedRequest = [NSURLRequest requestWithURL:feedURL];
    NSURLConnection *feedConnection = [[[NSURLConnection alloc]
initWithRequest:feedRequest delegate:self] autorelease];
    // property for NSURLConnection reference
    self.weatherFeedConnection = feedConnection;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response
{
    // property for accumulated data from request
    self.weatherFeedData = [[[NSMutableData alloc] initWithLength:0]
autorelease];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.weatherFeedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
    NSLog(@"%s %@", __FUNCTION__, error);
    self.weatherFeedConnection = nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    self.weatherFeedConnection = nil;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    // now start new background thread to parse received data using NSXMLParser
    [self performSelectorInBackground:@selector(parseWeatherFeedXML:)
withObject:self.weatherFeedData];
    self.weatherFeedData = nil;
}
//
- (void)parseWeatherFeedXML:(NSData *)feedData
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    // property for counter of parsed days (max two)
    self.parsedForecastDayCounter = 0;
    // we will add parsed days (object) to array property
    self.parsedDays = [NSMutableArray arrayWithCapacity:2];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:feedData];
    parser.delegate = self;
    [parser setShouldProcessNamespaces:YES];
    [parser parse];
    // after parser ends we check what we got
    if(self.parsedForecastDayCounter > 0)
    {
        // and update UI in main (UI) thread
        [self performSelectorOnMainThread:@selector(forecastParsedForDays:)
withObject:self.parsedDays waitUntilDone:NO];
    }
    self.parsedDays = nil;
    [parser release]; parser = nil;
    [pool drain];
}
//
static NSString * const kForecastElementName = @"yweather:forecast";
static NSString * const kForecastElementDayKey = @"day";
static NSString * const kForecastElementDateKey = @"date";
static NSString * const kForecastElementLowKey = @"low";
static NSString * const kForecastElementHightKey = @"high";
static NSString * const kForecastElementTextKey = @"text";
static NSString * const kForecastElementCodeKey = @"code";
static const const NSUInteger kMaximumNumberOfDaysToParse = 2;
//
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary
*)attributeDict
{
    if(qName && ([qName isEqualToString:kForecastElementName]))
    {
        NSLog(@"%s %@ (%@)", __FUNCTION__, elementName, qName);
        NSMutableDictionary *forecast = [[NSMutableDictionary alloc] init];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementDayKey] forKey:kForecastElementDayKey];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementDateKey] forKey:kForecastElementDateKey];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementLowKey] forKey:kForecastElementLowKey];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementHightKey]
forKey:kForecastElementHightKey];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementTextKey] forKey:kForecastElementTextKey];
        [forecast setValue:[attributeDict
valueForKey:kForecastElementCodeKey] forKey:kForecastElementCodeKey];
        [self.parsedDays addObject:forecast];
        [forecast release]; forecast = nil;
        self.parsedForecastDayCounter++;
    }
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
    if(qName && ([qName isEqualToString:kForecastElementName]))
    {
        // we are done - no reason to parse further after 2 days offered by api
        if(self.parsedForecastDayCounter >= kMaximumNumberOfDaysToParse)
        {
            [parser abortParsing];
            return;
        }
    }
}
// called from background thread after parsing is done
- (void)forecastParsedForDays:(NSArray *)parsedDays
{
    NSMutableString *outputStr = [[NSMutableString alloc] initWithString:@""];
    NSObject *forecast = nil;
    for (forecast in parsedDays) {
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementDayKey, [forecast
valueForKey:kForecastElementDayKey]]];
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementDateKey, [forecast
valueForKey:kForecastElementDateKey]]];
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementLowKey, [forecast
valueForKey:kForecastElementLowKey]]];
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementHightKey, [forecast
valueForKey:kForecastElementHightKey]]];
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementTextKey, [forecast
valueForKey:kForecastElementTextKey]]];
        [outputStr appendString:[NSString stringWithFormat:@"%@:
%...@\n", kForecastElementCodeKey, [forecast
valueForKey:kForecastElementCodeKey]]];
    }
    self.textView.text = outputStr;
    [outputStr release]; outputStr = nil;
}



with regards from reader of your books,
Peter Blazejewicz
_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to