NSXMLParser工作正常,但如何实现UIActivityIndi​​cator来显示网络活动?

时间:2011-04-04 21:19:14

标签: iphone ios nsxmlparser

我从NSXMLParser将数据加载到我的UITableView中。 这一切都运行正常但我想要实现的是App加载XML数据时的一些活动,所以对用户来说这一切都更加友好。 我发现的一些样本仍然让我感到困惑,因为我没有采用与XMLParser实现相同的方式。

我在这里提供了我的数据,请提供一些关于如何将其放入我的代码中的代码示例。

XMLParser.h:

#import <UIKit/UIKit.h>

@class DAFAppDelegate, Stage, Month;

@interface XMLParser : NSObject <NSXMLParserDelegate>
{
     NSMutableString *currentElementValue;
     DAFAppDelegate *appDelegate;
     Stage *aStage;
     Month *aMonth;
}

- (XMLParser *) initXMLParser;
+ (NSDate *)dateFromString:(NSString *)dateString;
+ (NSString *)stringFromDate:(NSDate *)stringDate;

@end

XMLParser.m:

#import "XMLParser.h"
#import "DAFAppDelegate.h"
#import "Stage.h"
#import "Month.h"

@implementation XMLParser

- (XMLParser *) initXMLParser
{
     [super init];
     appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];
     return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
     if([elementName isEqualToString:@"Stages"])
     {
          //Initialize the array.
          appDelegate.stages = [[NSMutableArray alloc] init];
     }
     if([elementName isEqualToString:@"Month"])
     {
          //Initialize the Month.
          aMonth = [[Month alloc] init];
          aMonth.stagesPerMonth = [[NSMutableArray alloc] init];
          //Extract the attribute here.
          aMonth.name = [attributeDict valueForKey:@"name"];
          aMonth.monthID = [[attributeDict objectForKey:@"id"] integerValue];
          NSLog(@"Reading Month id value :%i", aMonth.monthID);
          NSLog(@"Reading Month name value :%@", aMonth.name);
     }
     if([elementName isEqualToString:@"Stage"])
     {
          //Initialize the Stage.
          aStage = [[Stage alloc] init];
          //Extract the attribute here.
          aStage.stageID = [[attributeDict objectForKey:@"id"] integerValue];
          NSLog(@"Reading id value :%i", aStage.stageID);
     }
     NSLog(@"Processing Element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{ 
     if(!currentElementValue)
     {
          currentElementValue = [[NSMutableString alloc] initWithString:string];
     }
     else
     {
          [currentElementValue appendString:string];
     }
     NSLog(@"Processing Value: %@", currentElementValue);
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
     NSDate* date = [NSDate date];
     NSDateFormatter* nsformatter = [[[NSDateFormatter alloc] init] autorelease];
     [nsformatter setDateFormat:@"yyyy-MM-dd"];
     NSDate* stageDate = [XMLParser dateFromString:aStage.end];
     if([elementName isEqualToString:@"Stages"])
     {
          return;
     }
     if([elementName isEqualToString:@"Month"])
     {
          if (!aMonth.stagesPerMonth || aMonth.stagesPerMonth.count)
          {
               [appDelegate.stages addObject:aMonth];
          }
          [aMonth release];
          aMonth = nil;
     }
     if([elementName isEqualToString:@"Stage"])
     {
          NSTimeInterval interval = [date timeIntervalSinceDate:stageDate];
          if (interval < 0)
          {
               [aMonth.stagesPerMonth addObject:aStage];
          }
          [aStage release];
          aStage = nil;
     }
     else
     {
          [aStage setValue:currentElementValue forKey:elementName];
          [currentElementValue release];
          currentElementValue = nil;
     }
}

-(void) parserDidStartDocument:(NSXMLParser *)parser
{
     NSLog(@"parserDidStartDocument");
}

-(void) parserDidEndDocument: (NSXMLParser *)parser
{
     NSLog(@"parserDidEndDocument");
}

+ (NSDate *)dateFromString:(NSString *)dateString
{
     NSDateFormatter *nsDateFormatter = [[NSDateFormatter alloc] init];
     [nsDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
     NSDate *date = [nsDateFormatter dateFromString:dateString];
     return date;
     [nsDateFormatter release];
}

+ (NSString *)stringFromDate:(NSDate *)stringDate
{
     NSDateFormatter *stringDateFormatter = [[NSDateFormatter alloc] init];
     NSLocale *nlLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"nl_NL"];
     [stringDateFormatter setLocale:nlLocale];
     [stringDateFormatter setDateFormat:@"EEE', 'dd MMMM yyyy  HH:mma"];
     NSString *dateString = [stringDateFormatter stringFromDate:stringDate];
     return dateString;
     [stringDateFormatter release];
}

- (void) dealloc
{
     [aStage release];
     [aMonth release];
     [currentElementValue release];
     [super dealloc];
}

@end

DAFAppDelegate.h:

@class RootViewController;

@interface DAFAppDelegate : NSObject <UIApplicationDelegate>
{
     UIWindow *window;
     UINavigationController *navigationController;

