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]