     IBOutlet UITabBarController *rootTabController;

     RootViewController *rootViewController;
     NSMutableArray *stages;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *rootTabController;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;

@property (nonatomic, retain) NSMutableArray *stages;

+ (void) showAlert;

@end

DAFAppDelegate.m:

#import "DAFAppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"


@implementation DAFAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize rootViewController;
@synthesize rootTabController;
@synthesize stages;

+ (void) showAlert
{
     UIAlertView *av = [[[UIAlertView alloc] initWithTitle:@"No Connection" message:@"Could not retrieve data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
     [av show];
}

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
     NSURL *url = [[NSURL alloc] initWithString:@"http://web.me.com/ijar/Stages.xml"];
     NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

     //Initialize the delegate.
     XMLParser *parser = [[XMLParser alloc] initXMLParser];

     //Set delegate
     [xmlParser setDelegate:parser];

     //Start parsing the XML file.
     BOOL success = [xmlParser parse];

     if(success)
     {
          NSLog(@"No Errors");
     }
     else
     {
          [DAFAppDelegate showAlert];
          NSLog(@"Error Error Error!!!");
     }    
     [window addSubview:[rootTabController view]];
     [window makeKeyAndVisible];
}

- (void)dealloc
{
     [navigationController release];
     [rootViewController release];
     [rootTabController release];
     [window release];
     [stages release];
     [super dealloc];
}

@end

RootViewController.h:

@class DAFAppDelegate;

@interface RootViewController : UITableViewController
{
     DAFAppDelegate *appDelegate;
}

@end

RootViewController.m:

#import "RootViewController.h"
#import "DAFAppDelegate.h"
#import "DetailViewController.h"
#import "XMLParser.h"
#import "Stage.h"
#import "Month.h"
#import "AgendaCustomCell.h"


@implementation RootViewController

#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad
{
     [super viewDidLoad];
     appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];

     self.title = NSLocalizedString(@"Agenda", @"Master view navigation title");
     UIImageView *image=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,45,45)] ;
     [image setImage:[UIImage imageNamed:@"topBarIcon.png"]];
     [self.navigationController.navigationBar.topItem setTitleView:image];
     self.tableView.backgroundColor = [UIColor clearColor];
}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [appDelegate.stages count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    Month *aMonth = [appDelegate.stages objectAtIndex:section];
    return aMonth.name;
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    Month *aMonth = [appDelegate.stages objectAtIndex:section];
    return [aMonth.stagesPerMonth count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier = @"AgendaCustomCell";

     AgendaCustomCell *cell = (AgendaCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

     if (cell == nil)
     {
          NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:@"AgendaCustomCell" owner:nil options:nil];

          for (id currentObject in topLevelObject)
          {
               if ([currentObject isKindOfClass:[UITableViewCell class]])
               {
                    cell = (AgendaCustomCell *)currentObject;
                    break;
               }
          }
     }

     Month *aMonth = [appDelegate.stages objectAtIndex:indexPath.section];
     Stage *aStage = [aMonth.stagesPerMonth objectAtIndex:indexPath.row];

     NSString *startDate = [XMLParser stringFromDate:[XMLParser dateFromString:aStage.start]];
     NSString *endDate = [XMLParser stringFromDate:[XMLParser dateFromString:aStage.end]];

     int endDateLength = endDate.length;
     NSString *dateTitle = [NSString stringWithFormat:@"%@ - %@", startDate, [endDate substringFromIndex:endDateLength -7]];

     cell.titleLabel.text = aStage.title;
     cell.dateLabel.text = dateTitle;
     cell.nameLabel.text = aStage.teacher;

     return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
}

#pragma mark -
#pragma mark Table view selection

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     //When a row is selected, create the detail view controller and set its detail item to the item associated with the selected row.
         DetailViewController *detailViewController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
         Month *aMonth = [appDelegate.stages objectAtIndex:indexPath.section];
     detailViewController.stage = [aMonth.stagesPerMonth objectAtIndex:indexPath.row];

         // Push the detail view controller.
         [[self navigationController] pushViewController:detailViewController animated:YES];
         [detailViewController release];
}

#pragma mark -
#pragma mark Memory management

- (void)dealloc
{    
     [appDelegate release];
     [super dealloc];
}

@end

2 个答案:

答案 0 :(得分:3)

如果您想在状态栏调用中使用标准活动指示器:

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

在你调用解析器之前。

然后,一旦解析器完成(didEndDocument方法),就调用:

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

答案 1 :(得分:0)

我不打算为你编写代码,但这里有一些你可以采取的步骤。 1.要获得更好的UX,请在开始xml解析之前将RootViewController.view添加到窗口。 2.在RootViewController:viewDidLoad方法中,创建并显示UIActivityIndi​​catorView(“微调器”)。 3.解析完成后,在RootViewController上调用一个方法,它执行以下三项操作:  a)隐藏旋转器  b)加载tableView的数据源(aMonth.stagesPerMonth)  c)tableView [reloadData];

祝你好运。 -Mike